feat: reorganize admin settings with tabbed interface and documentation

- Reorganized admin settings into tabbed interface (General, Security, Payment Methods)
- Vertical tabs on desktop, horizontal scrollable on mobile
- Moved Payment Methods from separate menu to Settings tab
- Fixed admin profile reuse and dashboard blocking
- Fixed maintenance mode guard to use AppConfig model
- Added admin auto-redirect after login (admins → /admin, users → /)
- Reorganized documentation into docs/ folder structure
- Created comprehensive README and documentation index
- Added PWA and Web Push notifications to to-do list
This commit is contained in:
dwindown
2025-10-13 09:28:12 +07:00
parent 49d60676d0
commit 89f881e7cf
99 changed files with 4884 additions and 392 deletions

View File

@@ -29,7 +29,7 @@ export function AdminSettings() {
enableEmailVerification: true,
enablePaymentVerification: true,
maintenanceMode: false,
maintenanceMessage: 'Sistem sedang dalam pemeliharaan. Mohon coba lagi nanti.',
maintenanceMessage: 'System is under maintenance. Please try again later.',
})
const [loading, setLoading] = useState(true)
const [saving, setSaving] = useState(false)
@@ -65,7 +65,7 @@ export function AdminSettings() {
enableEmailVerification: configData.features?.find((c) => c.key === 'enable_email_verification')?.value === 'true',
enablePaymentVerification: configData.features?.find((c) => c.key === 'enable_payment_verification')?.value === 'true',
maintenanceMode: configData.system?.find((c) => c.key === 'maintenance_mode')?.value === 'true',
maintenanceMessage: configData.system?.find((c) => c.key === 'maintenance_message')?.value || 'Sistem sedang dalam pemeliharaan. Mohon coba lagi nanti.',
maintenanceMessage: configData.system?.find((c) => c.key === 'maintenance_message')?.value || 'System is under maintenance. Please try again later.',
}
setSettings(settingsObj)
} catch (error) {
@@ -82,14 +82,14 @@ export function AdminSettings() {
// Save each setting individually
const configUpdates = [
{ key: 'app_name', value: settings.appName, category: 'general', label: 'Nama Aplikasi', type: 'text' },
{ key: 'app_url', value: settings.appUrl, category: 'general', label: 'URL Aplikasi', type: 'text' },
{ key: 'support_email', value: settings.supportEmail, category: 'general', label: 'Email Support', type: 'email' },
{ key: 'enable_registration', value: String(settings.enableRegistration), category: 'features', label: 'Registrasi Pengguna Baru', type: 'boolean' },
{ key: 'enable_email_verification', value: String(settings.enableEmailVerification), category: 'features', label: 'Verifikasi Email', type: 'boolean' },
{ key: 'enable_payment_verification', value: String(settings.enablePaymentVerification), category: 'features', label: 'Verifikasi Pembayaran', type: 'boolean' },
{ key: 'maintenance_mode', value: String(settings.maintenanceMode), category: 'system', label: 'Mode Pemeliharaan', type: 'boolean' },
{ key: 'maintenance_message', value: settings.maintenanceMessage, category: 'system', label: 'Pesan Pemeliharaan', type: 'text' },
{ key: 'app_name', value: settings.appName, category: 'general', label: 'Application Name', type: 'text' },
{ key: 'app_url', value: settings.appUrl, category: 'general', label: 'Application URL', type: 'text' },
{ key: 'support_email', value: settings.supportEmail, category: 'general', label: 'Support Email', type: 'email' },
{ key: 'enable_registration', value: String(settings.enableRegistration), category: 'features', label: 'New User Registration', type: 'boolean' },
{ key: 'enable_email_verification', value: String(settings.enableEmailVerification), category: 'features', label: 'Email Verification', type: 'boolean' },
{ key: 'enable_payment_verification', value: String(settings.enablePaymentVerification), category: 'features', label: 'Payment Verification', type: 'boolean' },
{ key: 'maintenance_mode', value: String(settings.maintenanceMode), category: 'system', label: 'Maintenance Mode', type: 'boolean' },
{ key: 'maintenance_message', value: settings.maintenanceMessage, category: 'system', label: 'Maintenance Message', type: 'text' },
]
await Promise.all(
@@ -100,11 +100,11 @@ export function AdminSettings() {
)
)
toast.success('Pengaturan berhasil disimpan')
toast.success('Settings saved successfully')
fetchSettings() // Refresh
} catch (error) {
console.error('Failed to save settings:', error)
toast.error('Gagal menyimpan pengaturan')
toast.error('Failed to save settings')
} finally {
setSaving(false)
}
@@ -117,7 +117,7 @@ export function AdminSettings() {
if (loading) {
return (
<div className="flex items-center justify-center h-64">
<div className="text-muted-foreground">Memuat...</div>
<div className="text-muted-foreground">Loading...</div>
</div>
)
}
@@ -125,9 +125,9 @@ export function AdminSettings() {
return (
<div className="max-w-4xl mx-auto">
<div className="mb-8">
<h1 className="text-3xl font-bold text-foreground">Pengaturan Aplikasi</h1>
<h1 className="text-3xl font-bold text-foreground">Application Settings</h1>
<p className="mt-2 text-muted-foreground">
Kelola konfigurasi dan pengaturan sistem
Manage system configuration and settings
</p>
</div>
@@ -139,15 +139,15 @@ export function AdminSettings() {
<Globe className="h-5 w-5 text-primary" />
</div>
<div>
<h2 className="text-lg font-semibold text-foreground">Pengaturan Umum</h2>
<p className="text-sm text-muted-foreground">Informasi dasar aplikasi</p>
<h2 className="text-lg font-semibold text-foreground">General Settings</h2>
<p className="text-sm text-muted-foreground">Basic application information</p>
</div>
</div>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Nama Aplikasi
Application Name
</label>
<Input
type="text"
@@ -158,7 +158,7 @@ export function AdminSettings() {
<div>
<label className="block text-sm font-medium text-foreground mb-2">
URL Aplikasi
Application URL
</label>
<Input
type="url"
@@ -187,17 +187,17 @@ export function AdminSettings() {
<Shield className="h-5 w-5 text-primary" />
</div>
<div>
<h2 className="text-lg font-semibold text-foreground">Fitur & Keamanan</h2>
<p className="text-sm text-muted-foreground">Aktifkan atau nonaktifkan fitur</p>
<h2 className="text-lg font-semibold text-foreground">Features & Security</h2>
<p className="text-sm text-muted-foreground">Enable or disable features</p>
</div>
</div>
<div className="space-y-4">
<div className="flex items-center justify-between p-4 rounded-lg bg-muted/50">
<div>
<p className="font-medium text-foreground">Registrasi Pengguna Baru</p>
<p className="font-medium text-foreground">New User Registration</p>
<p className="text-sm text-muted-foreground">
Izinkan pengguna baru mendaftar
Allow new users to register
</p>
</div>
<Switch
@@ -208,9 +208,9 @@ export function AdminSettings() {
<div className="flex items-center justify-between p-4 rounded-lg bg-muted/50">
<div>
<p className="font-medium text-foreground">Verifikasi Email</p>
<p className="font-medium text-foreground">Email Verification</p>
<p className="text-sm text-muted-foreground">
Wajibkan verifikasi email untuk pengguna baru
Require email verification for new users
</p>
</div>
<Switch
@@ -221,9 +221,9 @@ export function AdminSettings() {
<div className="flex items-center justify-between p-4 rounded-lg bg-muted/50">
<div>
<p className="font-medium text-foreground">Verifikasi Pembayaran Manual</p>
<p className="font-medium text-foreground">Manual Payment Verification</p>
<p className="text-sm text-muted-foreground">
Aktifkan verifikasi manual untuk pembayaran
Enable manual verification for payments
</p>
</div>
<Switch
@@ -241,9 +241,9 @@ export function AdminSettings() {
<Database className="h-5 w-5 text-primary" />
</div>
<div>
<h2 className="text-lg font-semibold text-foreground">Mode Pemeliharaan</h2>
<h2 className="text-lg font-semibold text-foreground">Maintenance Mode</h2>
<p className="text-sm text-muted-foreground">
Nonaktifkan akses sementara untuk maintenance
Temporarily disable access for maintenance
</p>
</div>
</div>
@@ -251,9 +251,9 @@ export function AdminSettings() {
<div className="space-y-4">
<div className="flex items-center justify-between p-4 rounded-lg bg-destructive/10 border border-destructive/20">
<div>
<p className="font-medium text-foreground">Mode Pemeliharaan</p>
<p className="font-medium text-foreground">Maintenance Mode</p>
<p className="text-sm text-muted-foreground">
Aktifkan untuk menutup akses sementara
Enable to temporarily close access
</p>
</div>
<Switch
@@ -266,7 +266,7 @@ export function AdminSettings() {
{settings.maintenanceMode && (
<div>
<label className="block text-sm font-medium text-foreground mb-2">
Pesan Pemeliharaan
Maintenance Message
</label>
<Textarea
value={settings.maintenanceMessage}
@@ -286,7 +286,7 @@ export function AdminSettings() {
className="flex items-center gap-2"
>
<Save className="h-5 w-5" />
{saving ? 'Menyimpan...' : 'Simpan Pengaturan'}
{saving ? 'Saving...' : 'Save Settings'}
</Button>
</div>
</div>