Files
cms-gov/app/Views/admin/pages/form.php

229 lines
10 KiB
PHP
Raw Permalink Normal View History

<?= $this->extend('admin/layout') ?>
<?= $this->section('content') ?>
<div class="space-y-5 sm:space-y-6">
<!-- Page Header -->
<div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<div>
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white/90">
<?= $page ? 'Edit Halaman' : 'Tambah Halaman' ?>
</h2>
<p class="text-sm text-gray-500 dark:text-gray-400">
<?= $page ? 'Ubah informasi halaman' : 'Tambahkan halaman baru' ?>
</p>
</div>
<div class="flex items-center gap-2">
<span id="autosave-indicator" class="hidden text-sm text-gray-500 dark:text-gray-400">Disimpan otomatis</span>
<button
type="button"
id="preview-btn"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2.5 text-sm font-medium text-gray-700 shadow-theme-xs hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-white/[0.03]"
>
<i class="fe fe-eye"></i>
Preview
</button>
</div>
</div>
<!-- Form -->
<form
action="<?= $page ? base_url('admin/pages/update/' . $page['id']) : base_url('admin/pages/store') ?>"
method="post"
class="space-y-6"
id="page-form"
>
<?= csrf_field() ?>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<!-- Main Content Area (2/3 width) -->
<div class="lg:col-span-2 space-y-6">
<!-- Title -->
<div class="rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/[0.03]">
<div class="p-5 sm:p-6">
<label class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400">
Judul <span class="text-error-500">*</span>
</label>
<input
type="text"
name="title"
id="title"
value="<?= old('title', $page['title'] ?? '') ?>"
placeholder="Masukkan judul halaman"
class="h-11 w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:focus:border-brand-800"
required
>
<?php if (isset($validation) && $validation->hasError('title')): ?>
<p class="mt-1 text-sm text-error-600"><?= esc($validation->getError('title')) ?></p>
<?php endif; ?>
</div>
</div>
<!-- Editor.js Container -->
<div class="rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/[0.03]">
<div class="p-5 sm:p-6">
<label class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400">
Konten <span class="text-error-500">*</span>
</label>
<div id="editorjs" class="min-h-[500px] rounded-lg border border-gray-300 bg-white p-4 dark:border-gray-700 dark:bg-gray-900"></div>
<!-- Hidden inputs for Editor.js data -->
<input type="hidden" name="content" id="content" value="<?= esc($page['content'] ?? '') ?>">
<input type="hidden" name="content_json" id="content_json" value="<?= esc($page['content_json'] ?? '') ?>">
<input type="hidden" name="content_html" id="content_html" value="<?= esc($page['content_html'] ?? '') ?>">
<input type="hidden" name="excerpt" id="excerpt" value="<?= esc($page['excerpt'] ?? '') ?>">
<?php if (isset($validation) && $validation->hasError('content_json')): ?>
<p class="mt-1 text-sm text-error-600"><?= esc($validation->getError('content_json')) ?></p>
<?php endif; ?>
</div>
</div>
</div>
<!-- Sidebar (1/3 width) - Document Settings -->
<div class="space-y-6">
<!-- Status -->
<div class="rounded-lg border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/[0.03]">
<div class="p-5 sm:p-6">
<h3 class="mb-4 text-sm font-semibold text-gray-700 dark:text-gray-300">Pengaturan Dokumen</h3>
<div class="space-y-4">
<div>
<label class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400">
Status <span class="text-error-500">*</span>
</label>
<select
name="status"
id="status"
class="h-11 w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:focus:border-brand-800"
required
>
<option value="draft" <?= old('status', $page['status'] ?? 'draft') === 'draft' ? 'selected' : '' ?>>Draft</option>
<option value="published" <?= old('status', $page['status'] ?? '') === 'published' ? 'selected' : '' ?>>Published</option>
</select>
<?php if (isset($validation) && $validation->hasError('status')): ?>
<p class="mt-1 text-sm text-error-600"><?= esc($validation->getError('status')) ?></p>
<?php endif; ?>
</div>
<div>
<label class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400">
Excerpt
</label>
<textarea
name="excerpt"
id="excerpt-textarea"
rows="3"
placeholder="Ringkasan halaman (otomatis dari konten pertama)"
class="w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:focus:border-brand-800"
><?= old('excerpt', $page['excerpt'] ?? '') ?></textarea>
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Akan diisi otomatis dari paragraf pertama</p>
</div>
<div>
<label class="mb-1.5 block text-sm font-medium text-gray-700 dark:text-gray-400">
Featured Image URL
</label>
<input
type="url"
name="featured_image"
id="featured_image"
value="<?= old('featured_image', $page['featured_image'] ?? '') ?>"
placeholder="https://example.com/image.jpg"
class="h-11 w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:focus:border-brand-800"
>
<?php if (!empty($page['featured_image'] ?? '')): ?>
<div class="mt-2">
<img src="<?= esc($page['featured_image']) ?>" alt="Featured" class="h-24 w-full rounded-lg object-cover">
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Form Actions - Match grid layout -->
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<div class="lg:col-span-2">
<div class="flex items-center justify-end gap-3 rounded-lg border border-gray-200 bg-white p-5 dark:border-gray-800 dark:bg-white/[0.03]">
<a
href="<?= base_url('admin/pages') ?>"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-gray-300 bg-white px-4 py-2.5 text-sm font-medium text-gray-700 shadow-theme-xs hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-white/[0.03]"
>
Batal
</a>
<button
type="submit"
class="inline-flex items-center justify-center gap-2 rounded-lg bg-brand-500 px-4 py-2.5 text-sm font-medium text-white shadow-theme-xs hover:bg-brand-600"
>
<i class="fe fe-save"></i>
<?= $page ? 'Simpan Perubahan' : 'Simpan Halaman' ?>
</button>
</div>
</div>
</div>
</form>
</div>
<!-- Editor.js Bundle (Built by Vite) -->
<?php
// Get manifest file to load hashed assets
$manifestPath = FCPATH . 'assets/editor/.vite/manifest.json';
$editorJsPath = base_url('assets/editor/editor.js'); // Fallback
if (file_exists($manifestPath)) {
$manifest = json_decode(file_get_contents($manifestPath), true);
if (isset($manifest['resources/js/editor/editor.js'])) {
$editorJsPath = base_url('assets/editor/' . $manifest['resources/js/editor/editor.js']['file']);
}
}
?>
<script src="<?= $editorJsPath ?>"></script>
<script>
// CSRF & Endpoints for Editor.js
window.csrfTokenName = '<?= csrf_token() ?>';
window.csrfTokenValue = '<?= csrf_hash() ?>';
window.csrfHeaderName = '<?= csrf_header() ?>';
window.uploadEndpoint = '<?= base_url('admin/upload') ?>';
window.linkPreviewEndpoint = '<?= base_url('admin/link-preview') ?>';
window.pageId = <?= $page ? $page['id'] : 'null' ?>;
// Sync excerpt textarea with hidden input
const excerptTextarea = document.getElementById('excerpt-textarea');
const excerptInput = document.getElementById('excerpt');
if (excerptTextarea && excerptInput) {
excerptTextarea.addEventListener('input', function() {
excerptInput.value = this.value;
});
}
// Fix Editor.js toolbar z-index to stay below header
document.addEventListener('DOMContentLoaded', function() {
const style = document.createElement('style');
style.textContent = `
.ce-toolbar,
.ce-inline-toolbar,
.ce-popover,
.ce-conversion-toolbar,
.ce-settings,
.ce-block-settings,
.ce-toolbar__plus,
.ce-toolbar__settings-btn,
.ce-popover__item,
.ce-popover__items,
.ce-settings__button {
z-index: 10 !important;
}
header,
header[class*="sticky"],
header[class*="fixed"] {
z-index: 99999 !important;
}
`;
document.head.appendChild(style);
});
</script>
<?= $this->endSection() ?>