diff --git a/Dashboard-MD/BANTUAN.md b/Dashboard-MD/BANTUAN.md
new file mode 100644
index 0000000..326ff08
--- /dev/null
+++ b/Dashboard-MD/BANTUAN.md
@@ -0,0 +1,453 @@
+Design Contract – Halaman Bantuan / Support Center
+
+Dokumen ini adalah kontrak desain UI/UX untuk halaman Bantuan / Support Center.
+Implementasi tidak dapat dilanjutkan tanpa mengikuti spesifikasi ini secara konsisten.
+
+1. Tujuan Halaman
+
+Halaman Bantuan bertujuan untuk:
+
+Memberikan akses cepat ke panduan & dokumentasi
+
+Menyediakan video tutorial
+
+Menjawab pertanyaan umum (FAQ)
+
+Menyediakan kontak support
+
+Menyediakan virtual assistant (chat)
+
+Menampilkan statistik kredibilitas platform
+
+2. Struktur Layout Keseluruhan
+Layout Grid
+
+Menggunakan 3-column responsive grid.
+
+Desktop (≥ 1200px)
+
+Grid: 3 columns
+
+Gap: 32px
+
+Container max-width: 1200px – 1320px
+
+Center aligned
+
+Tablet (768px – 1199px)
+
+Grid: 2 columns
+
+Gap: 24px
+
+Mobile (< 768px)
+
+Grid: 1 column
+
+Gap: 16px
+
+Card full width
+
+3. Struktur Komponen UI
+3.1 Card Utama (Reusable Component)
+
+Semua section menggunakan komponen dasar:
+
+Card
+ ├── Icon Container
+ ├── Title
+ ├── List / Content
+
+Spesifikasi Card
+
+Border radius: 16px
+
+Padding: 24px
+
+Shadow:
+
+Light: soft shadow
+
+Dark: subtle glow / low-opacity shadow
+
+Transition hover: 0.2s ease
+
+Hover effect:
+
+Slight lift (translateY(-2px))
+
+Elevation shadow increase
+
+4. Daftar Komponen
+4.1 Panduan Memulai
+
+Isi:
+
+Cara Login
+
+Navigasi Dashboard
+
+Fitur Dasar
+
+Tips & Trik
+
+Interaksi:
+
+Klik item → navigasi ke halaman detail
+
+Cursor pointer
+
+Hover underline atau highlight
+
+4.2 Video Tutorial
+
+Isi:
+
+Dashboard Overview
+
+Analisis Data
+
+Membuat Laporan
+
+Export Data
+
+Interaksi:
+
+Klik → buka modal video atau halaman video
+
+Bisa tambahkan icon play kecil di tiap item
+
+4.3 FAQ
+
+Isi:
+
+Masalah Login
+
+Reset Password
+
+Akses Data
+
+Laporan Error
+
+Interaksi:
+
+Accordion expand/collapse
+
+Animasi height smooth (200–300ms)
+
+4.4 Hubungi Support
+
+Isi:
+
+Email
+
+WhatsApp
+
+Jam Kerja
+
+Waktu Respon
+
+Interaksi:
+
+Email → mailto link
+
+WhatsApp → wa.me link
+
+Jam kerja non-clickable
+
+4.5 Dokumentasi
+
+Isi:
+
+API Reference
+
+Integrasi Sistem
+
+Format Data
+
+Best Practices
+
+Interaksi:
+
+Klik → navigasi dokumentasi
+
+4.6 Jenna – Virtual Assistant
+
+Komponen:
+
+Chat Container
+ ├── Header Title
+ ├── Chat Message Area
+ ├── Input Field
+ └── Send Button
+
+
+Spesifikasi:
+
+Tinggi tetap (±300–350px)
+
+Scrollable message container
+
+Input rounded
+
+Send button icon (arrow)
+
+Interaksi:
+
+Enter → kirim pesan
+
+Klik send → kirim pesan
+
+Auto-scroll ke pesan terakhir
+
+Disabled state saat loading
+
+4.7 Statistik Section
+
+3 Card horizontal:
+
+150+ Artikel Panduan
+
+50+ Video Tutorial
+
+24/7 Support Aktif
+
+Spesifikasi:
+
+Center aligned text
+
+Angka besar (font-size 32–40px)
+
+Subtext kecil opacity 70%
+
+5. Design System
+5.1 Light Mode
+Background
+
+Page background: #F5F7FA
+
+Card background: #FFFFFF
+
+Primary Color
+
+Blue: #3B82F6
+
+Hover: #2563EB
+
+Text
+
+Primary: #111827
+
+Secondary: #6B7280
+
+Border
+
+#E5E7EB
+
+Shadow
+0 4px 12px rgba(0,0,0,0.05)
+
+Icon Container
+
+Background: #EFF6FF
+
+Icon color: #2563EB
+
+5.2 Dark Mode
+Background
+
+Page background: #0F172A
+
+Card background: #1E293B
+
+Primary Color
+
+Blue: #3B82F6
+
+Hover: #60A5FA
+
+Text
+
+Primary: #F8FAFC
+
+Secondary: #94A3B8
+
+Border
+
+#334155
+
+Shadow
+0 4px 20px rgba(0,0,0,0.4)
+
+Icon Container
+
+Background: #1D4ED8
+
+Icon color: #FFFFFF
+
+6. Typography
+
+Font Family:
+
+Inter / Poppins / System UI
+
+Hierarchy:
+
+Element Size Weight
+Section Title 18–20px 600
+Card Title 16–18px 600
+List Item 14–16px 400
+Statistik Number 32–40px 700
+
+Line height:
+
+1.5 standard
+
+1.2 for large numbers
+
+7. Spacing System
+
+Gunakan sistem 8pt grid:
+
+8px
+
+16px
+
+24px
+
+32px
+
+48px
+
+Padding Card: 24px
+Gap Grid Desktop: 32px
+
+8. Responsivitas
+Desktop
+
+3 kolom utama
+
+Statistik 3 sejajar
+
+Tablet
+
+2 kolom
+
+Statistik 2 + 1
+
+Mobile
+
+1 kolom
+
+Statistik stacked vertical
+
+Chat full width
+
+9. State & Interactivity Requirements
+
+Harus tersedia:
+
+Hover state
+
+Active state
+
+Focus state (accessibility)
+
+Disabled state
+
+Loading state (chat)
+
+Keyboard support:
+
+Tab navigable
+
+Enter kirim pesan
+
+Esc tutup modal (jika ada)
+
+10. Accessibility
+
+Minimum contrast ratio 4.5:1
+
+Focus ring visible
+
+Button min-height 40px
+
+Click area minimal 44x44px
+
+11. Animasi
+
+Durasi standar: 200ms – 300ms
+Easing: ease-in-out
+
+Digunakan untuk:
+
+Hover card
+
+Accordion FAQ
+
+Chat message appear
+
+Button press
+
+12. Toggle Dark / Light Mode
+
+Harus tersedia:
+
+Theme switcher
+
+Persist ke localStorage
+
+Default mengikuti system preference
+
+13. Data Dinamis
+
+Data yang harus bisa dinamis:
+
+Jumlah artikel
+
+Jumlah video
+
+Status support 24/7
+
+Chat message list
+
+FAQ content
+
+Dokumentasi link
+
+14. Non-Functional Requirements
+
+Clean modular component
+
+Reusable Card component
+
+Maintainable theme config
+
+Dark & Light share same structure
+
+15. Kesimpulan
+
+Halaman ini menggunakan:
+
+Card-based layout
+
+Grid responsive
+
+Dual theme (Light & Dark)
+
+High clarity & readability
+
+Modern SaaS style
+
+Virtual assistant as engagement point
+
+Implementasi wajib mengikuti spesifikasi ini agar:
+
+Konsistensi visual terjaga
+
+User experience optimal
+
+Maintainability tinggi
+
+Skalabilitas mudah
\ No newline at end of file
diff --git a/src/components/help-page.tsx b/src/components/help-page.tsx
new file mode 100644
index 0000000..3440a4b
--- /dev/null
+++ b/src/components/help-page.tsx
@@ -0,0 +1,246 @@
+import { Container, Grid, Title, Text, SimpleGrid, Box, Accordion, Stack } from '@mantine/core';
+import { HelpCard } from '@/components/ui/help-card';
+import { IconBook, IconVideo, IconHelpCircle, IconMessage, IconFileText, IconHeadphones } from '@tabler/icons-react';
+import { useState } from 'react';
+
+const HelpPage = () => {
+ // Sample data for sections
+ const guideItems = [
+ { title: 'Cara Login', description: 'Langkah-langkah untuk login ke dashboard' },
+ { title: 'Navigasi Dashboard', description: 'Penjelasan tentang tata letak dan navigasi' },
+ { title: 'Fitur Dasar', description: 'Panduan penggunaan fitur-fitur utama' },
+ { title: 'Tips & Trik', description: 'Tips untuk meningkatkan produktivitas' },
+ ];
+
+ const videoItems = [
+ { title: 'Dashboard Overview', duration: '5:23' },
+ { title: 'Analisis Data', duration: '8:45' },
+ { title: 'Membuat Laporan', duration: '6:12' },
+ { title: 'Export Data', duration: '4:30' },
+ ];
+
+ const faqItems = [
+ { question: 'Bagaimana cara reset password?', answer: 'Anda dapat mereset password melalui halaman login dengan klik "Lupa Password"' },
+ { question: 'Apakah saya bisa mengakses data offline?', answer: 'Saat ini aplikasi hanya dapat diakses secara online' },
+ { question: 'Berapa lama waktu respon support?', answer: 'Tim support kami biasanya merespon dalam waktu kurang dari 24 jam' },
+ { question: 'Bagaimana cara menambahkan pengguna baru?', answer: 'Fitur penambahan pengguna dapat ditemukan di menu Pengaturan > Manajemen Pengguna' },
+ ];
+
+ const documentationItems = [
+ { title: 'API Reference', description: 'Dokumentasi lengkap untuk integrasi API' },
+ { title: 'Integrasi Sistem', description: 'Cara mengintegrasikan dengan sistem eksternal' },
+ { title: 'Format Data', description: 'Spesifikasi format data yang didukung' },
+ { title: 'Best Practices', description: 'Praktik terbaik dalam penggunaan platform' },
+ ];
+
+ const stats = [
+ { value: '150+', label: 'Artikel Panduan' },
+ { value: '50+', label: 'Video Tutorial' },
+ { value: '24/7', label: 'Support Aktif' },
+ ];
+
+ // State for chat functionality
+ const [messages, setMessages] = useState([
+ { id: 1, text: 'Halo! Saya Jenna, asisten virtual Anda. Bagaimana saya bisa membantu hari ini?', sender: 'jenna' }
+ ]);
+ const [inputValue, setInputValue] = useState('');
+ const [isLoading, setIsLoading] = useState(false);
+
+ const handleSendMessage = () => {
+ if (inputValue.trim() === '') return;
+
+ // Add user message
+ const newUserMessage = {
+ id: messages.length + 1,
+ text: inputValue,
+ sender: 'user'
+ };
+
+ setMessages(prev => [...prev, newUserMessage]);
+ setInputValue('');
+ setIsLoading(true);
+
+ // Simulate Jenna's response after delay
+ setTimeout(() => {
+ const jennaResponse = {
+ id: messages.length + 2,
+ text: 'Terima kasih atas pertanyaan Anda. Saat ini saya adalah versi awal dari asisten virtual. Tim kami sedang mengembangkan kemampuan saya lebih lanjut.',
+ sender: 'jenna'
+ };
+ setMessages(prev => [...prev, jennaResponse]);
+ setIsLoading(false);
+ }, 1000);
+ };
+
+ const handleKeyPress = (e: React.KeyboardEvent) => {
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault();
+ handleSendMessage();
+ }
+ };
+
+ return (
+
+ Pusat Bantuan
+
+ Temukan jawaban untuk pertanyaan Anda atau hubungi tim support kami
+
+
+ {/* Statistics Section */}
+
+ {stats.map((stat, index) => (
+
+ {stat.value}
+ {stat.label}
+
+ ))}
+
+
+
+
+
+ {/* Panduan Memulai */}
+
+ } title="Panduan Memulai" h="100%">
+
+ {guideItems.map((item, index) => (
+ alert(`Navigasi ke ${item.title}`)}>
+ {item.title}
+ {item.description}
+
+ ))}
+
+
+
+
+ {/* Video Tutorial */}
+
+ } title="Video Tutorial" h="100%">
+
+ {videoItems.map((item, index) => (
+ alert(`Buka video: ${item.title}`)}>
+ {item.title}
+ {item.duration}
+
+ ))}
+
+
+
+
+ {/* FAQ */}
+
+ } title="FAQ" h="100%">
+
+ {faqItems.map((item, index) => (
+
+ {item.question}
+
+ {item.answer}
+
+
+ ))}
+
+
+
+
+
+
+
+
+ {/* Hubungi Support */}
+
+ } title="Hubungi Support" h="100%">
+
+ Email
+ support@example.com
+
+ WhatsApp
+ +62 123 456 7890
+
+ Jam Kerja
+ Senin - Jumat, 09:00 - 17:00 WIB
+
+ Waktu Respon
+ Rata-rata 2-4 jam kerja
+
+
+
+
+ {/* Dokumentasi */}
+
+ } title="Dokumentasi" h="100%">
+
+ {documentationItems.map((item, index) => (
+ alert(`Navigasi ke dokumentasi: ${item.title}`)}>
+ {item.title}
+ {item.description}
+
+ ))}
+
+
+
+
+ {/* Jenna - Virtual Assistant */}
+
+ } title="Jenna - Virtual Assistant" h="100%">
+
+
+ {messages.map((msg) => (
+
+ {msg.text}
+
+ ))}
+
+
+
+ setInputValue(e.target.value)}
+ onKeyPress={handleKeyPress}
+ placeholder="Ketik pesan Anda..."
+ style={{
+ flex: 1,
+ padding: '8px 12px',
+ borderRadius: '20px',
+ border: '1px solid #ccc',
+ }}
+ disabled={isLoading}
+ />
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default HelpPage;
\ No newline at end of file
diff --git a/src/components/ui/help-card.tsx b/src/components/ui/help-card.tsx
new file mode 100644
index 0000000..844c4b3
--- /dev/null
+++ b/src/components/ui/help-card.tsx
@@ -0,0 +1,90 @@
+import { Card, useMantineTheme, useComputedColorScheme } from '@mantine/core';
+import type { CardProps } from '@mantine/core';
+import type { ReactNode } from 'react';
+
+interface HelpCardProps extends CardProps {
+ children: ReactNode;
+ icon?: ReactNode;
+ title?: string;
+ minHeight?: string | number; // Allow specifying a minimum height
+}
+
+export const HelpCard = ({
+ children,
+ icon,
+ title,
+ minHeight = 'auto', // Default to auto, but allow override
+ ...props
+}: HelpCardProps) => {
+ const theme = useMantineTheme();
+ const colorScheme = useComputedColorScheme('light');
+ const isDark = colorScheme === 'dark';
+
+ return (
+
+ {(icon || title) && (
+
+ {icon && (
+
+ {icon}
+
+ )}
+
+ {title && (
+
+ {title}
+
+ )}
+
+ )}
+
+
+ {children}
+
+
+ );
+};
diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts
index 8b0a1b8..0bc961b 100644
--- a/src/routeTree.gen.ts
+++ b/src/routeTree.gen.ts
@@ -28,6 +28,7 @@ import { Route as DashboardKeamananRouteImport } from './routes/dashboard/keaman
import { Route as DashboardJennaAnalyticRouteImport } from './routes/dashboard/jenna-analytic'
import { Route as DashboardDemografiPekerjaanRouteImport } from './routes/dashboard/demografi-pekerjaan'
import { Route as DashboardBumdesRouteImport } from './routes/dashboard/bumdes'
+import { Route as DashboardBantuanRouteImport } from './routes/dashboard/bantuan'
import { Route as AdminUsersRouteImport } from './routes/admin/users'
import { Route as AdminSettingsRouteImport } from './routes/admin/settings'
import { Route as AdminApikeyRouteImport } from './routes/admin/apikey'
@@ -130,6 +131,11 @@ const DashboardBumdesRoute = DashboardBumdesRouteImport.update({
path: '/bumdes',
getParentRoute: () => DashboardRouteRoute,
} as any)
+const DashboardBantuanRoute = DashboardBantuanRouteImport.update({
+ id: '/bantuan',
+ path: '/bantuan',
+ getParentRoute: () => DashboardRouteRoute,
+} as any)
const AdminUsersRoute = AdminUsersRouteImport.update({
id: '/users',
path: '/users',
@@ -155,6 +161,7 @@ export interface FileRoutesByFullPath {
'/admin/apikey': typeof AdminApikeyRoute
'/admin/settings': typeof AdminSettingsRoute
'/admin/users': typeof AdminUsersRoute
+ '/dashboard/bantuan': typeof DashboardBantuanRoute
'/dashboard/bumdes': typeof DashboardBumdesRoute
'/dashboard/demografi-pekerjaan': typeof DashboardDemografiPekerjaanRoute
'/dashboard/jenna-analytic': typeof DashboardJennaAnalyticRoute
@@ -177,6 +184,7 @@ export interface FileRoutesByTo {
'/admin/apikey': typeof AdminApikeyRoute
'/admin/settings': typeof AdminSettingsRoute
'/admin/users': typeof AdminUsersRoute
+ '/dashboard/bantuan': typeof DashboardBantuanRoute
'/dashboard/bumdes': typeof DashboardBumdesRoute
'/dashboard/demografi-pekerjaan': typeof DashboardDemografiPekerjaanRoute
'/dashboard/jenna-analytic': typeof DashboardJennaAnalyticRoute
@@ -202,6 +210,7 @@ export interface FileRoutesById {
'/admin/apikey': typeof AdminApikeyRoute
'/admin/settings': typeof AdminSettingsRoute
'/admin/users': typeof AdminUsersRoute
+ '/dashboard/bantuan': typeof DashboardBantuanRoute
'/dashboard/bumdes': typeof DashboardBumdesRoute
'/dashboard/demografi-pekerjaan': typeof DashboardDemografiPekerjaanRoute
'/dashboard/jenna-analytic': typeof DashboardJennaAnalyticRoute
@@ -228,6 +237,7 @@ export interface FileRouteTypes {
| '/admin/apikey'
| '/admin/settings'
| '/admin/users'
+ | '/dashboard/bantuan'
| '/dashboard/bumdes'
| '/dashboard/demografi-pekerjaan'
| '/dashboard/jenna-analytic'
@@ -250,6 +260,7 @@ export interface FileRouteTypes {
| '/admin/apikey'
| '/admin/settings'
| '/admin/users'
+ | '/dashboard/bantuan'
| '/dashboard/bumdes'
| '/dashboard/demografi-pekerjaan'
| '/dashboard/jenna-analytic'
@@ -274,6 +285,7 @@ export interface FileRouteTypes {
| '/admin/apikey'
| '/admin/settings'
| '/admin/users'
+ | '/dashboard/bantuan'
| '/dashboard/bumdes'
| '/dashboard/demografi-pekerjaan'
| '/dashboard/jenna-analytic'
@@ -437,6 +449,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof DashboardBumdesRouteImport
parentRoute: typeof DashboardRouteRoute
}
+ '/dashboard/bantuan': {
+ id: '/dashboard/bantuan'
+ path: '/bantuan'
+ fullPath: '/dashboard/bantuan'
+ preLoaderRoute: typeof DashboardBantuanRouteImport
+ parentRoute: typeof DashboardRouteRoute
+ }
'/admin/users': {
id: '/admin/users'
path: '/users'
@@ -480,6 +499,7 @@ const AdminRouteRouteWithChildren = AdminRouteRoute._addFileChildren(
)
interface DashboardRouteRouteChildren {
+ DashboardBantuanRoute: typeof DashboardBantuanRoute
DashboardBumdesRoute: typeof DashboardBumdesRoute
DashboardDemografiPekerjaanRoute: typeof DashboardDemografiPekerjaanRoute
DashboardJennaAnalyticRoute: typeof DashboardJennaAnalyticRoute
@@ -492,6 +512,7 @@ interface DashboardRouteRouteChildren {
}
const DashboardRouteRouteChildren: DashboardRouteRouteChildren = {
+ DashboardBantuanRoute: DashboardBantuanRoute,
DashboardBumdesRoute: DashboardBumdesRoute,
DashboardDemografiPekerjaanRoute: DashboardDemografiPekerjaanRoute,
DashboardJennaAnalyticRoute: DashboardJennaAnalyticRoute,
diff --git a/src/routes/dashboard/bantuan.ts b/src/routes/dashboard/bantuan.ts
new file mode 100644
index 0000000..510fc86
--- /dev/null
+++ b/src/routes/dashboard/bantuan.ts
@@ -0,0 +1,7 @@
+import { createFileRoute } from '@tanstack/react-router'
+import HelpPage from '@/components/help-page'
+
+export const Route = createFileRoute('/dashboard/bantuan')({
+ component: HelpPage,
+})
+