progress rapiin dashboard
This commit is contained in:
parent
8654e70e9a
commit
fc9f6d280b
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\AksesFile;
|
||||
use App\Models\FileDirectory;
|
||||
use App\Models\LogActivity;
|
||||
use App\Models\MasterKategori;
|
||||
use App\Models\MasterKlasifikasi;
|
||||
use App\Models\SubUnitKerja;
|
||||
@ -12,6 +13,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use setasign\Fpdi\Fpdi;
|
||||
use ZipArchive;
|
||||
|
||||
use function PHPUnit\Framework\isEmpty;
|
||||
@ -182,32 +184,7 @@ class DashboardController extends Controller
|
||||
|
||||
public function OptionUnitKerja(){
|
||||
$q = request()->get('q');
|
||||
$authPegawai = auth()->user()?->dataUser;
|
||||
|
||||
$authUnitKerja = optional($authPegawai->mappingUnitKerjaPegawai[0] ?? null)->objectunitkerjapegawaifk;
|
||||
$authSubUnitKerja = optional($authPegawai->mappingUnitKerjaPegawai[0] ?? null)->objectsubunitkerjapegawaifk;
|
||||
|
||||
$aksesFile = AksesFile::where('pegawai_id', $authPegawai->id)
|
||||
->where('statusenabled', true)
|
||||
->first();
|
||||
$query = UnitKerja::where('statusenabled', true);
|
||||
if($aksesFile){
|
||||
if($aksesFile->all_akses){
|
||||
|
||||
}elseif($aksesFile->unit_akses){
|
||||
$query->where('id', $aksesFile->unit_akses);
|
||||
}
|
||||
}else{
|
||||
$data= $query->where('id', $authUnitKerja)
|
||||
->with(['subUnitKerja' => function($query) use($authSubUnitKerja){
|
||||
$query->where('id', $authSubUnitKerja);
|
||||
}])->select('id', 'name')->get();
|
||||
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'data' => $data
|
||||
], 200);
|
||||
}
|
||||
|
||||
$data = $query->when($q, function ($query, $q){
|
||||
$query->where('name', 'ILIKE', '%' .$q . '%');
|
||||
@ -220,30 +197,60 @@ class DashboardController extends Controller
|
||||
}
|
||||
|
||||
public function deleteFile(string $id){
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'File tidak ditemukan'
|
||||
]);
|
||||
}
|
||||
$oldPath= public_path('file/' . $data->file);
|
||||
$fileInfo = pathinfo($data->file);
|
||||
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
|
||||
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
|
||||
if (file_exists($oldPath)) {
|
||||
// pastikan folder tujuan ada
|
||||
if (!is_dir(dirname($newPath))) {
|
||||
mkdir(dirname($newPath), 0777, true);
|
||||
}
|
||||
rename($oldPath, $newPath);
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
try {
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'File tidak ditemukan'
|
||||
]);
|
||||
}
|
||||
$oldPath= public_path('file/' . $data->file);
|
||||
$fileInfo = pathinfo($data->file);
|
||||
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
|
||||
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
|
||||
if (file_exists($oldPath)) {
|
||||
// pastikan folder tujuan ada
|
||||
if (!is_dir(dirname($newPath))) {
|
||||
mkdir(dirname($newPath), 0777, true);
|
||||
}
|
||||
rename($oldPath, $newPath);
|
||||
}
|
||||
|
||||
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
|
||||
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $data->file_directory_id,
|
||||
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||
'entry_at' => $data->entry_at,
|
||||
'action_type' => 'Hapus Dokumen',
|
||||
'statusenabled' => true,
|
||||
'mod_change' => $data->entry_at,
|
||||
'id_unit_kerja' => $data->id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $data->id_sub_unit_kerja,
|
||||
'file' => $data->file,
|
||||
'tanggal_terbit' => $data->tanggal_terbit,
|
||||
'no_dokumen' => $data->no_dokumen,
|
||||
'permission_file' => $data->permission_file,
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Berhasil menghapus data'
|
||||
]);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollBack();
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal menghapus data'
|
||||
]);
|
||||
//throw $th;
|
||||
}
|
||||
|
||||
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Berhasil menghapus data'
|
||||
]);
|
||||
}
|
||||
|
||||
public function optionSubUnitKerja(string $id){
|
||||
@ -349,8 +356,15 @@ class DashboardController extends Controller
|
||||
}
|
||||
|
||||
public function dashboardVersion2(){
|
||||
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
|
||||
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
|
||||
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
|
||||
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
|
||||
$data = [
|
||||
'title' => 'Dashboard',
|
||||
'title' => 'Dashboard',
|
||||
'katDok' => $katDok,
|
||||
'authUnitKerja' => $authUnitKerja,
|
||||
'authSubUnitKerja' => $authSubUnitKerja,
|
||||
];
|
||||
return view('dashboardV2.index', $data);
|
||||
}
|
||||
@ -372,4 +386,148 @@ class DashboardController extends Controller
|
||||
];
|
||||
return response()->json($payload);
|
||||
}
|
||||
|
||||
public function storeVersion2(){
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
try {
|
||||
$datas = request('data');
|
||||
foreach ($datas as $data) {
|
||||
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $data['id_unit_kerja'],2);
|
||||
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $data['id_sub_unit_kerja'],2);
|
||||
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
|
||||
$payload = [
|
||||
'id_unit_kerja' => $id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $id_sub_unit_kerja,
|
||||
'master_kategori_directory_id' => $master_kategori_directory_id,
|
||||
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
|
||||
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? null,
|
||||
'tanggal_terbit' => $data['date_active'] ?? null,
|
||||
'no_dokumen' => $data['no_dokumen'] ?? null,
|
||||
'permission_file' => $data['is_permission'] === "1" ? true : false,
|
||||
];
|
||||
if(!empty($data['file'])){
|
||||
$file = $data['file'];
|
||||
$imageName = $file->getClientOriginalName();
|
||||
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}";
|
||||
$file->storeAs($path, $imageName, 'file_directory');
|
||||
$payload['file'] =$path .'/' .$imageName;
|
||||
}
|
||||
$fd = FileDirectory::create($payload);
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $fd->file_directory_id,
|
||||
'pegawai_id_entry' => $fd->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $fd->pegawai_nama_entry,
|
||||
'entry_at' => $fd->entry_at,
|
||||
'action_type' => 'Upload Dokumen',
|
||||
'statusenabled' => true,
|
||||
'mod_change' => $fd->entry_at,
|
||||
'id_unit_kerja' => $fd->id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $fd->id_sub_unit_kerja,
|
||||
'file' => $fd->file,
|
||||
'tanggal_terbit' => $fd->tanggal_terbit,
|
||||
'no_dokumen' => $fd->no_dokumen,
|
||||
'permission_file' => $fd->permission_file,
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
}
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'Data berhasil disimpan'
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollback();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => $th->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function dataPdf($fileDirectoryId)
|
||||
{
|
||||
$data = FileDirectory::where('file_directory_id', $fileDirectoryId)->first();
|
||||
|
||||
$filePath = public_path('file/' . $data->file);
|
||||
|
||||
if (!file_exists($filePath)) {
|
||||
abort(404, 'PDF Tidak ditemukan');
|
||||
}
|
||||
|
||||
$stampFile = public_path('assets/copy.png');
|
||||
if (!file_exists($stampFile)) {
|
||||
// kalau watermark tidak ada, tampilkan file asli
|
||||
return response()->file($filePath, [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
||||
]);
|
||||
}
|
||||
|
||||
$tempConverted = storage_path('app/temp/' . uniqid('conv_') . '.pdf');
|
||||
|
||||
try {
|
||||
// coba watermark langsung
|
||||
return $this->watermarkCenterAndStream($filePath, $stampFile);
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
// kalau gagal (PDF modern) -> convert dulu
|
||||
// dd($e);
|
||||
$this->convertWithGhostscript($filePath, $tempConverted);
|
||||
|
||||
$resp = $this->watermarkCenterAndStream($tempConverted, $stampFile);
|
||||
|
||||
@unlink($tempConverted);
|
||||
return $resp;
|
||||
}
|
||||
}
|
||||
|
||||
private function watermarkCenterAndStream(string $pdfPath, string $stampFile)
|
||||
{
|
||||
$pdf = new Fpdi();
|
||||
$pageCount = $pdf->setSourceFile($pdfPath);
|
||||
|
||||
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
|
||||
$tplId = $pdf->importPage($pageNo);
|
||||
$size = $pdf->getTemplateSize($tplId);
|
||||
|
||||
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
|
||||
$pdf->useTemplate($tplId);
|
||||
|
||||
// watermark tengah (skala adaptif)
|
||||
$stampW = $size['width'] * 0.60;
|
||||
$stampH = $stampW * 0.75; // sesuaikan rasio gambar kalau perlu
|
||||
|
||||
$x = ($size['width'] - $stampW) / 2;
|
||||
$y = ($size['height'] - $stampH) / 2;
|
||||
|
||||
$pdf->Image($stampFile, $x, $y, $stampW, $stampH);
|
||||
}
|
||||
|
||||
$output = $pdf->Output('S');
|
||||
|
||||
return response($output, 200, [
|
||||
'Content-Type' => 'application/pdf',
|
||||
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
||||
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
||||
]);
|
||||
}
|
||||
|
||||
private function convertWithGhostscript(string $inputPdf, string $outputPdf): void
|
||||
{
|
||||
$gs = config('services.ghostscript.path');
|
||||
|
||||
if (!$gs || !file_exists($gs)) {
|
||||
throw new \RuntimeException('Ghostscript tidak ditemukan. Cek GHOSTSCRIPT_PATH di .env');
|
||||
}
|
||||
|
||||
$cmd = "\"{$gs}\" -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress "
|
||||
. "-dNOPAUSE -dBATCH -dQUIET -sOutputFile=\"{$outputPdf}\" \"{$inputPdf}\"";
|
||||
|
||||
exec($cmd, $out, $code);
|
||||
|
||||
if ($code !== 0 || !file_exists($outputPdf)) {
|
||||
throw new \RuntimeException('Convert Ghostscript gagal (code=' . $code . ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,4 @@ class FileDirectory extends Model
|
||||
protected $primaryKey = 'file_directory_id';
|
||||
protected $guarded = ['file_directory_id'];
|
||||
|
||||
// protected $with = ['klasifikasi'];
|
||||
|
||||
// // public function klasifikasi(){
|
||||
// // return $this->belongsTo(MasterKlasifikasi::class, 'master_klasifikasi_directory_id', 'master_klasifikasi_directory_id');
|
||||
// // }
|
||||
|
||||
}
|
||||
|
||||
14
app/Models/LogActivity.php
Normal file
14
app/Models/LogActivity.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class LogActivity extends Model
|
||||
{
|
||||
protected $connection = 'dbDirectory';
|
||||
protected $table = 'logging.log_activity_file_directory';
|
||||
public $timestamps = false;
|
||||
protected $primaryKey = 'id';
|
||||
protected $guarded = ['id'];
|
||||
}
|
||||
@ -8,7 +8,9 @@
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"laravel/framework": "^12.0",
|
||||
"laravel/tinker": "^2.10.1"
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"setasign/fpdf": "^1.8",
|
||||
"setasign/fpdi": "^2.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
||||
120
composer.lock
generated
120
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c514d8f7b9fc5970bdd94287905ef584",
|
||||
"content-hash": "26cb6fff423ee0edff5bec050b76b10f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -3274,6 +3274,124 @@
|
||||
},
|
||||
"time": "2025-06-25T14:20:11+00:00"
|
||||
},
|
||||
{
|
||||
"name": "setasign/fpdf",
|
||||
"version": "1.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Setasign/FPDF.git",
|
||||
"reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Setasign/FPDF/zipball/0838e0ee4925716fcbbc50ad9e1799b5edfae0a0",
|
||||
"reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"ext-zlib": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"fpdf.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Olivier Plathey",
|
||||
"email": "oliver@fpdf.org",
|
||||
"homepage": "http://fpdf.org/"
|
||||
}
|
||||
],
|
||||
"description": "FPDF is a PHP class which allows to generate PDF files with pure PHP. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.",
|
||||
"homepage": "http://www.fpdf.org",
|
||||
"keywords": [
|
||||
"fpdf",
|
||||
"pdf"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/Setasign/FPDF/tree/1.8.6"
|
||||
},
|
||||
"time": "2023-06-26T14:44:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "setasign/fpdi",
|
||||
"version": "v2.6.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Setasign/FPDI.git",
|
||||
"reference": "4b53852fde2734ec6a07e458a085db627c60eada"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Setasign/FPDI/zipball/4b53852fde2734ec6a07e458a085db627c60eada",
|
||||
"reference": "4b53852fde2734ec6a07e458a085db627c60eada",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-zlib": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"setasign/tfpdf": "<1.31"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7",
|
||||
"setasign/fpdf": "~1.8.6",
|
||||
"setasign/tfpdf": "~1.33",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"tecnickcom/tcpdf": "^6.8"
|
||||
},
|
||||
"suggest": {
|
||||
"setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"setasign\\Fpdi\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jan Slabon",
|
||||
"email": "jan.slabon@setasign.com",
|
||||
"homepage": "https://www.setasign.com"
|
||||
},
|
||||
{
|
||||
"name": "Maximilian Kresse",
|
||||
"email": "maximilian.kresse@setasign.com",
|
||||
"homepage": "https://www.setasign.com"
|
||||
}
|
||||
],
|
||||
"description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
|
||||
"homepage": "https://www.setasign.com/fpdi",
|
||||
"keywords": [
|
||||
"fpdf",
|
||||
"fpdi",
|
||||
"pdf"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Setasign/FPDI/issues",
|
||||
"source": "https://github.com/Setasign/FPDI/tree/v2.6.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/setasign/fpdi",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-05T09:57:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
"version": "v7.3.0",
|
||||
|
||||
@ -34,5 +34,8 @@ return [
|
||||
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
|
||||
],
|
||||
],
|
||||
'ghostscript' => [
|
||||
'path' => env('GHOSTSCRIPT_PATH'),
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
BIN
public/assets/copy.png
Normal file
BIN
public/assets/copy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 224 KiB |
@ -40,33 +40,20 @@ function renderTree(units, katDok, keyword) {
|
||||
<ul class="file-tree-ul ms-2">
|
||||
${files.map(file => {
|
||||
let fileName = file.file.split('/').pop();
|
||||
let uploadedBy = file.pegawai_nama_entry || "Unknown";
|
||||
let uploadedAt = new Date(file.entry_at).toLocaleString("id-ID", {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
});
|
||||
console.log(file);
|
||||
|
||||
return `
|
||||
<li class="file-tree-li">
|
||||
<div class="">
|
||||
📄 <a href="#"
|
||||
class="file-link"
|
||||
📄
|
||||
<a href="#" class="file-link"
|
||||
data-file="${file?.file}"
|
||||
data-name_file="${fileName}"
|
||||
data-upload="${uploadedBy}"
|
||||
data-time="${uploadedAt}"
|
||||
data-klasifikasi="${file?.klasifikasi?.nama_klasifikasi_directory}"
|
||||
data-id="${file?.file_directory_id}"
|
||||
title="Diupload oleh: ${uploadedBy} pada ${uploadedAt}">
|
||||
${fileName}
|
||||
</a>
|
||||
data-fileName="${fileName || '-'}"
|
||||
data-id="${file.file_directory_id}"
|
||||
data-no_dokumen="${file.no_dokumen || '-'}"
|
||||
data-tanggal_terbit="${file.tanggal_terbit || '-'}" data-permission_file="${file.permission_file || '-'}">${fileName}</a>
|
||||
</div>
|
||||
<small class="text-muted fst-italic">
|
||||
Upload by ${uploadedBy} · ${uploadedAt}
|
||||
</small>
|
||||
|
||||
</li>
|
||||
|
||||
`;
|
||||
|
||||
@ -153,6 +153,7 @@
|
||||
let upload = e.target.getAttribute('data-upload');
|
||||
let time = e.target.getAttribute('data-time');
|
||||
let klasifikasiView = e.target.getAttribute('data-klasifikasi');
|
||||
console.log(fileUrl);
|
||||
|
||||
$("#confirm-upload-dokumen").html(upload);
|
||||
$("#confirm-time-dokumen").html(time);
|
||||
@ -164,17 +165,8 @@
|
||||
|
||||
let ext = fileUrl.split('.').pop().toLowerCase();
|
||||
let previewBox = document.getElementById('file-preview');
|
||||
|
||||
if (['jpg','jpeg','png','gif','webp'].includes(ext)) {
|
||||
previewBox.innerHTML = `<img src="/file/${fileUrl}" class="img-fluid rounded shadow-sm" width="100%" alt="preview">`;
|
||||
} else if (ext === 'pdf') {
|
||||
previewBox.innerHTML = `<iframe src="/file/${fileUrl}" width="100%" height="500px" style="border:none;"></iframe>`;
|
||||
} else {
|
||||
previewBox.innerHTML = `
|
||||
<p class="text-muted">Tidak bisa preview file ini. Silakan download:</p>
|
||||
<a href="/file/${fileUrl}" target="_blank" class="btn btn-sm btn-primary">⬇️ Download</a>
|
||||
`;
|
||||
}
|
||||
previewBox.innerHTML = `<iframe src="/file-preview/${idDirectory}" width="100%" height="500px" style="border:none;"></iframe>`;
|
||||
$("#previewModal").modal('show')
|
||||
|
||||
// 🔥 Tampilkan modal
|
||||
$("#previewModal").modal("show");
|
||||
@ -261,21 +253,21 @@
|
||||
|
||||
}
|
||||
|
||||
$("#download-file").off('click').on('click', function(){
|
||||
if(currentFile){
|
||||
let link = document.createElement('a');
|
||||
link.href = 'file/' + currentFile; // alamat file
|
||||
link.download = currentFile.split('/').pop(); // nama file otomatis
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}else{
|
||||
console.error('error');
|
||||
// $("#download-file").off('click').on('click', function(){
|
||||
// if(currentFile){
|
||||
// let link = document.createElement('a');
|
||||
// link.href = 'file/' + currentFile; // alamat file
|
||||
// link.download = currentFile.split('/').pop(); // nama file otomatis
|
||||
// document.body.appendChild(link);
|
||||
// link.click();
|
||||
// document.body.removeChild(link);
|
||||
// }else{
|
||||
// console.error('error');
|
||||
|
||||
}
|
||||
})
|
||||
// }
|
||||
// })
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
<div class="modal-body p-2" style="min-height:250px; max-height:70vh; overflow:auto;">
|
||||
<div class="d-flex justify-content-end align-items-center sticky-top bg-white z-10">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger mb-2 me-2" id="delete-file">🗑 Hapus</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary mb-2" id="download-file">⬇ Download</button>
|
||||
</div>
|
||||
<div id="file-preview"
|
||||
class="text-center text-muted d-flex justify-content-center align-items-center"
|
||||
@ -24,17 +23,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer d-flex justify-content-between">
|
||||
<div>
|
||||
<div class="text-black">Klasifikasi Dokumen <strong id="confirm-upload-klasifikasi"></strong></div>
|
||||
<div class="mt-2 text-muted fst-italic small text-black">
|
||||
Ditambahkan oleh <strong id="confirm-upload-dokumen"></strong> pada <span id="confirm-time-dokumen"></span>
|
||||
</div>
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer d-flex justify-content-between align-items-center">
|
||||
|
||||
<div class="small text-muted">
|
||||
<span class="me-3">
|
||||
Nomor Dokumen:
|
||||
<strong id="confirm-upload-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span class="me-3">
|
||||
Tanggal Terbit:
|
||||
<strong id="confirm-time-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Akses Dokumen:
|
||||
<span id="confirm-permission" class="badge bg-secondary">-</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Button -->
|
||||
<div class="d-flex gap-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="btn-view-full">
|
||||
Lihat Full
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">
|
||||
Tutup
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,13 +3,14 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<h4 class="mb-0">Data Terakhir</h4>
|
||||
<button type="button" class="btn btn-success" data-bs-target="#modalCreateFile" data-bs-toggle="modal">Tambah File</button>
|
||||
</div>
|
||||
<div class="card-body p-2">
|
||||
<div class="d-flex mb-3">
|
||||
<input type="text" onchange="searchData(this)" class="form-control form-control-sm" placeholder="Search">
|
||||
<button type="button" class="btn btn-primary ms-2">Cari</button>
|
||||
<div class="d-flex align-items-center gap-2 mb-3">
|
||||
<input type="text" onchange="searchData(this)" class="form-control" placeholder="Search">
|
||||
<button type="button" class="btn btn-primary">Cari</button>
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
@ -28,8 +29,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('dashboardV2.modal.create')
|
||||
@include('dashboardV2.modal.view')
|
||||
<script>
|
||||
const katDok = @json($katDok);
|
||||
const authUnitKerja = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]?->unitKerja);
|
||||
const authSubUnitKerja = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]->sub_unit_kerja);
|
||||
const mappingUnitKerjaPegawai = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]);
|
||||
|
||||
function fetchData(){
|
||||
fetch(`/last-document`)
|
||||
.then(response => response.json())
|
||||
@ -49,6 +56,7 @@
|
||||
}
|
||||
tbody.innerHTML = resData.map(item => {
|
||||
const fullPath = item.file;
|
||||
console.log(item);
|
||||
|
||||
const parts = fullPath.split('/');
|
||||
|
||||
@ -57,7 +65,12 @@
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td>${fileName}</td>
|
||||
<td>📄<a href="#" class="file-link"
|
||||
data-file="${item.file}"
|
||||
data-fileName="${fileName || '-'}"
|
||||
data-id="${item.file_directory_id}"
|
||||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||||
data-tanggal_terbit="${item.tanggal_terbit || '-'}" data-permission_file="${item.permission_file || '-'}">${fileName}</a></td>
|
||||
<td>${folderPath}</td>
|
||||
<td>${formatTanggal(item.entry_at)}</td>
|
||||
</tr>
|
||||
@ -81,5 +94,365 @@
|
||||
});
|
||||
}
|
||||
fetchData()
|
||||
|
||||
let colCount = 1;
|
||||
$(document).ready(function() {
|
||||
$('.unit_kerja').select2({
|
||||
placeholder: '--- Pilih Unit Kerja ---',
|
||||
allowClear: true,
|
||||
width: '100%',
|
||||
ajax: {
|
||||
url : '/select-unit-kerja',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function(params){
|
||||
let q = '';
|
||||
if(allAkses){
|
||||
q = params.term;
|
||||
}else{
|
||||
q = authUnitKerja?.name ?? '';
|
||||
}
|
||||
|
||||
return { q };
|
||||
},
|
||||
processResults: function(data){
|
||||
let results = data?.data.map(item => ({
|
||||
id: item.id,
|
||||
text: item.name
|
||||
}));
|
||||
return { results };
|
||||
},
|
||||
cache: true,
|
||||
},
|
||||
minimumInputLength: 0,
|
||||
});
|
||||
|
||||
$('.sub_unit_kerja').select2({
|
||||
placeholder: '-- Pilih Sub Unit Kerja --',
|
||||
allowClear: true,
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
// --- isi default unit kerja ---
|
||||
if(authUnitKerja){
|
||||
let option = new Option(authUnitKerja.name, authUnitKerja.id, true, true);
|
||||
$('.unit_kerja').append(option).trigger('change');
|
||||
}
|
||||
|
||||
let initialUnit = $('.unit_kerja').val();
|
||||
if(initialUnit){
|
||||
loadSubUnitKerja(initialUnit);
|
||||
}
|
||||
|
||||
// jalankan setiap kali unit_kerja berubah
|
||||
$('.unit_kerja').on('change', function(){
|
||||
let idUnit = $(this).val();
|
||||
if(idUnit){
|
||||
loadSubUnitKerja(idUnit);
|
||||
}
|
||||
});
|
||||
|
||||
selectOptionUnitKerjaV1(0);
|
||||
});
|
||||
|
||||
function loadSubUnitKerja(unitId){
|
||||
$('.sub_unit_kerja').empty().append('<option value="" disabled>-- Pilih Sub Unit Kerja --</option>');
|
||||
|
||||
$.ajax({
|
||||
url: `/select-sub-unit-kerja/${unitId}`,
|
||||
method: 'GET',
|
||||
success: function(response) {
|
||||
if (response?.data) {
|
||||
response.data.forEach(unit => {
|
||||
let selected = (authSubUnitKerja && unit.id === authSubUnitKerja.objectsubunitkerjapegawaifk);
|
||||
const option = new Option(unit.name, unit.id, false, selected);
|
||||
$('.sub_unit_kerja').append(option);
|
||||
});
|
||||
$('.sub_unit_kerja').trigger('change');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function addFormV2(){
|
||||
let col = $("#col_add_fileV2");
|
||||
let html = '';
|
||||
|
||||
html += `
|
||||
<div class="row g-3 align-items-start" id="col-${colCount}">
|
||||
<hr class="my-3" />
|
||||
<div class="col-12 d-flex justify-content-end">
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-danger"
|
||||
onclick="removeCol(${colCount})">
|
||||
<i class="fa-solid fa-trash"></i> Hapus
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Unit <span class="text-danger">*</span></label>
|
||||
<select class="form-select"
|
||||
name="data[${colCount}][id_unit_kerja]"
|
||||
id="select_id_unit_kerja_${colCount}"
|
||||
required>
|
||||
<option value="" disabled selected>Pilih Unit</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Sub Unit <span class="text-danger">*</span></label>
|
||||
<select class="form-select"
|
||||
name="data[${colCount}][id_sub_unit_kerja]"
|
||||
id="select_id_sub_unit_kerja_${colCount}"
|
||||
required>
|
||||
<option value="" disabled selected>Pilih Sub Unit</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Kategori Dokumen <span class="text-danger">*</span></label>
|
||||
<select class="form-select"
|
||||
name="data[${colCount}][master_kategori_directory_id]"
|
||||
id="select_kategori_${colCount}"
|
||||
required>
|
||||
<option value="" disabled selected>Pilih Kategori</option>
|
||||
@foreach ($katDok as $kat)
|
||||
<option value="{{ $kat->master_kategori_directory_id }}/{{ $kat->nama_kategori_directory }}">
|
||||
{{ $kat->nama_kategori_directory }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-semibold">Nomor Dokumen</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">#</span>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="data[${colCount}][no_dokumen]"
|
||||
placeholder="Contoh: 001/RS/IT/I/2026">
|
||||
</div>
|
||||
<div class="form-text text-muted">Opsional, isi jika ada nomor resmi dokumen.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-semibold">Tanggal Terbit</label>
|
||||
<input class="form-control"
|
||||
type="date"
|
||||
name="data[${colCount}][date_active]"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-semibold">Boleh dilihat unit lain? <span class="text-danger">*</span></label>
|
||||
|
||||
<div class="border rounded-3 p-2 bg-light">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="radio"
|
||||
name="data[${colCount}][is_permission]"
|
||||
id="perm_yes_${colCount}"
|
||||
value="1"
|
||||
required>
|
||||
<label class="form-check-label" for="perm_yes_${colCount}">Iya</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-1">
|
||||
<input class="form-check-input"
|
||||
type="radio"
|
||||
name="data[${colCount}][is_permission]"
|
||||
id="perm_no_${colCount}"
|
||||
value="2"
|
||||
required>
|
||||
<label class="form-check-label" for="perm_no_${colCount}">Tidak</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<label for="fileUpload_${colCount}" class="form-label fw-semibold">📂 Upload Dokumen (PDF)</label>
|
||||
|
||||
<div class="border rounded-3 p-3 bg-white shadow-sm">
|
||||
<input class="form-control"
|
||||
type="file"
|
||||
id="fileUpload_${colCount}"
|
||||
accept=".pdf"
|
||||
name="data[${colCount}][file]">
|
||||
<div class="mt-2 text-success fw-semibold d-none file-name" id="fileName_${colCount}"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-text text-muted">
|
||||
Format yang didukung: <b>PDF</b>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`;
|
||||
col.append(html)
|
||||
selectOptionUnitKerjaV1(colCount)
|
||||
colCount++;
|
||||
}
|
||||
|
||||
function removeCol(count){
|
||||
$(`#col-${count}`).remove()
|
||||
}
|
||||
|
||||
function selectOptionUnitKerjaV1(colCount) {
|
||||
let selectUnit = $(`#select_id_unit_kerja_${colCount}`);
|
||||
let selectSubUnit = $(`#select_id_sub_unit_kerja_${colCount}`);
|
||||
|
||||
// inisialisasi select2 untuk Unit Kerja
|
||||
selectUnit.select2({
|
||||
placeholder: '-- Pilih Unit Kerja --',
|
||||
allowClear:true,
|
||||
width: '100%',
|
||||
dropdownParent: selectUnit.parent(),
|
||||
ajax:{
|
||||
url : '/select-unit-kerja',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function(params){
|
||||
return { q: params.term }
|
||||
},
|
||||
processResults: function(data){
|
||||
return {
|
||||
results : data?.data.map(item => ({
|
||||
id: item.id+'/'+item.name,
|
||||
text: item.name,
|
||||
sub_units: item.sub_unit_kerja // kirim ke front
|
||||
}))
|
||||
}
|
||||
},
|
||||
cache: true,
|
||||
},
|
||||
minimumInputLength: 1,
|
||||
});
|
||||
|
||||
selectSubUnit.select2({
|
||||
placeholder: '-- Pilih Sub Unit Kerja --',
|
||||
allowClear: true,
|
||||
width: '100%',
|
||||
dropdownParent: selectSubUnit.parent()
|
||||
});
|
||||
|
||||
// event ketika unit kerja dipilih
|
||||
selectUnit.on('select2:select', function (e) {
|
||||
let data = e.params.data; // data unit kerja terpilih
|
||||
selectSubUnit.empty().append('<option value="" disabled selected>-- Pilih Sub Unit Kerja --</option>');
|
||||
|
||||
if (data.sub_units && data.sub_units.length > 0) {
|
||||
data.sub_units.forEach(sub => {
|
||||
selectSubUnit.append(`<option value="${sub.id}/${sub.name}">${sub.name}</option>`);
|
||||
});
|
||||
}
|
||||
|
||||
// aktifkan select2 untuk sub unit
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
let currentFile = null;
|
||||
let idDirectory = null;
|
||||
document.addEventListener('click', function(e){
|
||||
if(e.target.matches('.file-link')){
|
||||
e.preventDefault();
|
||||
let fileUrl = e.target.getAttribute('data-file');
|
||||
let noDokumen = e.target.getAttribute('data-no_dokumen')
|
||||
let tanggalTerbit = e.target.getAttribute('data-tanggal_terbit')
|
||||
let permissionFile = e.target.getAttribute('data-permission_file')
|
||||
let fileName = e.target.getAttribute('data-fileName')
|
||||
currentFile = fileUrl;
|
||||
idDirectory = e.target.getAttribute('data-id');
|
||||
|
||||
|
||||
const titleEl = document.getElementById('confirm_preview_file');
|
||||
if (titleEl) titleEl.textContent = fileName;
|
||||
|
||||
// set footer info
|
||||
const noEl = document.getElementById('confirm-upload-dokumen');
|
||||
if (noEl) noEl.textContent = noDokumen;
|
||||
|
||||
const tglEl = document.getElementById('confirm-time-dokumen');
|
||||
|
||||
if (tglEl) tglEl.textContent = tanggalTerbit;
|
||||
|
||||
const permEl = document.getElementById('confirm-permission');
|
||||
if (permEl) {
|
||||
// contoh label permission biar enak dibaca
|
||||
const isPublic = (permissionFile === 'true' || permissionFile.toLowerCase() === 'iya');
|
||||
permEl.textContent = isPublic ? 'Bisa dilihat unit lain' : 'Hanya unit ini';
|
||||
permEl.className = 'badge ' + (isPublic ? 'bg-success' : 'bg-secondary');
|
||||
}
|
||||
let previewBox = document.getElementById('file-preview');
|
||||
previewBox.innerHTML = `<iframe src="/file-preview/${idDirectory}" width="100%" height="500px" style="border:none;"></iframe>`;
|
||||
$("#previewModal").modal('show')
|
||||
}
|
||||
|
||||
if(e.target.id === 'delete-file'){
|
||||
if(!currentFile){
|
||||
Swal.fire({
|
||||
text: "Tidak ada file yang dipilih!",
|
||||
icon: "warning",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
return;
|
||||
}
|
||||
Swal.fire({
|
||||
title: 'Yakin ingin menghapus file ini?',
|
||||
text: "File akan dihapus",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
cancelButtonColor: '#6c757d',
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal'
|
||||
}).then((result) => {
|
||||
if(result.isConfirmed){
|
||||
fetch(`/delete-file/${idDirectory}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type' : 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
|
||||
},
|
||||
body: JSON.stringify({ file: currentFile })
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if(data.success){
|
||||
Swal.fire({
|
||||
text: 'File berhasil dihapus',
|
||||
icon: 'success',
|
||||
timer: 2000,
|
||||
showConfirmButton: false
|
||||
});
|
||||
$("#previewModal").modal("hide");
|
||||
fetchData()
|
||||
currentFile = null;
|
||||
idDirectory = null;
|
||||
}else{
|
||||
Swal.fire({
|
||||
text: 'Gagal menghapus file',
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
Swal.fire({
|
||||
text: 'Terjadi error saat menghapus file ',
|
||||
icon: 'error'
|
||||
});
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if(e.target.matches('#btn-view-full')){
|
||||
window.open(`/file-preview/${idDirectory}`, '_blank');
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
96
resources/views/dashboardV2/modal/create.blade.php
Normal file
96
resources/views/dashboardV2/modal/create.blade.php
Normal file
@ -0,0 +1,96 @@
|
||||
<div class="modal fade" id="modalCreateFile" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">Aksi </h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<!-- Modal Form -->
|
||||
<form id="formFile" action="/uploadv2" enctype="multipart/form-data" method="POST">
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<div class="container" style="max-height: 70vh; overflow-y:auto;">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Unit <span class="text-danger">*</span></label>
|
||||
<select class="form-control unit_kerja" name="data[0][id_unit_kerja]" id="select_id_unit_kerja_0" required>
|
||||
<option value="" disable>Select Choose</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Sub Unit <span class="text-danger">*</span></label>
|
||||
<select class="form-control" name="data[0][id_sub_unit_kerja]" id="select_id_sub_unit_kerja_0" required>
|
||||
<option value="" disable selected>Select Choose</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-semibold">Kategori Dokumen <span class="text-danger">*</span></label>
|
||||
<select class="form-control" name="data[0][master_kategori_directory_id]" id="select_kategori_0" required>
|
||||
<option value="" disable>Select Choose</option>
|
||||
@foreach ($katDok as $kat)
|
||||
<option value="{{ $kat->master_kategori_directory_id }}/{{ $kat->nama_kategori_directory }}">{{ $kat->nama_kategori_directory }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-semibold">Nomor Dokumen</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">#</span>
|
||||
<input type="text" class="form-control" name="data[0][no_dokumen]" placeholder="Contoh: 001/RS/IT/I/2026">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-semibold">Tanggal Terbit</label>
|
||||
<input class="form-control" type="date" name="data[0][date_active]" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-semibold">Boleh dilihat unit lain? <span class="text-danger">*</span></label>
|
||||
|
||||
<div class="border rounded-3 p-2 bg-light">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="data[0][is_permission]" id="perm_yes" value="1" required>
|
||||
<label class="form-check-label" for="perm_yes">
|
||||
Iya
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-1">
|
||||
<input class="form-check-input" type="radio" name="data[0][is_permission]" id="perm_no" value="2" required>
|
||||
<label class="form-check-label" for="perm_no">
|
||||
Tidak
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 mb-2">
|
||||
<label for="fileUpload0" class="form-label fw-semibold">📂 Upload Dokumen (PDF)</label>
|
||||
<div class="border rounded-3 p-3 bg-white shadow-sm">
|
||||
<input class="form-control" type="file" id="fileUpload0" accept=".pdf" name="data[0][file]">
|
||||
<div class="mt-2 text-success fw-semibold d-none file-name"></div>
|
||||
</div>
|
||||
<div class="form-text text-muted">
|
||||
Bisa upload lebih dari 1 file. Format yang didukung: <b>PDF</b>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="col_add_fileV2" class="col-12"></div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm mt-3" onclick="addFormV2()">
|
||||
+ Tambah Form
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Footer -->
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
||||
<button type="submit" class="btn btn-primary">Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
61
resources/views/dashboardV2/modal/view.blade.php
Normal file
61
resources/views/dashboardV2/modal/view.blade.php
Normal file
@ -0,0 +1,61 @@
|
||||
<!-- Modal Preview -->
|
||||
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="modal-header">
|
||||
<h6 class="modal-title" id="previewModalLabel">
|
||||
📄 Preview <strong id="confirm_preview_file"></strong>
|
||||
</h6>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="modal-body p-2" style="min-height:250px; max-height:70vh; overflow:auto;">
|
||||
<div class="d-flex justify-content-end align-items-center sticky-top bg-white z-10">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger mb-2 me-2" id="delete-file">🗑 Hapus</button>
|
||||
</div>
|
||||
<div id="file-preview"
|
||||
class="text-center text-muted d-flex justify-content-center align-items-center"
|
||||
style="height:100%;">
|
||||
<p>📂 Pilih file untuk melihat preview</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer d-flex justify-content-between align-items-center">
|
||||
|
||||
<div class="small text-muted">
|
||||
<span class="me-3">
|
||||
Nomor Dokumen:
|
||||
<strong id="confirm-upload-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span class="me-3">
|
||||
Tanggal Terbit:
|
||||
<strong id="confirm-time-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Akses Dokumen:
|
||||
<span id="confirm-permission" class="badge bg-secondary">-</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Button -->
|
||||
<div class="d-flex gap-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="btn-view-full">
|
||||
Lihat Full
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">
|
||||
Tutup
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
</a>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
{{-- <li class="sidebar-item">
|
||||
<a class="sidebar-link justify-content-between"
|
||||
href="/master-klasifikasi" aria-expanded="false">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
@ -53,7 +53,7 @@
|
||||
<span class="hide-menu">Master Klasifikasi</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</li> --}}
|
||||
<li class="sidebar-item">
|
||||
<a class="sidebar-link justify-content-between"
|
||||
href="/akses" aria-expanded="false">
|
||||
|
||||
@ -12,6 +12,8 @@ Route::middleware(['auth'])->group(function(){
|
||||
Route::get('/', [DashboardController::class, 'index']);
|
||||
Route::get('/new', [DashboardController::class, 'dashboardVersion2']);
|
||||
Route::get('/last-document', [DashboardController::class, 'dataDocumentLast']);
|
||||
Route::post('/uploadv2', [DashboardController::class, 'storeVersion2']);
|
||||
Route::get('/file-preview/{id}', [DashboardController::class, 'dataPdf']);
|
||||
Route::post('/upload', [DashboardController::class, 'store']);
|
||||
Route::get('/data-unit-kerja', [DashboardController::class, 'dataUnitKerja']);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user