39303-vm/document.php
2026-03-25 07:58:17 +00:00

252 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
require_once __DIR__ . '/archive_bootstrap.php';
ensure_archive_schema();
require_auth();
$documentId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$document = $documentId > 0 ? get_document($documentId) : null;
if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string)($_POST['action'] ?? '') === 'validate_document' && $document) {
validate_document($documentId, current_user(), trim((string)($_POST['validation_notes'] ?? '')));
header('Location: document.php?id=' . $documentId);
exit;
}
$document = $documentId > 0 ? get_document($documentId) : null;
if (!$document) {
http_response_code(404);
}
$meta = page_meta('Detail Arsip KBRI Harare', 'Detail arsip digital, validasi, dan akses pratinjau aman KBRI Harare.');
$flashes = get_flashes();
$user = current_user();
$activity = $document ? document_activity($document) : [];
$canAccessFile = $document ? can_access_document_file($document) : false;
$canPreview = $document ? ($canAccessFile && can_preview_inline($document)) : false;
?>
<!doctype html>
<html lang="id" data-bs-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><?= h($meta['title']) ?></title>
<?php if ($meta['description'] !== ''): ?>
<meta name="description" content="<?= h($meta['description']) ?>" />
<meta property="og:description" content="<?= h($meta['description']) ?>" />
<meta property="twitter:description" content="<?= h($meta['description']) ?>" />
<?php endif; ?>
<?php if ($meta['image'] !== ''): ?>
<meta property="og:image" content="<?= h($meta['image']) ?>" />
<meta property="twitter:image" content="<?= h($meta['image']) ?>" />
<?php endif; ?>
<meta property="og:title" content="<?= h($meta['title']) ?>" />
<meta property="twitter:title" content="<?= h($meta['title']) ?>" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?= urlencode((string)filemtime(__DIR__ . '/assets/css/custom.css')) ?>">
</head>
<body class="archive-app app-authenticated detail-page">
<div class="toast-container position-fixed top-0 end-0 p-3">
<?php foreach ($flashes as $flash): ?>
<div class="toast align-items-center text-bg-<?= h($flash['type']) ?> border-0 mb-2" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="4500">
<div class="d-flex">
<div class="toast-body"><?= h($flash['message']) ?></div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<?php endforeach; ?>
</div>
<header class="topbar topbar-static">
<div class="d-flex align-items-center gap-3">
<a href="index.php" class="btn btn-outline-secondary btn-sm"><i class="bi bi-arrow-left me-2"></i>Kembali</a>
<div>
<p class="section-kicker mb-1">Detail arsip</p>
<h1 class="h4 mb-0">Pusat validasi & pratinjau dokumen</h1>
</div>
</div>
<div class="d-flex align-items-center gap-2 gap-lg-3">
<button class="btn btn-outline-secondary btn-sm theme-toggle" type="button" data-theme-toggle>
<i class="bi bi-moon-stars"></i>
</button>
<div class="profile-chip static-chip">
<span class="avatar"><?= h($user['avatar'] ?? 'U') ?></span>
<span class="text-start d-none d-md-inline-block">
<strong class="d-block"><?= h($user['name']) ?></strong>
<small class="text-secondary"><?= h($user['role_label'] ?? '') ?></small>
</span>
</div>
</div>
</header>
<main class="detail-layout container-fluid px-3 px-lg-4 py-4">
<?php if (!$document): ?>
<section class="card border-0 shadow-sm">
<div class="card-body p-5 text-center">
<i class="bi bi-file-earmark-x display-5 text-secondary"></i>
<h2 class="h4 mt-3">Dokumen tidak ditemukan</h2>
<p class="text-secondary">ID arsip tidak tersedia atau telah berubah.</p>
<a href="index.php" class="btn btn-primary">Kembali ke dashboard</a>
</div>
</section>
<?php else: ?>
<div class="row g-4 align-items-start">
<div class="col-12 col-xl-8">
<section class="card border-0 shadow-sm mb-4">
<div class="card-body p-4">
<div class="d-flex flex-column flex-lg-row justify-content-between gap-3 mb-3">
<div>
<div class="d-flex flex-wrap gap-2 align-items-center mb-2">
<span class="status-pill <?= $document['status'] === 'validated' ? 'validated' : 'pending' ?>"><?= $document['status'] === 'validated' ? 'Tervalidasi' : 'Menunggu Validasi' ?></span>
<span class="badge text-bg-secondary-subtle text-secondary-emphasis border"><?= h($document['category']) ?></span>
</div>
<h2 class="h3 mb-1"><?= h($document['title']) ?></h2>
<p class="text-secondary mb-0"><?= h($document['folder_path']) ?></p>
</div>
<div class="detail-actions d-flex flex-wrap gap-2">
<?php if ($canAccessFile): ?>
<a href="file.php?id=<?= (int)$document['id'] ?>&disposition=download" class="btn btn-outline-secondary"><i class="bi bi-download me-2"></i>Unduh</a>
<?php if ($canPreview): ?>
<a href="file.php?id=<?= (int)$document['id'] ?>&disposition=inline" class="btn btn-outline-secondary" target="_blank" rel="noopener"><i class="bi bi-eye me-2"></i>Pratinjau</a>
<button class="btn btn-primary" type="button" onclick="window.print()"><i class="bi bi-printer me-2"></i>Cetak</button>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
<div class="row g-3 detail-meta">
<div class="col-6 col-lg-3">
<span class="meta-label">Tanggal dokumen</span>
<strong><?= h(date('d M Y', strtotime((string)$document['document_date']))) ?></strong>
</div>
<div class="col-6 col-lg-3">
<span class="meta-label">Departemen</span>
<strong><?= h($document['department']) ?></strong>
</div>
<div class="col-6 col-lg-3">
<span class="meta-label">Diunggah oleh</span>
<strong><?= h($document['created_by']) ?></strong>
</div>
<div class="col-6 col-lg-3">
<span class="meta-label">Lampiran</span>
<strong><?= h(strtoupper((string)$document['attachment_ext'])) ?> · <?= h(format_filesize((int)$document['attachment_size'])) ?></strong>
</div>
</div>
<?php if ($document['notes']): ?>
<div class="annotation-box mt-4">
<span class="meta-label">Catatan dokumen</span>
<p class="mb-0"><?= nl2br(h($document['notes'])) ?></p>
</div>
<?php endif; ?>
</div>
</section>
<section class="card border-0 shadow-sm">
<div class="card-body p-4">
<div class="d-flex justify-content-between align-items-start gap-3 mb-3">
<div>
<p class="section-kicker mb-2">Pratinjau aman</p>
<h2 class="h5 mb-1">Akses file sesuai status validasi</h2>
</div>
<span class="badge text-bg-dark"><?= $canAccessFile ? 'Akses dibuka' : 'Terkunci' ?></span>
</div>
<?php if ($canPreview): ?>
<div class="preview-frame">
<?php if (in_array(strtolower((string)$document['attachment_ext']), ['jpg', 'jpeg', 'png'], true)): ?>
<img src="file.php?id=<?= (int)$document['id'] ?>&disposition=inline" alt="Pratinjau <?= h($document['title']) ?>" class="img-fluid rounded-3 w-100">
<?php elseif (strtolower((string)$document['attachment_ext']) === 'mp4'): ?>
<video controls class="w-100 rounded-3" preload="metadata">
<source src="file.php?id=<?= (int)$document['id'] ?>&disposition=inline" type="video/mp4">
</video>
<?php else: ?>
<iframe src="file.php?id=<?= (int)$document['id'] ?>&disposition=inline" title="Pratinjau dokumen" class="preview-iframe"></iframe>
<?php endif; ?>
</div>
<?php elseif ($canAccessFile): ?>
<div class="empty-panel tall">
<i class="bi bi-file-earmark-lock2"></i>
<p class="mb-1 fw-semibold">Jenis file tidak mendukung pratinjau inline.</p>
<p class="mb-0 text-secondary small">Unduh lampiran untuk membuka dokumen ini.</p>
</div>
<?php else: ?>
<div class="empty-panel tall">
<i class="bi bi-shield-lock"></i>
<p class="mb-1 fw-semibold">Pratinjau dikunci sampai validasi selesai.</p>
<p class="mb-0 text-secondary small">Setelah disetujui Super Admin, staf dapat pratinjau, unduh, dan cetak dari halaman ini.</p>
</div>
<?php endif; ?>
</div>
</section>
</div>
<div class="col-12 col-xl-4">
<?php if (is_super_admin() && $document['status'] !== 'validated'): ?>
<section class="card border-0 shadow-sm mb-4">
<div class="card-body p-4">
<p class="section-kicker mb-2">Aksi Super Admin</p>
<h2 class="h5 mb-1">Validasi dokumen</h2>
<p class="text-secondary small">Setelah disetujui, dokumen terbuka untuk pratinjau, unduh, dan cetak oleh staf terkait.</p>
<form method="post" class="vstack gap-3 mt-3">
<input type="hidden" name="csrf_token" value="<?= h(csrf_token()) ?>">
<input type="hidden" name="action" value="validate_document">
<div>
<label class="form-label" for="validation_notes">Catatan validasi</label>
<textarea id="validation_notes" class="form-control" name="validation_notes" rows="4" placeholder="Contoh: Metadata sesuai, siap diakses unit kerja."></textarea>
</div>
<button type="submit" class="btn btn-primary"><i class="bi bi-patch-check me-2"></i>Validasi dokumen</button>
</form>
</div>
</section>
<?php endif; ?>
<section class="card border-0 shadow-sm mb-4">
<div class="card-body p-4">
<p class="section-kicker mb-2">Status akses</p>
<h2 class="h5 mb-1">Ringkasan kepatuhan</h2>
<ul class="list-unstyled security-list mb-0">
<li><i class="bi bi-check2-circle"></i><span>Password user demo diproses dengan verifikasi Bcrypt.</span></li>
<li><i class="bi bi-check2-circle"></i><span>Form terlindungi CSRF token dan prepared statements PDO.</span></li>
<li><i class="bi bi-check2-circle"></i><span>File hanya di-stream melalui gerbang aplikasi, bukan tautan publik langsung.</span></li>
<li><i class="bi bi-check2-circle"></i><span><?= $document['status'] === 'validated' ? 'Dokumen siap diakses sesuai hak role.' : 'Dokumen menunggu otorisasi Super Admin.' ?></span></li>
</ul>
</div>
</section>
<section class="card border-0 shadow-sm">
<div class="card-body p-4">
<p class="section-kicker mb-2">Audit trail</p>
<h2 class="h5 mb-1">Riwayat aktivitas</h2>
<div class="timeline mt-3">
<?php foreach ($activity as $entry): ?>
<article class="timeline-item">
<span class="timeline-dot"></span>
<div>
<strong class="d-block text-capitalize"><?= h($entry['action'] ?? '') ?></strong>
<small class="text-secondary d-block"><?= h($entry['actor'] ?? '') ?> · <?= h($entry['timestamp'] ?? '') ?></small>
<?php if (!empty($entry['notes'])): ?>
<p class="mb-0 mt-2 text-secondary small"><?= h($entry['notes']) ?></p>
<?php endif; ?>
</div>
</article>
<?php endforeach; ?>
</div>
</div>
</section>
</div>
</div>
<?php endif; ?>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?= urlencode((string)filemtime(__DIR__ . '/assets/js/main.js')) ?>"></script>
</body>
</html>