@rozaqi02/reusable-dashboard 1.1.4 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +452 -493
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +452 -493
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js","../src/config/cidikaWidgetConfig.js","../src/config/dummyUmkmWidgetConfig.js","../src/config/tokoSepatuWidgetConfig.js","../src/config/createDashboardConfig.js","../src/utils/formatters.js","../src/utils/adapterHelpers.js","../src/data-adapter/cidikaDashboardAdapter.js","../src/data-adapter/dummyUmkmDashboardAdapter.js","../src/data-adapter/tokoSepatuDashboardAdapter.js","../src/data-source/cidikaSupabaseSource.js","../src/data-source/tokoSepatuSupabaseSource.js","../src/hooks/useReusableDashboard.js","../src/utils/dateRange.js","../src/hooks/useRealtimeUpdate.js","../src/presentation/atoms/Button.jsx","../src/presentation/atoms/Input.jsx","../src/presentation/atoms/Icon.jsx","../src/presentation/atoms/Typography.jsx","../src/presentation/atoms/Badge.jsx","../src/presentation/atoms/SkeletonLoader.jsx","../src/presentation/molecules/StatCard.jsx","../src/presentation/molecules/SearchBar.jsx","../src/presentation/molecules/DateRangeFilter.jsx","../src/presentation/molecules/ChartHeader.jsx","../src/presentation/organisms/DataTable.jsx","../src/presentation/organisms/ChartCard.jsx","../src/presentation/organisms/FilterPanel.jsx","../src/presentation/organisms/SidebarNavigation.jsx","../src/presentation/organisms/TopbarHeader.jsx","../src/presentation/templates/DashboardLayout.jsx","../src/presentation/ReusableDashboardView.jsx","../src/presentation/SetupWizard.jsx","../src/utils/labels.js"],"sourcesContent":["// ──────────────────────────────────────────────────────────────────────────────\n// Config\n// ──────────────────────────────────────────────────────────────────────────────\nexport { cidikaWidgetConfig } from \"./config/cidikaWidgetConfig.js\";\nexport { dummyUmkmWidgetConfig } from \"./config/dummyUmkmWidgetConfig.js\";\nexport { tokoSepatuWidgetConfig } from \"./config/tokoSepatuWidgetConfig.js\";\n\n// Factory — mengemas semua konfigurasi menjadi 1 objek tunggal (revisi dosen)\nexport {\n createDashboardConfig,\n validateDashboardConfig,\n} from \"./config/createDashboardConfig.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Data Adapter\n// ──────────────────────────────────────────────────────────────────────────────\nexport {\n adaptCidikaDashboardData,\n createEmptyDashboardData,\n} from \"./data-adapter/cidikaDashboardAdapter.js\";\nexport {\n adaptDummyUmkmData,\n createEmptyDummyUmkmData,\n} from \"./data-adapter/dummyUmkmDashboardAdapter.js\";\nexport {\n adaptTokoSepatuData,\n createEmptyTokoSepatuData,\n} from \"./data-adapter/tokoSepatuDashboardAdapter.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Data Source\n// ──────────────────────────────────────────────────────────────────────────────\nexport { createCidikaSupabaseSource } from \"./data-source/cidikaSupabaseSource.js\";\nexport { createTokoSepatuSupabaseSource } from \"./data-source/tokoSepatuSupabaseSource.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Hook\n// ──────────────────────────────────────────────────────────────────────────────\nexport { useReusableDashboard } from \"./hooks/useReusableDashboard.js\";\nexport { useRealtimeUpdate } from \"./hooks/useRealtimeUpdate.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Atoms\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as Button } from \"./presentation/atoms/Button.jsx\";\nexport { default as Input } from \"./presentation/atoms/Input.jsx\";\nexport { default as Icon, resolveIcon } from \"./presentation/atoms/Icon.jsx\";\nexport { default as Typography } from \"./presentation/atoms/Typography.jsx\";\nexport { default as Badge } from \"./presentation/atoms/Badge.jsx\";\nexport { default as SkeletonLoader } from \"./presentation/atoms/SkeletonLoader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Molecules\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as StatCard } from \"./presentation/molecules/StatCard.jsx\";\nexport { default as SearchBar } from \"./presentation/molecules/SearchBar.jsx\";\nexport { default as DateRangeFilter } from \"./presentation/molecules/DateRangeFilter.jsx\";\nexport { default as ChartHeader } from \"./presentation/molecules/ChartHeader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Organisms\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as DataTable } from \"./presentation/organisms/DataTable.jsx\";\nexport { default as ChartCard } from \"./presentation/organisms/ChartCard.jsx\";\nexport { default as FilterPanel } from \"./presentation/organisms/FilterPanel.jsx\";\nexport { default as SidebarNavigation } from \"./presentation/organisms/SidebarNavigation.jsx\";\nexport { default as TopbarHeader } from \"./presentation/organisms/TopbarHeader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Templates\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as DashboardLayout } from \"./presentation/templates/DashboardLayout.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Page-Level View\n// ──────────────────────────────────────────────────────────────────────────────\nexport { ReusableDashboardView } from \"./presentation/ReusableDashboardView.jsx\";\n\n// Setup Wizard — pop-up panduan konfigurasi (revisi dosen Opsi B)\nexport { SetupWizard } from \"./presentation/SetupWizard.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Utils\n// ──────────────────────────────────────────────────────────────────────────────\nexport { createDashboardLabels } from \"./utils/labels.js\";\nexport {\n createDefaultFilters,\n formatYYYYMMDD,\n resolveDateRange,\n} from \"./utils/dateRange.js\";\nexport { formatDate, formatIDR, shortId } from \"./utils/formatters.js\";\nexport {\n toNumber,\n buildDayBuckets,\n sortMapEntries,\n} from \"./utils/adapterHelpers.js\";\n\n","export const cidikaWidgetConfig = {\n id: \"cidika.travel.dashboard\",\n defaultFilters: {\n statusScope: \"confirmed\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n sortPkgBy: \"bookings\",\n sortPkgDir: \"desc\",\n },\n widgets: {\n stats: [\n {\n id: \"bookingsConfirm\",\n label: \"confirmedBookings\",\n icon: \"TrendingUp\",\n valueKey: \"bookingsConfirm\",\n format: \"number\",\n accentColor: \"blue\",\n },\n {\n id: \"revenueConfirm\",\n label: \"confirmedRevenue\",\n icon: \"DollarSign\",\n valueKey: \"revenueConfirm\",\n format: \"currency\",\n accentColor: \"green\",\n },\n {\n id: \"avgRevenue\",\n label: \"avgRevenue\",\n icon: \"Users\",\n valueKey: \"avgRevenue\",\n format: \"currency\",\n accentColor: \"violet\",\n },\n {\n id: \"conversionRate\",\n label: \"conversionRate\",\n icon: \"PieChart\",\n valueKey: \"conversionRate\",\n format: \"percent\",\n accentColor: \"orange\",\n },\n ],\n charts: [\n {\n id: \"dailyTrends\",\n type: \"dailyArea\",\n label: \"dailyTrends\",\n icon: \"BarChart3\",\n },\n {\n id: \"statusDistribution\",\n type: \"statusPie\",\n label: \"statusDistribution\",\n icon: \"PieChart\",\n },\n {\n id: \"audienceDistribution\",\n type: \"audiencePie\",\n label: \"audienceDistribution\",\n icon: \"Users\",\n },\n {\n id: \"topPackages\",\n type: \"topPackagesBar\",\n label: \"topPackages\",\n icon: \"TrendingUp\",\n },\n ],\n table: {\n id: \"recentBookings\",\n label: \"recentBookings\",\n icon: \"Calendar\",\n emptyLabel: \"noRecentBookings\",\n columns: [\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\n { id: \"package\", label: \"package\", accessor: \"packageName\" },\n { id: \"audience\", label: \"audience\", accessor: \"audienceLabel\" },\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\n {\n id: \"status\",\n label: \"status\",\n accessor: \"statusLabel\",\n type: \"statusBadge\",\n statusAccessor: \"status\",\n },\n ],\n },\n },\n};\n","export const dummyUmkmWidgetConfig = {\n id: \"dummy.umkm.dashboard\",\n defaultFilters: {\n statusScope: \"all\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n sortPkgBy: \"revenue\",\n sortPkgDir: \"desc\",\n },\n widgets: {\n stats: [\n {\n id: \"orders\",\n label: \"confirmedBookings\",\n icon: \"TrendingUp\",\n valueKey: \"bookingsConfirm\",\n format: \"number\",\n },\n {\n id: \"revenue\",\n label: \"confirmedRevenue\",\n icon: \"DollarSign\",\n valueKey: \"revenueConfirm\",\n format: \"currency\",\n },\n ],\n charts: [\n {\n id: \"revenueTrend\",\n type: \"dailyArea\",\n label: \"dailyTrends\",\n icon: \"BarChart3\",\n },\n {\n id: \"recentOrderStatus\",\n type: \"statusPie\",\n label: \"statusDistribution\",\n icon: \"PieChart\",\n },\n ],\n table: {\n id: \"recentOrders\",\n label: \"recentBookings\",\n icon: \"Calendar\",\n emptyLabel: \"noRecentBookings\",\n columns: [\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\n ],\n },\n },\n};\n","/**\r\n * Widget Configuration — Toko Sepatu Online (Studi Kasus Dummy UMKM Non-Travel)\r\n *\r\n * Konfigurasi ini membuktikan bahwa modul reusable dashboard dapat digunakan\r\n * pada domain bisnis yang berbeda (retail sepatu) hanya dengan mendefinisikan\r\n * konfigurasi baru tanpa mengubah komponen inti.\r\n *\r\n * Perbedaan dengan cidikaWidgetConfig:\r\n * - 4 stat cards (orders, revenue, avg order, products)\r\n * - 2 charts (daily trends, status distribution)\r\n * - 1 tabel (recent orders) dengan 5 kolom\r\n * - Filter lebih sederhana (tanpa audience, tanpa pending overlay)\r\n */\r\nexport const tokoSepatuWidgetConfig = {\r\n id: \"toko.sepatu.dashboard\",\r\n defaultFilters: {\r\n statusScope: \"all\",\r\n includePendingOverlay: false,\r\n audience: \"\",\r\n daysPreset: 30,\r\n sortPkgBy: \"revenue\",\r\n sortPkgDir: \"desc\",\r\n },\r\n widgets: {\r\n stats: [\r\n {\r\n id: \"totalOrders\",\r\n label: \"confirmedBookings\",\r\n icon: \"TrendingUp\",\r\n valueKey: \"bookingsConfirm\",\r\n format: \"number\",\r\n accentColor: \"sky\",\r\n },\r\n {\r\n id: \"totalRevenue\",\r\n label: \"confirmedRevenue\",\r\n icon: \"DollarSign\",\r\n valueKey: \"revenueConfirm\",\r\n format: \"currency\",\r\n accentColor: \"green\",\r\n },\r\n {\r\n id: \"avgOrderValue\",\r\n label: \"avgRevenue\",\r\n icon: \"BarChart3\",\r\n valueKey: \"avgRevenue\",\r\n format: \"currency\",\r\n accentColor: \"violet\",\r\n },\r\n {\r\n id: \"totalProducts\",\r\n label: \"totalProducts\",\r\n icon: \"PieChart\",\r\n valueKey: \"packages\",\r\n format: \"number\",\r\n accentColor: \"orange\",\r\n },\r\n ],\r\n charts: [\r\n {\r\n id: \"dailyOrderTrends\",\r\n type: \"dailyArea\",\r\n label: \"dailyTrends\",\r\n icon: \"BarChart3\",\r\n },\r\n {\r\n id: \"orderStatusDistribution\",\r\n type: \"statusPie\",\r\n label: \"statusDistribution\",\r\n icon: \"PieChart\",\r\n },\r\n {\r\n id: \"topProducts\",\r\n type: \"topPackagesBar\",\r\n label: \"topPackages\",\r\n icon: \"TrendingUp\",\r\n },\r\n ],\r\n table: {\r\n id: \"recentOrders\",\r\n label: \"recentBookings\",\r\n icon: \"Calendar\",\r\n emptyLabel: \"noRecentBookings\",\r\n columns: [\r\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\r\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\r\n { id: \"product\", label: \"package\", accessor: \"packageName\" },\r\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\r\n {\r\n id: \"status\",\r\n label: \"status\",\r\n accessor: \"statusLabel\",\r\n type: \"statusBadge\",\r\n statusAccessor: \"status\",\r\n },\r\n ],\r\n },\r\n },\r\n};\r\n","/**\r\n * createDashboardConfig — Factory function untuk mengemas semua konfigurasi\r\n * dashboard dalam satu objek tunggal.\r\n *\r\n * Sebelum adanya factory ini, developer harus menyiapkan 3 file terpisah\r\n * (widgetConfig, adapter, dataSource) dan mengimpornya satu per satu ke hook.\r\n * Dengan factory ini cukup 1 objek yang diserahkan ke useReusableDashboard.\r\n *\r\n * @param {object} options\r\n * @param {object} options.widgetConfig - Konfigurasi widget deklaratif.\r\n * @param {object} options.dataSource - Objek data source (fetchDashboardSnapshot, subscribeLiveUpdate).\r\n * @param {Function} options.adapter - Fungsi adapter pure function.\r\n * @param {Function} options.createEmptyState - Fungsi pembuat state kosong.\r\n * @param {object} [options.labels] - Objek label UI (opsional, bisa di-override di komponen).\r\n * @param {string} [options.languageCode=\"id\"] - Kode bahasa (id / en).\r\n * @param {string} [options.dateLocale=\"id-ID\"] - Locale format tanggal.\r\n *\r\n * @returns {object} Objek config terpadu yang siap dipakai useReusableDashboard.\r\n *\r\n * @example\r\n * // Sebelum (3 import terpisah):\r\n * const source = createCidikaSupabaseSource(supabase);\r\n * useReusableDashboard({ config: cidikaWidgetConfig, dataSource: source,\r\n * adapter: adaptCidikaDashboardData, createEmptyState: createEmptyDashboardData, ... })\r\n *\r\n * // Sesudah (1 file config):\r\n * const dashboardConfig = createDashboardConfig({\r\n * widgetConfig: cidikaWidgetConfig,\r\n * dataSource: createCidikaSupabaseSource(supabase),\r\n * adapter: adaptCidikaDashboardData,\r\n * createEmptyState: createEmptyDashboardData,\r\n * });\r\n * useReusableDashboard(dashboardConfig)\r\n */\r\nexport function createDashboardConfig({\r\n widgetConfig,\r\n dataSource,\r\n adapter,\r\n createEmptyState,\r\n labels,\r\n languageCode = \"id\",\r\n dateLocale = \"id-ID\",\r\n}) {\r\n // Validasi minimal — membantu developer yang lupa mengisi bagian penting\r\n const missing = [];\r\n if (!widgetConfig) missing.push(\"widgetConfig\");\r\n if (!dataSource) missing.push(\"dataSource\");\r\n if (!adapter) missing.push(\"adapter\");\r\n if (!createEmptyState) missing.push(\"createEmptyState\");\r\n\r\n return {\r\n // Properti yang langsung dibaca useReusableDashboard\r\n config: widgetConfig,\r\n dataSource,\r\n adapter,\r\n createEmptyState,\r\n languageCode,\r\n dateLocale,\r\n labels,\r\n\r\n // Metadata untuk setup wizard & validasi\r\n _meta: {\r\n isValid: missing.length === 0,\r\n missing,\r\n hasDataSource: Boolean(dataSource?.fetchDashboardSnapshot),\r\n hasRealtimeSupport: Boolean(dataSource?.subscribeLiveUpdate),\r\n hasLabels: Boolean(labels),\r\n widgetCount: {\r\n stats: widgetConfig?.widgets?.stats?.length ?? 0,\r\n charts: widgetConfig?.widgets?.charts?.length ?? 0,\r\n tableColumns: widgetConfig?.widgets?.table?.columns?.length ?? 0,\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Memvalidasi apakah sebuah dashboardConfig sudah lengkap dan siap dipakai.\r\n * Digunakan oleh SetupWizard untuk menentukan apakah perlu menampilkan panduan.\r\n *\r\n * @param {object} dashboardConfig - Hasil dari createDashboardConfig.\r\n * @returns {{ valid: boolean, issues: string[] }}\r\n */\r\nexport function validateDashboardConfig(dashboardConfig) {\r\n const issues = [];\r\n\r\n if (!dashboardConfig) {\r\n return { valid: false, issues: [\"dashboardConfig tidak ditemukan. Pastikan sudah memanggil createDashboardConfig().\"] };\r\n }\r\n\r\n const meta = dashboardConfig?._meta;\r\n\r\n if (!meta) {\r\n issues.push(\"Config tidak dibuat melalui createDashboardConfig(). Gunakan factory function ini untuk validasi otomatis.\");\r\n } else {\r\n if (meta.missing.length > 0) {\r\n meta.missing.forEach(m => issues.push(`Properti wajib belum diisi: \"${m}\"`));\r\n }\r\n if (!meta.hasDataSource) {\r\n issues.push(\"dataSource.fetchDashboardSnapshot() tidak ditemukan. Pastikan sudah membuat data source yang benar.\");\r\n }\r\n }\r\n\r\n if (!dashboardConfig.config?.widgets?.stats?.length) {\r\n issues.push(\"widgetConfig.widgets.stats kosong. Tambahkan minimal 1 stat card.\");\r\n }\r\n if (!dashboardConfig.config?.widgets?.charts?.length) {\r\n issues.push(\"widgetConfig.widgets.charts kosong. Tambahkan minimal 1 chart.\");\r\n }\r\n if (!dashboardConfig.config?.widgets?.table?.columns?.length) {\r\n issues.push(\"widgetConfig.widgets.table.columns kosong. Tambahkan minimal 1 kolom tabel.\");\r\n }\r\n if (!dashboardConfig.labels) {\r\n issues.push(\"labels belum diisi. Sediakan objek labels agar teks UI tampil dengan benar.\");\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n","export function formatIDR(value) {\n try {\n return (Number(value) || 0).toLocaleString(\"id-ID\");\n } catch (_error) {\n return String(value ?? 0);\n }\n}\n\nexport function shortId(value, length = 8) {\n if (!value) return \"-\";\n return String(value).slice(0, length);\n}\n\nexport function formatDate(value, locale) {\n if (!value) return \"-\";\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return \"-\";\n return date.toLocaleDateString(locale);\n}\n","/**\n * adapterHelpers — Fungsi utilitas bersama yang digunakan oleh semua data-adapter.\n * Diekstrak dari adapter individu untuk menghindari duplikasi kode (prinsip DRY).\n */\n\n/**\n * Mengkonversi nilai apapun ke angka yang valid.\n * Mengembalikan 0 jika nilai tidak valid atau bukan angka finite.\n *\n * @param {*} value - Nilai yang akan dikonversi.\n * @returns {number} Angka finite, atau 0 jika tidak valid.\n */\nexport function toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\n/**\n * Membangun array bucket harian untuk chart tren.\n * Setiap bucket berisi dateKey, label terformat, dan counter awal (0).\n *\n * @param {number} daysWindow - Jumlah hari dalam rentang.\n * @param {string} fromISO - Tanggal awal dalam format ISO.\n * @param {string} dateLocale - Locale untuk format tanggal (misal: \"id-ID\").\n * @returns {Array<{dateKey: string, label: string, count: number, revenue: number, pendingCount: number}>}\n */\nexport function buildDayBuckets(daysWindow, fromISO, dateLocale) {\n const start = new Date(fromISO);\n return Array.from({ length: daysWindow }).map((_, index) => {\n const day = new Date(start);\n day.setDate(start.getDate() + index);\n return {\n dateKey: day.toISOString().slice(0, 10),\n label: day.toLocaleDateString(dateLocale, {\n day: \"2-digit\",\n month: \"short\",\n }),\n count: 0,\n revenue: 0,\n pendingCount: 0,\n };\n });\n}\n\n/**\n * Mengurutkan entri Map berdasarkan nilai numerik.\n *\n * @param {Map} map - Map yang akan diurutkan.\n * @param {\"asc\"|\"desc\"} direction - Arah pengurutan.\n * @returns {Array<[string, number]>} Array entri terurut.\n */\nexport function sortMapEntries(map, direction) {\n return Array.from(map.entries()).sort((a, b) =>\n direction === \"asc\" ? a[1] - b[1] : b[1] - a[1]\n );\n}\n","import { shortId } from \"../utils/formatters.js\";\nimport { toNumber, buildDayBuckets, sortMapEntries } from \"../utils/adapterHelpers.js\";\n\nfunction createPackageTitleResolver(packageLocales, languageCode) {\n const byPackage = new Map();\n\n packageLocales.forEach((row) => {\n if (!row.package_id) return;\n const current = byPackage.get(row.package_id) || {};\n byPackage.set(row.package_id, {\n ...current,\n [row.lang]: row.title,\n });\n });\n\n return (packageId) => {\n if (!packageId) return \"-\";\n const labels = byPackage.get(packageId);\n if (!labels) return shortId(packageId, 6);\n return (\n labels[languageCode] ||\n labels.en ||\n labels.id ||\n Object.values(labels).find(Boolean) ||\n shortId(packageId, 6)\n );\n };\n}\n\nexport function createEmptyDashboardData() {\n return {\n stats: {\n bookingsConfirm: 0,\n bookingsPending: 0,\n revenueConfirm: 0,\n packages: 0,\n sections: 0,\n avgRevenue: 0,\n conversionRate: 0,\n },\n charts: {\n dailyTrends: [],\n statusDistribution: [],\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings: [],\n },\n };\n}\n\nexport function adaptCidikaDashboardData({\n raw,\n filters,\n range,\n dateLocale,\n languageCode,\n labels,\n}) {\n if (!raw) return createEmptyDashboardData();\n\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\n const dayLookup = new Map(\n dailyBuckets.map((bucket) => [bucket.dateKey, bucket])\n );\n\n const statusMap = new Map();\n const audienceMap = new Map();\n const packageCountMap = new Map();\n const packageRevenueMap = new Map();\n const getPackageTitle = createPackageTitleResolver(\n raw.packageLocales || [],\n languageCode\n );\n\n let bookingsConfirm = 0;\n let bookingsPending = 0;\n let revenueConfirm = 0;\n\n (raw.bookings || []).forEach((row) => {\n const dayKey = String(row.created_at || \"\").slice(0, 10);\n const status = String(row.status || \"pending\").toLowerCase();\n const total = toNumber(row.total_idr);\n const audience = row.audience || \"unknown\";\n\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\n audienceMap.set(audience, (audienceMap.get(audience) || 0) + 1);\n\n const bucket = dayLookup.get(dayKey);\n if (bucket) {\n if (status === \"confirmed\") {\n bucket.count += 1;\n bucket.revenue += total;\n }\n if (status === \"pending\") {\n bucket.pendingCount += 1;\n }\n }\n\n if (status === \"confirmed\") {\n bookingsConfirm += 1;\n revenueConfirm += total;\n packageCountMap.set(\n row.package_id,\n (packageCountMap.get(row.package_id) || 0) + 1\n );\n packageRevenueMap.set(\n row.package_id,\n (packageRevenueMap.get(row.package_id) || 0) + total\n );\n } else if (status === \"pending\") {\n bookingsPending += 1;\n }\n });\n\n const statusDistribution = sortMapEntries(statusMap, \"desc\").map(\n ([status, count]) => ({\n status,\n label: labels.formatStatusLabel(status),\n count,\n })\n );\n\n const audienceDistribution = sortMapEntries(audienceMap, \"desc\").map(\n ([audience, count]) => ({\n audience,\n label: labels.formatAudienceLabel(audience),\n count,\n })\n );\n\n const metricMap =\n filters.sortPkgBy === \"revenue\" ? packageRevenueMap : packageCountMap;\n\n const topPackages = sortMapEntries(metricMap, filters.sortPkgDir)\n .slice(0, 5)\n .map(([packageId, value]) => ({\n packageId,\n name: getPackageTitle(packageId),\n value: toNumber(value),\n }));\n\n const recentBookings = (raw.recent || []).map((row) => {\n const status = String(row.status || \"pending\").toLowerCase();\n return {\n id: row.id,\n createdAt: row.created_at,\n customerName: row.customer_name || \"-\",\n packageName: getPackageTitle(row.package_id),\n audienceLabel: labels.formatAudienceLabel(row.audience),\n totalIDR: toNumber(row.total_idr),\n status,\n statusLabel: labels.formatStatusLabel(status),\n };\n });\n\n const avgRevenue =\n bookingsConfirm > 0 ? Math.round(revenueConfirm / bookingsConfirm) : 0;\n const conversionRate =\n bookingsConfirm + bookingsPending > 0\n ? Math.round((bookingsConfirm / (bookingsConfirm + bookingsPending)) * 100)\n : 0;\n\n return {\n stats: {\n bookingsConfirm,\n bookingsPending,\n revenueConfirm,\n packages: toNumber(raw.staticCounts?.packages),\n sections: toNumber(raw.staticCounts?.sections),\n avgRevenue,\n conversionRate,\n },\n charts: {\n dailyTrends: dailyBuckets,\n statusDistribution,\n audienceDistribution,\n topPackages,\n },\n table: {\n recentBookings,\n },\n };\n}\n","/**\n * dummyUmkmDashboardAdapter — Data-adapter layer untuk studi kasus\n * aplikasi dummy UMKM non-travel (penjualan produk).\n *\n * Adapter ini membuktikan bahwa modul reusable dashboard dapat digunakan\n * pada domain bisnis yang berbeda dari Cidika Travel hanya dengan\n * mengganti adapter, tanpa mengubah komponen inti.\n *\n * Struktur data Supabase dummy UMKM yang diharapkan:\n * - Tabel `orders` : id, created_at, total_amount, status, customer_name, product_id\n * - Tabel `products` : id, name\n * - Tabel `customers`: id, name\n */\n\nimport { toNumber, buildDayBuckets } from \"../utils/adapterHelpers.js\";\n\n/**\n * Membuat state kosong yang sesuai dengan kontrak data dummy UMKM.\n * Dipanggil oleh useReusableDashboard sebagai initial state dan saat error.\n *\n * @returns {object} Empty dashboard data object.\n */\nexport function createEmptyDummyUmkmData() {\n return {\n stats: {\n bookingsConfirm: 0,\n revenueConfirm: 0,\n totalProducts: 0,\n totalCustomers: 0,\n },\n charts: {\n dailyTrends: [],\n statusDistribution: [],\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings: [],\n },\n };\n}\n\n/**\n * Memetakan data mentah dari Supabase dummy UMKM ke format standar widget.\n *\n * Format `raw` yang diharapkan dari dataSource:\n * ```\n * {\n * bookings: Array<{ id, created_at, total_amount, status, customer_name, product_id }>,\n * recent: Array<{ id, created_at, customer_name, total_amount, status, product_id }>,\n * staticCounts: { packages: number, sections: number } // opsional\n * }\n * ```\n *\n * @param {object} params\n * @param {object} params.raw - Data mentah dari dataSource.\n * @param {object} params.filters - State filter aktif.\n * @param {object} params.range - Rentang tanggal { fromISO, toISO, daysWindow }.\n * @param {string} params.dateLocale - Locale untuk format tanggal (misal: \"id-ID\").\n * @param {object} [params.labels] - Label i18n (opsional, untuk format status).\n * @returns {object} Objek data standar { stats, charts, table }.\n */\nexport function adaptDummyUmkmData({ raw, filters, range, dateLocale, labels }) {\n if (!raw) return createEmptyDummyUmkmData();\n\n const orders = raw.bookings || [];\n const recent = raw.recent || [];\n\n // Bangun bucket harian untuk chart tren\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\n const dayLookup = new Map(dailyBuckets.map((b) => [b.dateKey, b]));\n\n const statusMap = new Map();\n let totalOrders = 0;\n let totalRevenue = 0;\n\n orders.forEach((row) => {\n const dayKey = String(row.created_at || \"\").slice(0, 10);\n const status = String(row.status || \"pending\").toLowerCase();\n const amount = toNumber(row.total_amount);\n\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\n\n const bucket = dayLookup.get(dayKey);\n if (bucket) {\n if (status === \"confirmed\") {\n bucket.count += 1;\n bucket.revenue += amount;\n }\n if (status === \"pending\") {\n bucket.pendingCount += 1;\n }\n }\n\n if (status === \"confirmed\") {\n totalOrders += 1;\n totalRevenue += amount;\n }\n });\n\n // Distribusi status untuk pie chart\n const statusDistribution = Array.from(statusMap.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([status, count]) => ({\n status,\n label: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\n count,\n }));\n\n // Tabel recent orders — field mapping ke kontrak standar\n const recentBookings = recent.map((row) => {\n const status = String(row.status || \"pending\").toLowerCase();\n return {\n id: row.id,\n createdAt: row.created_at,\n customerName: row.customer_name || \"-\",\n packageName: row.product_name || row.product_id || \"-\",\n totalIDR: toNumber(row.total_amount),\n status,\n statusLabel: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\n };\n });\n\n return {\n stats: {\n bookingsConfirm: totalOrders,\n revenueConfirm: totalRevenue,\n totalProducts: toNumber(raw.staticCounts?.packages),\n totalCustomers: toNumber(raw.staticCounts?.sections),\n },\n charts: {\n dailyTrends: dailyBuckets,\n statusDistribution,\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings,\n },\n };\n}\n","/**\r\n * tokoSepatuDashboardAdapter — Data-adapter layer untuk studi kasus\r\n * Toko Sepatu Online (domain retail/e-commerce).\r\n *\r\n * Adapter ini membuktikan bahwa modul reusable dashboard dapat digunakan\r\n * pada domain bisnis yang berbeda dari Cidika Travel hanya dengan\r\n * mengganti adapter, tanpa mengubah komponen inti.\r\n *\r\n * Struktur data Supabase Toko Sepatu yang diharapkan:\r\n * - Tabel `orders` : id, created_at, total_amount, status, customer_id\r\n * - Tabel `products` : id, name, brand, category, price_idr, stock\r\n * - Tabel `customers` : id, name, email, phone, city\r\n * - Tabel `order_items` : id, order_id, product_id, qty, price_idr, subtotal\r\n */\r\n\r\nimport { shortId } from \"../utils/formatters.js\";\r\nimport { toNumber, buildDayBuckets, sortMapEntries } from \"../utils/adapterHelpers.js\";\r\n\r\n/**\r\n * Membuat state kosong yang sesuai dengan kontrak data toko sepatu.\r\n * @returns {object} Empty dashboard data object.\r\n */\r\nexport function createEmptyTokoSepatuData() {\r\n return {\r\n stats: {\r\n bookingsConfirm: 0,\r\n bookingsPending: 0,\r\n revenueConfirm: 0,\r\n packages: 0,\r\n sections: 0,\r\n avgRevenue: 0,\r\n conversionRate: 0,\r\n },\r\n charts: {\r\n dailyTrends: [],\r\n statusDistribution: [],\r\n audienceDistribution: [],\r\n topPackages: [],\r\n },\r\n table: {\r\n recentBookings: [],\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Memetakan data mentah dari Supabase Toko Sepatu ke format standar widget.\r\n *\r\n * @param {object} params\r\n * @param {object} params.raw - Data mentah dari dataSource.\r\n * @param {object} params.filters - State filter aktif.\r\n * @param {object} params.range - Rentang tanggal { fromISO, toISO, daysWindow }.\r\n * @param {string} params.dateLocale - Locale untuk format tanggal.\r\n * @param {object} [params.labels] - Label i18n.\r\n * @returns {object} Objek data standar { stats, charts, table }.\r\n */\r\nexport function adaptTokoSepatuData({ raw, filters, range, dateLocale, labels }) {\r\n if (!raw) return createEmptyTokoSepatuData();\r\n\r\n const orders = raw.bookings || [];\r\n const recent = raw.recent || [];\r\n\r\n // Bangun bucket harian untuk chart tren\r\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\r\n const dayLookup = new Map(dailyBuckets.map((b) => [b.dateKey, b]));\r\n\r\n const statusMap = new Map();\r\n const productCountMap = new Map();\r\n const productRevenueMap = new Map();\r\n\r\n let ordersConfirm = 0;\r\n let ordersPending = 0;\r\n let revenueConfirm = 0;\r\n\r\n // Buat lookup nama produk\r\n const productNameMap = new Map();\r\n (raw.products || []).forEach((p) => {\r\n productNameMap.set(p.id, p.name);\r\n });\r\n\r\n orders.forEach((row) => {\r\n const dayKey = String(row.created_at || \"\").slice(0, 10);\r\n const status = String(row.status || \"pending\").toLowerCase();\r\n const total = toNumber(row.total_amount);\r\n\r\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\r\n\r\n const bucket = dayLookup.get(dayKey);\r\n if (bucket) {\r\n if (status === \"confirmed\") {\r\n bucket.count += 1;\r\n bucket.revenue += total;\r\n }\r\n if (status === \"pending\") {\r\n bucket.pendingCount += 1;\r\n }\r\n }\r\n\r\n if (status === \"confirmed\") {\r\n ordersConfirm += 1;\r\n revenueConfirm += total;\r\n\r\n // Hitung produk terlaris dari order_items\r\n const items = row.order_items || [];\r\n items.forEach((item) => {\r\n const pid = item.product_id;\r\n productCountMap.set(pid, (productCountMap.get(pid) || 0) + toNumber(item.qty));\r\n productRevenueMap.set(pid, (productRevenueMap.get(pid) || 0) + toNumber(item.subtotal));\r\n });\r\n } else if (status === \"pending\") {\r\n ordersPending += 1;\r\n }\r\n });\r\n\r\n // Distribusi status\r\n const statusDistribution = sortMapEntries(statusMap, \"desc\").map(\r\n ([status, count]) => ({\r\n status,\r\n label: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\r\n count,\r\n })\r\n );\r\n\r\n // Top products\r\n const metricMap =\r\n filters.sortPkgBy === \"revenue\" ? productRevenueMap : productCountMap;\r\n\r\n const topPackages = sortMapEntries(metricMap, filters.sortPkgDir || \"desc\")\r\n .slice(0, 5)\r\n .map(([productId, value]) => ({\r\n packageId: productId,\r\n name: productNameMap.get(productId) || shortId(productId, 6),\r\n value: toNumber(value),\r\n }));\r\n\r\n // Tabel recent orders\r\n const recentBookings = recent.map((row) => {\r\n const status = String(row.status || \"pending\").toLowerCase();\r\n // Ambil nama produk dari item pertama atau dari join\r\n const productName =\r\n row.product_name ||\r\n (row.order_items && row.order_items[0]\r\n ? productNameMap.get(row.order_items[0].product_id)\r\n : null) ||\r\n \"-\";\r\n\r\n return {\r\n id: row.id,\r\n createdAt: row.created_at,\r\n customerName: row.customer_name || \"-\",\r\n packageName: productName,\r\n totalIDR: toNumber(row.total_amount),\r\n status,\r\n statusLabel: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\r\n };\r\n });\r\n\r\n const avgRevenue =\r\n ordersConfirm > 0 ? Math.round(revenueConfirm / ordersConfirm) : 0;\r\n const conversionRate =\r\n ordersConfirm + ordersPending > 0\r\n ? Math.round((ordersConfirm / (ordersConfirm + ordersPending)) * 100)\r\n : 0;\r\n\r\n return {\r\n stats: {\r\n bookingsConfirm: ordersConfirm,\r\n bookingsPending: ordersPending,\r\n revenueConfirm,\r\n packages: toNumber(raw.staticCounts?.products),\r\n sections: toNumber(raw.staticCounts?.customers),\r\n avgRevenue,\r\n conversionRate,\r\n },\r\n charts: {\r\n dailyTrends: dailyBuckets,\r\n statusDistribution,\r\n audienceDistribution: [],\r\n topPackages,\r\n },\r\n table: {\r\n recentBookings,\r\n },\r\n };\r\n}\r\n","function ensureNoError(response, message) {\n if (response?.error) {\n const err = new Error(message);\n err.cause = response.error;\n throw err;\n }\n}\n\nexport function createCidikaSupabaseSource(supabase) {\n return {\n async fetchDashboardSnapshot({\n fromISO,\n toISO,\n audience,\n statusScope,\n languageCode,\n }) {\n const bookingsQuery = supabase\n .from(\"bookings\")\n .select(\n \"id, created_at, total_idr, status, package_id, audience, customer_name\"\n )\n .gte(\"created_at\", fromISO)\n .lte(\"created_at\", toISO)\n .order(\"created_at\", { ascending: true });\n\n if (audience) bookingsQuery.eq(\"audience\", audience);\n\n const recentQuery = supabase\n .from(\"bookings\")\n .select(\n \"id, created_at, customer_name, total_idr, status, package_id, audience\"\n )\n .gte(\"created_at\", fromISO)\n .lte(\"created_at\", toISO)\n .order(\"created_at\", { ascending: false })\n .limit(10);\n\n if (audience) recentQuery.eq(\"audience\", audience);\n if (statusScope && statusScope !== \"all\") {\n recentQuery.eq(\"status\", statusScope);\n }\n\n const [bookingsRes, recentRes, packagesRes, sectionsRes] = await Promise.all(\n [\n bookingsQuery,\n recentQuery,\n supabase.from(\"packages\").select(\"*\", { count: \"exact\", head: true }),\n supabase\n .from(\"page_sections\")\n .select(\"*\", { count: \"exact\", head: true }),\n ]\n );\n\n ensureNoError(bookingsRes, \"Failed to load booking rows.\");\n ensureNoError(recentRes, \"Failed to load recent rows.\");\n\n const bookings = bookingsRes.data || [];\n const recent = recentRes.data || [];\n\n const packageIds = Array.from(\n new Set(\n [...bookings, ...recent]\n .map((row) => row.package_id)\n .filter((value) => Boolean(value))\n )\n );\n\n let packageLocales = [];\n if (packageIds.length > 0) {\n const localeRes = await supabase\n .from(\"package_locales\")\n .select(\"package_id,title,lang\")\n .in(\"package_id\", packageIds)\n .in(\"lang\", [languageCode, \"en\", \"id\"]);\n\n if (!localeRes.error) {\n packageLocales = localeRes.data || [];\n }\n }\n\n return {\n bookings,\n recent,\n packageLocales,\n staticCounts: {\n packages: packagesRes.error ? 0 : packagesRes.count || 0,\n sections: sectionsRes.error ? 0 : sectionsRes.count || 0,\n },\n };\n },\n\n subscribeLiveUpdate(onEvent) {\n const channel = supabase\n .channel(\"reusable-dashboard-live\")\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"bookings\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"packages\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"page_sections\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"package_locales\" },\n onEvent\n )\n .subscribe();\n\n return () => {\n supabase.removeChannel(channel);\n };\n },\n };\n}\n","/**\r\n * tokoSepatuSupabaseSource — Data-source layer untuk studi kasus\r\n * Toko Sepatu Online.\r\n *\r\n * Mengimplementasikan kontrak yang sama dengan cidikaSupabaseSource:\r\n * - fetchDashboardSnapshot({ fromISO, toISO, statusScope })\r\n * - subscribeLiveUpdate(onEvent)\r\n *\r\n * Tabel yang diquery: orders, order_items, products, customers\r\n */\r\n\r\nfunction ensureNoError(response, message) {\r\n if (response?.error) {\r\n const err = new Error(message);\r\n err.cause = response.error;\r\n throw err;\r\n }\r\n}\r\n\r\n/**\r\n * Membuat data source untuk Toko Sepatu Online.\r\n *\r\n * @param {object} supabase - Instance Supabase client.\r\n * @returns {object} Objek data source { fetchDashboardSnapshot, subscribeLiveUpdate }.\r\n */\r\nexport function createTokoSepatuSupabaseSource(supabase) {\r\n return {\r\n /**\r\n * Mengambil snapshot data dashboard dari Supabase.\r\n */\r\n async fetchDashboardSnapshot({\r\n fromISO,\r\n toISO,\r\n audience,\r\n statusScope,\r\n }) {\r\n // Query semua orders dalam rentang waktu (dengan order_items untuk top products)\r\n const ordersQuery = supabase\r\n .from(\"orders\")\r\n .select(\r\n \"id, created_at, total_amount, status, customer_id, order_items(product_id, qty, price_idr, subtotal)\"\r\n )\r\n .gte(\"created_at\", fromISO)\r\n .lte(\"created_at\", toISO)\r\n .order(\"created_at\", { ascending: true });\r\n\r\n // Query recent orders (10 terbaru) dengan nama customer\r\n const recentQuery = supabase\r\n .from(\"orders\")\r\n .select(\r\n \"id, created_at, total_amount, status, customers(name), order_items(product_id, qty, products(name))\"\r\n )\r\n .gte(\"created_at\", fromISO)\r\n .lte(\"created_at\", toISO)\r\n .order(\"created_at\", { ascending: false })\r\n .limit(10);\r\n\r\n if (statusScope && statusScope !== \"all\") {\r\n recentQuery.eq(\"status\", statusScope);\r\n }\r\n\r\n const [ordersRes, recentRes, productsRes, customersRes] =\r\n await Promise.all([\r\n ordersQuery,\r\n recentQuery,\r\n supabase\r\n .from(\"products\")\r\n .select(\"id, name, brand, category, price_idr\"),\r\n supabase\r\n .from(\"customers\")\r\n .select(\"*\", { count: \"exact\", head: true }),\r\n ]);\r\n\r\n ensureNoError(ordersRes, \"Failed to load orders.\");\r\n ensureNoError(recentRes, \"Failed to load recent orders.\");\r\n\r\n const orders = ordersRes.data || [];\r\n const recentRaw = recentRes.data || [];\r\n const products = productsRes.data || [];\r\n\r\n // Map recent orders ke format yang adapter harapkan\r\n const recent = recentRaw.map((row) => ({\r\n id: row.id,\r\n created_at: row.created_at,\r\n total_amount: row.total_amount,\r\n status: row.status,\r\n customer_name: row.customers?.name || \"-\",\r\n product_name:\r\n row.order_items?.[0]?.products?.name || \"-\",\r\n order_items: row.order_items,\r\n }));\r\n\r\n return {\r\n bookings: orders,\r\n recent,\r\n products,\r\n packageLocales: [],\r\n staticCounts: {\r\n products: products.length,\r\n customers: customersRes.error ? 0 : customersRes.count || 0,\r\n },\r\n };\r\n },\r\n\r\n /**\r\n * Subscribe ke perubahan realtime pada tabel orders dan products.\r\n */\r\n subscribeLiveUpdate(onEvent) {\r\n const channel = supabase\r\n .channel(\"toko-sepatu-dashboard-live\")\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"orders\" },\r\n onEvent\r\n )\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"products\" },\r\n onEvent\r\n )\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"order_items\" },\r\n onEvent\r\n )\r\n .subscribe();\r\n\r\n return () => {\r\n supabase.removeChannel(channel);\r\n };\r\n },\r\n };\r\n}\r\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { createDefaultFilters, resolveDateRange } from \"../utils/dateRange.js\";\nimport { useRealtimeUpdate } from \"./useRealtimeUpdate.js\";\n\nexport function useReusableDashboard({\n config,\n dataSource,\n adapter,\n createEmptyState,\n languageCode,\n dateLocale,\n labels,\n}) {\n const [filters, setFilters] = useState(() =>\n createDefaultFilters(config?.defaultFilters)\n );\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n const [lastUpdatedAt, setLastUpdatedAt] = useState(null);\n const [data, setData] = useState(() => createEmptyState());\n\n\n const range = useMemo(\n () =>\n resolveDateRange({\n daysPreset: filters.daysPreset,\n dateFrom: filters.dateFrom,\n dateTo: filters.dateTo,\n }),\n [filters.daysPreset, filters.dateFrom, filters.dateTo]\n );\n\n const refresh = useCallback(\n async ({ silent = false } = {}) => {\n if (!dataSource?.fetchDashboardSnapshot) return;\n\n if (!silent) {\n setLoading(true);\n setError(\"\");\n }\n\n try {\n const raw = await dataSource.fetchDashboardSnapshot({\n fromISO: range.fromISO,\n toISO: range.toISO,\n audience: filters.audience,\n statusScope: filters.statusScope,\n languageCode,\n });\n\n const adapted = adapter({\n raw,\n filters,\n range,\n dateLocale,\n languageCode,\n labels,\n });\n\n setData(adapted);\n setLastUpdatedAt(new Date());\n if (!silent) setError(\"\");\n } catch (loadError) {\n console.error(loadError);\n if (!silent) {\n setError(labels.loadFailed);\n setData(createEmptyState());\n }\n } finally {\n if (!silent) setLoading(false);\n }\n },\n [\n dataSource,\n range,\n filters,\n languageCode,\n adapter,\n dateLocale,\n labels,\n createEmptyState,\n ]\n );\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const { liveUpdateEnabled } = useRealtimeUpdate({\n dataSource,\n onUpdate: () => refresh({ silent: true }),\n });\n\n const updateFilter = useCallback((field, value) => {\n setFilters((current) => ({\n ...current,\n [field]: value,\n }));\n }, []);\n\n const resetFilters = useCallback(() => {\n setFilters(createDefaultFilters(config?.defaultFilters));\n }, [config?.defaultFilters]);\n\n return {\n filters,\n updateFilter,\n resetFilters,\n loading,\n error,\n data,\n refresh,\n range,\n liveUpdateEnabled,\n lastUpdatedAt,\n };\n}\n","function startOfDayISO(date) {\n const value = new Date(date);\n value.setHours(0, 0, 0, 0);\n return value.toISOString();\n}\n\nfunction endOfDayISO(date) {\n const value = new Date(date);\n value.setHours(23, 59, 59, 999);\n return value.toISOString();\n}\n\nexport function formatYYYYMMDD(date) {\n const value = new Date(date);\n const year = value.getFullYear();\n const month = String(value.getMonth() + 1).padStart(2, \"0\");\n const day = String(value.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nexport function createDefaultFilters(base = {}) {\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - 29);\n\n return {\n statusScope: \"confirmed\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n dateFrom: formatYYYYMMDD(fromDate),\n dateTo: formatYYYYMMDD(new Date()),\n sortPkgBy: \"bookings\",\n sortPkgDir: \"desc\",\n ...base,\n };\n}\n\n/** Tahun minimum yang diizinkan untuk input tanggal kustom. */\nconst MIN_YEAR = 2000;\n/** Batas maksimum rentang hari untuk mencegah loop tak terhingga (5 tahun). */\nconst MAX_DAYS_WINDOW = 365 * 5;\n\n/**\n * Memvalidasi apakah tanggal masuk akal (tahun >= MIN_YEAR dan <= tahun sekarang + 1).\n * @param {Date} date\n * @returns {boolean}\n */\nfunction isReasonableDate(date) {\n if (!date || Number.isNaN(date.getTime())) return false;\n const year = date.getFullYear();\n return year >= MIN_YEAR && year <= new Date().getFullYear() + 1;\n}\n\nexport function resolveDateRange({ daysPreset, dateFrom, dateTo }) {\n if (Number(daysPreset) > 0) {\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - (Number(daysPreset) - 1));\n const toDate = new Date();\n return {\n fromISO: startOfDayISO(fromDate),\n toISO: endOfDayISO(toDate),\n daysWindow: Number(daysPreset),\n };\n }\n\n const fallbackFrom = new Date(Date.now() - 29 * 24 * 60 * 60 * 1000);\n const fallbackTo = new Date();\n\n let from = dateFrom ? new Date(dateFrom) : fallbackFrom;\n let to = dateTo ? new Date(dateTo) : fallbackTo;\n\n // Jika tanggal tidak masuk akal (misal tahun 0202), gunakan fallback\n if (!isReasonableDate(from)) from = fallbackFrom;\n if (!isReasonableDate(to)) to = fallbackTo;\n\n if (from.getTime() > to.getTime()) {\n const swap = from;\n from = to;\n to = swap;\n }\n\n const fromISO = startOfDayISO(from);\n const toISO = endOfDayISO(to);\n const diffMs = new Date(toISO).getTime() - new Date(fromISO).getTime();\n // Cap daysWindow agar tidak pernah melebihi MAX_DAYS_WINDOW\n const daysWindow = Math.min(\n MAX_DAYS_WINDOW,\n Math.max(1, Math.round(diffMs / 86400000) + 1)\n );\n\n return { fromISO, toISO, daysWindow };\n}\n","import { useEffect, useState } from \"react\";\n\n/**\n * useRealtimeUpdate — Custom hook untuk mengelola subscription live update\n * melalui mekanisme Supabase Realtime (Postgres Changes).\n *\n * Hook ini mengabstraksikan logika subscription dan debounce sehingga dapat\n * digunakan secara independen oleh consumer yang membutuhkan live update\n * tanpa menggunakan useReusableDashboard secara penuh.\n *\n * @param {object} params\n * @param {object} params.dataSource - Objek data source yang mengimplementasikan\n * `subscribeLiveUpdate(callback): unsubscribeFn`.\n * @param {Function} params.onUpdate - Callback yang dipanggil saat ada perubahan data.\n * Dipanggil setelah debounce selesai.\n * @param {number} [params.debounceMs=350] - Durasi debounce dalam milidetik.\n *\n * @returns {{ liveUpdateEnabled: boolean }} State apakah live update aktif.\n *\n * @example\n * const { liveUpdateEnabled } = useRealtimeUpdate({\n * dataSource,\n * onUpdate: () => refresh({ silent: true }),\n * });\n */\nexport function useRealtimeUpdate({ dataSource, onUpdate, debounceMs = 350 }) {\n const [liveUpdateEnabled, setLiveUpdateEnabled] = useState(false);\n\n useEffect(() => {\n if (!dataSource?.subscribeLiveUpdate) return undefined;\n\n let debounceId;\n setLiveUpdateEnabled(true);\n\n const unsubscribe = dataSource.subscribeLiveUpdate(() => {\n clearTimeout(debounceId);\n debounceId = setTimeout(() => {\n onUpdate?.();\n }, debounceMs);\n });\n\n return () => {\n clearTimeout(debounceId);\n setLiveUpdateEnabled(false);\n unsubscribe?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dataSource, debounceMs]);\n // Note: onUpdate sengaja tidak dimasukkan dependency array untuk menghindari\n // re-subscribe yang tidak perlu saat parent re-render. Consumer harus\n // memoize callback-nya dengan useCallback jika ingin reaktivitas penuh.\n\n return { liveUpdateEnabled };\n}\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function Button({\n variant = \"primary\",\n size = \"md\",\n disabled = false,\n className = \"\",\n onClick,\n children,\n ...rest\n}) {\n const classes = [\n \"rdb-btn\",\n `rdb-btn-${variant}`,\n `rdb-btn-${size}`,\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button type=\"button\" className={classes} disabled={disabled} onClick={onClick} {...rest}>\n {children}\n </button>\n );\n}\n\nButton.propTypes = {\n variant: PropTypes.oneOf([\"primary\", \"secondary\", \"ghost\"]),\n size: PropTypes.oneOf([\"sm\", \"md\", \"lg\"]),\n disabled: PropTypes.bool,\n className: PropTypes.string,\n onClick: PropTypes.func,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function Input({\n type = \"text\",\n value,\n onChange,\n placeholder,\n label,\n disabled = false,\n className = \"\",\n ...rest\n}) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n {label ? <label className=\"rdb-label\">{label}</label> : null}\n <input\n type={type}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n disabled={disabled}\n className={[\"rdb-input\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n </div>\n );\n}\n\nInput.propTypes = {\n type: PropTypes.string,\n value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n onChange: PropTypes.func,\n placeholder: PropTypes.string,\n label: PropTypes.string,\n disabled: PropTypes.bool,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport {\n BarChart3,\n Calendar,\n DollarSign,\n PieChart,\n RotateCcw,\n TrendingUp,\n TrendingDown,\n Users,\n Search,\n ChevronLeft,\n ChevronRight,\n ArrowUp,\n ArrowDown,\n AlertCircle,\n} from \"lucide-react\";\n\n/**\n * Registry ikon yang tersedia di modul dashboard.\n * @type {Object.<string, React.ComponentType>}\n */\nconst ICON_REGISTRY = {\n BarChart3,\n Calendar,\n DollarSign,\n PieChart,\n RotateCcw,\n TrendingUp,\n TrendingDown,\n Users,\n Search,\n ChevronLeft,\n ChevronRight,\n ArrowUp,\n ArrowDown,\n AlertCircle,\n};\n\n/**\n * Icon — Atom komponen ikon berbasis SVG menggunakan Lucide React.\n *\n * @param {object} props\n * @param {string} props.name - Nama ikon dari registry (misal: \"TrendingUp\").\n * @param {number} [props.size=20] - Ukuran ikon dalam piksel.\n * @param {string} [props.className=\"\"] - ClassName tambahan.\n */\nexport default function Icon({ name, size = 20, className = \"\", ...rest }) {\n const IconComponent = ICON_REGISTRY[name] || BarChart3;\n\n return <IconComponent size={size} className={className} {...rest} />;\n}\n\n/**\n * Resolves an icon name to its Lucide React component.\n * Backward-compatible utility used internally.\n *\n * @param {string} name - Nama ikon.\n * @returns {React.ComponentType} Komponen ikon.\n */\nexport function resolveIcon(name) {\n return ICON_REGISTRY[name] || BarChart3;\n}\n\nIcon.propTypes = {\n /** Nama ikon dari registry Lucide React. */\n name: PropTypes.string.isRequired,\n /** Ukuran ikon dalam piksel. */\n size: PropTypes.number,\n /** ClassName tambahan. */\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst VARIANT_CLASS = {\n h1: \"rdb-h1\",\n h2: \"rdb-h2\",\n h3: \"rdb-h3\",\n subheading: \"rdb-subheading\",\n body: \"rdb-body\",\n caption: \"rdb-caption\",\n metric: \"rdb-metric\",\n};\n\nconst VARIANT_TAG = {\n h1: \"h1\", h2: \"h2\", h3: \"h3\",\n subheading: \"p\", body: \"p\", caption: \"span\", metric: \"span\",\n};\n\nexport default function Typography({ variant = \"body\", className = \"\", children, ...rest }) {\n const Tag = VARIANT_TAG[variant] || \"p\";\n const cls = [VARIANT_CLASS[variant] || \"rdb-body\", className].filter(Boolean).join(\" \");\n return <Tag className={cls} {...rest}>{children}</Tag>;\n}\n\nTypography.propTypes = {\n variant: PropTypes.oneOf([\"h1\",\"h2\",\"h3\",\"subheading\",\"body\",\"caption\",\"metric\"]),\n className: PropTypes.string,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst STATUS_CLASS = {\n confirmed: \"rdb-badge-confirmed\",\n pending: \"rdb-badge-pending\",\n cancelled: \"rdb-badge-cancelled\",\n success: \"rdb-badge-success\",\n info: \"rdb-badge-info\",\n default: \"rdb-badge-default\",\n};\n\nexport default function Badge({ status = \"default\", className = \"\", children, ...rest }) {\n const statusClass = STATUS_CLASS[status] || STATUS_CLASS.default;\n return (\n <span className={[\"rdb-badge\", statusClass, className].filter(Boolean).join(\" \")} {...rest}>\n {children}\n </span>\n );\n}\n\nBadge.propTypes = {\n status: PropTypes.string,\n className: PropTypes.string,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function SkeletonLoader({ className = \"\", style = {} }) {\n return (\n <div\n className={[\"rdb-skeleton\", className].filter(Boolean).join(\" \")}\n style={{ minHeight: 20, ...style }}\n role=\"status\"\n aria-label=\"Loading...\"\n />\n );\n}\n\nSkeletonLoader.propTypes = {\n className: PropTypes.string,\n style: PropTypes.object,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\nimport { formatIDR } from \"../../utils/formatters.js\";\n\nfunction renderValue(format, value) {\n if (format === \"currency\") return `Rp ${formatIDR(value)}`;\n if (format === \"percent\") return `${Number(value) || 0}%`;\n return String(Number(value) || 0);\n}\n\nexport default function StatCard({\n label,\n value,\n icon = \"TrendingUp\",\n format = \"number\",\n trend = null,\n accentColor = \"blue\",\n className = \"\",\n}) {\n return (\n <div className={[\"rdb-card rdb-statcard\", `rdb-accent-${accentColor}`, className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-statcard-header\">\n <div className=\"rdb-statcard-label-group\">\n <div className=\"rdb-statcard-icon\">\n <Icon name={icon} size={16} />\n </div>\n <span className=\"rdb-statcard-label\">{label}</span>\n </div>\n {trend ? (\n <Icon\n name={trend === \"up\" ? \"TrendingUp\" : \"TrendingDown\"}\n size={16}\n style={{ color: trend === \"up\" ? \"#10b981\" : \"#ef4444\" }}\n />\n ) : null}\n </div>\n <div className=\"rdb-statcard-value\">{renderValue(format, value)}</div>\n </div>\n );\n}\n\nStatCard.propTypes = {\n label: PropTypes.string.isRequired,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n icon: PropTypes.string,\n format: PropTypes.oneOf([\"number\", \"currency\", \"percent\"]),\n trend: PropTypes.oneOf([\"up\", \"down\", null]),\n accentColor: PropTypes.string,\n className: PropTypes.string,\n};\n","import React, { useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function SearchBar({\n value: controlledValue,\n onChange,\n onSearch,\n placeholder = \"Search...\",\n className = \"\",\n}) {\n const [internalValue, setInternalValue] = useState(\"\");\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const handleChange = useCallback((event) => {\n const v = event.target.value;\n if (!isControlled) setInternalValue(v);\n if (onChange) onChange(v);\n if (onSearch) onSearch(v);\n }, [isControlled, onChange, onSearch]);\n\n const handleKeyDown = useCallback((event) => {\n if (event.key === \"Enter\" && onSearch) onSearch(currentValue);\n }, [currentValue, onSearch]);\n\n return (\n <div className={[\"rdb-searchbar\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-searchbar-icon\">\n <Icon name=\"Search\" size={16} />\n </div>\n <input\n type=\"search\"\n value={currentValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"rdb-input rdb-searchbar-input\"\n style={{ width: \"100%\" }}\n />\n </div>\n );\n}\n\nSearchBar.propTypes = {\n value: PropTypes.string,\n onChange: PropTypes.func,\n onSearch: PropTypes.func,\n placeholder: PropTypes.string,\n className: PropTypes.string,\n};\n","import React, { useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst CURRENT_YEAR = new Date().getFullYear();\nconst MIN_YEAR = 2020;\nconst MAX_YEAR = CURRENT_YEAR + 1;\nconst MONTHS = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\n\nfunction getYears() {\n const y = [];\n for (let i = MAX_YEAR; i >= MIN_YEAR; i--) y.push(i);\n return y;\n}\n\nfunction getDaysInMonth(year, month) {\n return new Date(year, month, 0).getDate();\n}\n\nfunction parseDate(value) {\n if (value && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [y, m, d] = value.split(\"-\").map(Number);\n if (y >= MIN_YEAR && y <= MAX_YEAR && m >= 1 && m <= 12)\n return { year: y, month: m, day: d };\n }\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };\n}\n\nfunction fmt({ year, month, day }) {\n return `${year}-${String(month).padStart(2,\"0\")}-${String(day).padStart(2,\"0\")}`;\n}\n\nfunction DatePicker({ value, onChange, disabled = false, label = \"\" }) {\n const p = parseDate(value);\n const years = getYears();\n const maxDay = getDaysInMonth(p.year, p.month);\n\n const handleChange = useCallback((field, val) => {\n const u = { ...p, [field]: Number(val) };\n const max = getDaysInMonth(u.year, u.month);\n if (u.day > max) u.day = max;\n onChange(fmt(u));\n }, [p, onChange]);\n\n return (\n <div style={{ display:\"flex\", flexDirection:\"column\", gap:2 }}>\n {label ? <span className=\"rdb-caption rdb-label\">{label}</span> : null}\n <div style={{ display:\"flex\", gap:4, alignItems:\"center\" }}>\n <select className=\"rdb-select\" style={{ width:52 }} value={p.day}\n onChange={e => handleChange(\"day\", e.target.value)} disabled={disabled}>\n {Array.from({ length: maxDay }, (_,i) => i+1).map(d => (\n <option key={d} value={d}>{String(d).padStart(2,\"0\")}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width:62 }} value={p.month}\n onChange={e => handleChange(\"month\", e.target.value)} disabled={disabled}>\n {MONTHS.map((name, idx) => (\n <option key={idx+1} value={idx+1}>{name}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width:72 }} value={p.year}\n onChange={e => handleChange(\"year\", e.target.value)} disabled={disabled}>\n {years.map(y => <option key={y} value={y}>{y}</option>)}\n </select>\n </div>\n </div>\n );\n}\n\nexport default function DateRangeFilter({\n dateFrom, dateTo, onRangeChange,\n disabled = false, labelFrom = \"From\", labelTo = \"To\", className = \"\",\n}) {\n const handleFrom = useCallback(v => onRangeChange?.({ dateFrom: v, dateTo }), [dateTo, onRangeChange]);\n const handleTo = useCallback(v => onRangeChange?.({ dateFrom, dateTo: v }), [dateFrom, onRangeChange]);\n\n return (\n <div className={[\"rdb-daterange\", className].filter(Boolean).join(\" \")}>\n <DatePicker value={dateFrom} onChange={handleFrom} disabled={disabled} label={labelFrom} />\n <DatePicker value={dateTo} onChange={handleTo} disabled={disabled} label={labelTo} />\n </div>\n );\n}\n\nDateRangeFilter.propTypes = {\n dateFrom: PropTypes.string.isRequired,\n dateTo: PropTypes.string.isRequired,\n onRangeChange: PropTypes.func.isRequired,\n disabled: PropTypes.bool,\n labelFrom: PropTypes.string,\n labelTo: PropTypes.string,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function ChartHeader({ title, icon = \"BarChart3\", actions = null, className = \"\" }) {\n return (\n <div className={[\"rdb-chart-title-wrap\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-chart-title\">\n <Icon name={icon} size={18} />\n {title}\n </div>\n {actions}\n </div>\n );\n}\n\nChartHeader.propTypes = {\n title: PropTypes.string.isRequired,\n icon: PropTypes.string,\n actions: PropTypes.node,\n className: PropTypes.string,\n};\n","import React, { useMemo, useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport SearchBar from \"../molecules/SearchBar.jsx\";\nimport Badge from \"../atoms/Badge.jsx\";\nimport Icon from \"../atoms/Icon.jsx\";\nimport { formatDate, formatIDR } from \"../../utils/formatters.js\";\n\nexport default function DataTable({\n columns, data = [], labels = {}, dateLocale = \"id-ID\",\n searchable = true, sortable = true, pageSize = 10,\n emptyLabel = \"No data\", searchPlaceholder = \"Search...\", className = \"\",\n}) {\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [sortField, setSortField] = useState(null);\n const [sortDirection, setSortDirection] = useState(\"asc\");\n const [currentPage, setCurrentPage] = useState(1);\n\n const filteredData = useMemo(() => {\n if (!searchQuery.trim()) return data;\n const q = searchQuery.toLowerCase();\n return data.filter(row =>\n columns.some(col => {\n const v = row[col.accessor];\n return v != null && String(v).toLowerCase().includes(q);\n })\n );\n }, [data, searchQuery, columns]);\n\n const sortedData = useMemo(() => {\n if (!sortField) return filteredData;\n return [...filteredData].sort((a, b) => {\n const aV = a[sortField] ?? \"\";\n const bV = b[sortField] ?? \"\";\n if (typeof aV === \"number\" && typeof bV === \"number\")\n return sortDirection === \"asc\" ? aV - bV : bV - aV;\n const cmp = String(aV).localeCompare(String(bV), undefined, { numeric: true });\n return sortDirection === \"asc\" ? cmp : -cmp;\n });\n }, [filteredData, sortField, sortDirection]);\n\n const totalPages = Math.max(1, Math.ceil(sortedData.length / pageSize));\n const safePage = Math.min(currentPage, totalPages);\n const paginatedData = useMemo(() => {\n const start = (safePage - 1) * pageSize;\n return sortedData.slice(start, start + pageSize);\n }, [sortedData, safePage, pageSize]);\n\n const handleSearch = useCallback(v => { setSearchQuery(v); setCurrentPage(1); }, []);\n const handleSort = useCallback(acc => {\n if (!sortable) return;\n if (sortField === acc) setSortDirection(p => p === \"asc\" ? \"desc\" : \"asc\");\n else { setSortField(acc); setSortDirection(\"asc\"); }\n setCurrentPage(1);\n }, [sortable, sortField]);\n const handlePrev = useCallback(() => setCurrentPage(p => Math.max(1, p-1)), []);\n const handleNext = useCallback(() => setCurrentPage(p => Math.min(totalPages, p+1)), [totalPages]);\n\n return (\n <div style={{ display:\"flex\", flexDirection:\"column\", gap:12 }} className={className}>\n {searchable ? (\n <SearchBar value={searchQuery} onSearch={handleSearch} placeholder={searchPlaceholder} />\n ) : null}\n\n <div className=\"rdb-table-wrapper\">\n <table className=\"rdb-table\">\n <thead>\n <tr>\n {columns.map(col => (\n <th key={col.id} onClick={() => handleSort(col.accessor)}>\n <div style={{ display:\"flex\", alignItems:\"center\", gap:4 }}>\n <span>{labels[col.label] || col.label}</span>\n {sortable && sortField === col.accessor ? (\n <Icon name={sortDirection === \"asc\" ? \"ArrowUp\" : \"ArrowDown\"} size={13}\n style={{ color: \"var(--rdb-blue-500)\" }} />\n ) : null}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {paginatedData.map(row => (\n <tr key={row.id}>\n {columns.map(col => (\n <td key={`${row.id}-${col.id}`}>{renderCell(col, row, dateLocale)}</td>\n ))}\n </tr>\n ))}\n {paginatedData.length === 0 ? (\n <tr>\n <td className=\"rdb-table-empty\" colSpan={columns.length}>{emptyLabel}</td>\n </tr>\n ) : null}\n </tbody>\n </table>\n </div>\n\n {sortedData.length > pageSize ? (\n <div className=\"rdb-pagination\">\n <span className=\"rdb-pagination-info\">\n {(safePage-1)*pageSize+1}–{Math.min(safePage*pageSize, sortedData.length)} of {sortedData.length}\n </span>\n <div className=\"rdb-pagination-controls\">\n <button type=\"button\" className=\"rdb-page-btn\" onClick={handlePrev} disabled={safePage <= 1} aria-label=\"Previous\">\n <Icon name=\"ChevronLeft\" size={16} />\n </button>\n <span className=\"rdb-pagination-page\">{safePage} / {totalPages}</span>\n <button type=\"button\" className=\"rdb-page-btn\" onClick={handleNext} disabled={safePage >= totalPages} aria-label=\"Next\">\n <Icon name=\"ChevronRight\" size={16} />\n </button>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction renderCell(column, row, dateLocale) {\n const value = row[column.accessor];\n if (column.type === \"date\") return formatDate(value, dateLocale);\n if (column.type === \"currency\") return `Rp ${formatIDR(value)}`;\n if (column.type === \"statusBadge\") {\n const status = row[column.statusAccessor] || \"pending\";\n return <Badge status={status}>{value}</Badge>;\n }\n return value || \"-\";\n}\n\nDataTable.propTypes = {\n columns: PropTypes.arrayOf(PropTypes.shape({\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n accessor: PropTypes.string.isRequired,\n type: PropTypes.oneOf([\"date\",\"currency\",\"statusBadge\"]),\n statusAccessor: PropTypes.string,\n })).isRequired,\n data: PropTypes.arrayOf(PropTypes.object),\n labels: PropTypes.object,\n dateLocale: PropTypes.string,\n searchable: PropTypes.bool,\n sortable: PropTypes.bool,\n pageSize: PropTypes.number,\n emptyLabel: PropTypes.string,\n searchPlaceholder: PropTypes.string,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Legend,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport ChartHeader from \"../molecules/ChartHeader.jsx\";\nimport SkeletonLoader from \"../atoms/SkeletonLoader.jsx\";\nimport { formatIDR } from \"../../utils/formatters.js\";\n\n/**\n * Palet warna default untuk grafik.\n * @type {string[]}\n */\nconst COLORS = [\n \"#0ea5e9\",\n \"#a78bfa\",\n \"#f59e0b\",\n \"#10b981\",\n \"#ef4444\",\n \"#22d3ee\",\n];\n\n/**\n * ChartCard — Organism kartu grafik yang mengintegrasikan ChartHeader\n * dengan area visualisasi. Mendukung tipe grafik area, pie, dan bar.\n *\n * @param {object} props\n * @param {object} props.widget - Konfigurasi widget chart.\n * @param {object} props.labels - Objek label i18n.\n * @param {boolean} props.loading - Apakah sedang loading.\n * @param {object} props.filters - State filter dashboard.\n * @param {object} props.chartData - Data untuk semua jenis chart.\n * @param {string} [props.className=\"\"] - ClassName tambahan.\n */\nexport default function ChartCard({\n widget,\n labels,\n loading,\n filters,\n chartData,\n className = \"\",\n}) {\n const content = (() => {\n if (loading) return <SkeletonLoader style={{ height: 256 }} />;\n\n if (widget.type === \"dailyArea\") {\n return renderDailyArea(labels, filters, chartData.dailyTrends);\n }\n if (widget.type === \"statusPie\") {\n return renderPie(chartData.statusDistribution);\n }\n if (widget.type === \"audiencePie\") {\n return renderPie(chartData.audienceDistribution);\n }\n if (widget.type === \"topPackagesBar\") {\n return renderTopPackages(chartData.topPackages, labels, filters.sortPkgBy);\n }\n\n return <div className=\"rdb-muted\">Unsupported chart type.</div>;\n })();\n\n return (\n <div className={`rdb-card rdb-chart-card ${className}`}>\n <ChartHeader\n title={labels[widget.label] || widget.label}\n icon={widget.icon}\n />\n {content}\n </div>\n );\n}\n\n/**\n * Merender grafik area harian (daily area chart).\n * @param {object} labels - Label i18n.\n * @param {object} filters - Filter dashboard.\n * @param {Array} dailyData - Data daily trends.\n * @returns {React.ReactElement} Komponen AreaChart.\n */\nfunction renderDailyArea(labels, filters, dailyData = []) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"label\" />\n <YAxis yAxisId=\"left\" />\n <YAxis yAxisId=\"right\" orientation=\"right\" />\n <Tooltip\n formatter={(value, name) =>\n name === \"revenue\"\n ? [`Rp ${formatIDR(value)}`, labels.revenueMetric]\n : [value, labels.bookingsMetric]\n }\n />\n <Legend />\n <Area\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"count\"\n name={labels.confirmedBookingMetric}\n stroke=\"#0ea5e9\"\n fill=\"#0ea5e9\"\n fillOpacity={0.3}\n />\n <Area\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"revenue\"\n name={labels.confirmedRevenueMetric}\n stroke=\"#a78bfa\"\n fill=\"#a78bfa\"\n fillOpacity={0.3}\n />\n {filters.includePendingOverlay ? (\n <Area\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"pendingCount\"\n name={labels.pendingMetric}\n stroke=\"#ef4444\"\n fill=\"#ef4444\"\n fillOpacity={0.1}\n strokeDasharray=\"4 4\"\n />\n ) : null}\n </AreaChart>\n </ResponsiveContainer>\n );\n}\n\n/**\n * Merender diagram lingkaran (Pie/Donut Chart).\n * @param {Array} data - Data distribusi.\n * @returns {React.ReactElement} Komponen PieChart.\n */\nfunction renderPie(data = []) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <PieChart>\n <Pie\n data={data}\n dataKey=\"count\"\n nameKey=\"label\"\n innerRadius={60}\n outerRadius={100}\n paddingAngle={2}\n >\n {data.map((_, index) => (\n <Cell\n key={`${index}-${data[index].label}`}\n fill={COLORS[index % COLORS.length]}\n />\n ))}\n </Pie>\n <Tooltip />\n <Legend />\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\n/**\n * Merender grafik batang (Bar Chart) untuk paket teratas.\n * @param {Array} data - Data top packages.\n * @param {object} labels - Label i18n.\n * @param {string} sortPkgBy - Metrik pengurutan (bookings/revenue).\n * @returns {React.ReactElement} Komponen BarChart.\n */\nfunction renderTopPackages(data = [], labels, sortPkgBy) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <BarChart data={data} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" allowDecimals={false} />\n <YAxis type=\"category\" dataKey=\"name\" width={120} />\n <Tooltip\n formatter={(value) =>\n sortPkgBy === \"revenue\"\n ? [`Rp ${formatIDR(value)}`, labels.revenueMetric]\n : [value, labels.bookingsMetric]\n }\n />\n <Bar\n dataKey=\"value\"\n name={\n sortPkgBy === \"revenue\"\n ? labels.revenueMetric\n : labels.bookingsMetric\n }\n fill=\"#10b981\"\n radius={[4, 4, 4, 4]}\n />\n </BarChart>\n </ResponsiveContainer>\n );\n}\n\nChartCard.propTypes = {\n /** Konfigurasi widget chart. */\n widget: PropTypes.shape({\n id: PropTypes.string.isRequired,\n type: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.string,\n }).isRequired,\n /** Objek label i18n. */\n labels: PropTypes.object.isRequired,\n /** Apakah sedang loading. */\n loading: PropTypes.bool,\n /** State filter dashboard. */\n filters: PropTypes.object,\n /** Data untuk semua jenis chart. */\n chartData: PropTypes.object,\n /** ClassName tambahan. */\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Button from \"../atoms/Button.jsx\";\nimport DateRangeFilter from \"../molecules/DateRangeFilter.jsx\";\n\nconst STATUS_OPTIONS = [\"confirmed\", \"pending\", \"all\"];\nconst AUDIENCE_OPTIONS = [\"\", \"domestic\", \"foreign\"];\nconst DAY_PRESETS = [7, 30, 90, 0];\nconst SORT_BY_OPTIONS = [\"bookings\", \"revenue\"];\nconst SORT_DIR_OPTIONS = [\"desc\", \"asc\"];\n\nexport default function FilterPanel({ filters, labels, onFilterChange, onResetFilters, className = \"\" }) {\n return (\n <div className={[\"rdb-filter-panel\", className].filter(Boolean).join(\" \")}>\n {/* Row 1 */}\n <div className=\"rdb-filter-row\">\n <select className=\"rdb-select\" value={filters.statusScope}\n onChange={e => onFilterChange(\"statusScope\", e.target.value)}>\n {STATUS_OPTIONS.map(s => (\n <option key={s} value={s}>\n {s === \"confirmed\" ? labels.confirmedOnly : s === \"pending\" ? labels.pendingOnly : labels.allStatus}\n </option>\n ))}\n </select>\n\n <label className=\"rdb-filter-overlay-label\">\n <input type=\"checkbox\" checked={filters.includePendingOverlay}\n onChange={e => onFilterChange(\"includePendingOverlay\", e.target.checked)} />\n <span className=\"rdb-body\">{labels.showPendingOverlay}</span>\n </label>\n\n <select className=\"rdb-select\" value={filters.audience}\n onChange={e => onFilterChange(\"audience\", e.target.value)}>\n {AUDIENCE_OPTIONS.map(a => (\n <option key={a || \"all\"} value={a}>\n {a === \"domestic\" ? labels.audienceDomestic : a === \"foreign\" ? labels.audienceForeign : labels.allAudience}\n </option>\n ))}\n </select>\n\n <select className=\"rdb-select\" value={String(filters.daysPreset)}\n onChange={e => onFilterChange(\"daysPreset\", Number(e.target.value))}>\n {DAY_PRESETS.map(d => (\n <option key={String(d)} value={String(d)}>\n {d === 0 ? labels.customDate : labels.dayLabel(d)}\n </option>\n ))}\n </select>\n\n <DateRangeFilter\n dateFrom={filters.dateFrom || \"\"}\n dateTo={filters.dateTo || \"\"}\n onRangeChange={({ dateFrom, dateTo }) => {\n if (dateFrom !== filters.dateFrom) onFilterChange(\"dateFrom\", dateFrom);\n if (dateTo !== filters.dateTo) onFilterChange(\"dateTo\", dateTo);\n }}\n disabled={filters.daysPreset !== 0}\n className=\"rdb-filter-date\"\n />\n </div>\n\n {/* Row 2 */}\n <div className=\"rdb-filter-actions\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onResetFilters}>{labels.reset}</Button>\n <div className=\"rdb-filter-sort\">\n <span className=\"rdb-caption\">{labels.topSort}:</span>\n <select className=\"rdb-select\" style={{ width: \"auto\" }} value={filters.sortPkgBy}\n onChange={e => onFilterChange(\"sortPkgBy\", e.target.value)}>\n {SORT_BY_OPTIONS.map(s => (\n <option key={s} value={s}>{s === \"bookings\" ? labels.sortBookings : labels.sortRevenue}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width: \"auto\" }} value={filters.sortPkgDir}\n onChange={e => onFilterChange(\"sortPkgDir\", e.target.value)}>\n {SORT_DIR_OPTIONS.map(d => (\n <option key={d} value={d}>{d === \"desc\" ? labels.sortDesc : labels.sortAsc}</option>\n ))}\n </select>\n </div>\n </div>\n </div>\n );\n}\n\nFilterPanel.propTypes = {\n filters: PropTypes.object.isRequired,\n labels: PropTypes.object.isRequired,\n onFilterChange: PropTypes.func.isRequired,\n onResetFilters: PropTypes.func.isRequired,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function SidebarNavigation({ items = [], activeItem = \"\", onItemClick, logo = null, className = \"\" }) {\n return (\n <aside className={[\"rdb-sidebar\", className].filter(Boolean).join(\" \")}>\n {logo ? <div className=\"rdb-sidebar-logo\">{logo}</div> : null}\n <nav className=\"rdb-sidebar-nav\" aria-label=\"Sidebar navigation\">\n {items.map(item => {\n const isActive = item.id === activeItem;\n return (\n <button key={item.id} type=\"button\"\n onClick={() => onItemClick?.(item.id)}\n aria-current={isActive ? \"page\" : undefined}\n className={[\"rdb-nav-item\", isActive ? \"rdb-nav-item-active\" : \"\"].filter(Boolean).join(\" \")}>\n {item.icon ? (\n <Icon name={item.icon} size={18}\n style={{ color: isActive ? \"var(--rdb-blue-600)\" : \"var(--rdb-text-subtle)\" }} />\n ) : null}\n <span>{item.label}</span>\n {isActive ? <span className=\"rdb-nav-dot\" /> : null}\n </button>\n );\n })}\n </nav>\n </aside>\n );\n}\n\nSidebarNavigation.propTypes = {\n items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, icon: PropTypes.string })),\n activeItem: PropTypes.string,\n onItemClick: PropTypes.func,\n logo: PropTypes.node,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function TopbarHeader({ title = \"\", actions = null, leading = null, className = \"\" }) {\n return (\n <header className={[\"rdb-topbar\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-topbar-left\">\n {leading}\n {title ? <span className=\"rdb-h2\" style={{ overflow:\"hidden\", textOverflow:\"ellipsis\", whiteSpace:\"nowrap\" }}>{title}</span> : null}\n </div>\n {actions ? <div className=\"rdb-topbar-right\">{actions}</div> : null}\n </header>\n );\n}\n\nTopbarHeader.propTypes = {\n title: PropTypes.string,\n actions: PropTypes.node,\n leading: PropTypes.node,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function DashboardLayout({ header = null, sidebar = null, children, className = \"\" }) {\n return (\n <div className={[\"rdb-layout\", className].filter(Boolean).join(\" \")}>\n {header}\n <div className=\"rdb-layout-body\">\n {sidebar}\n <main className=\"rdb-layout-main\">{children}</main>\n </div>\n </div>\n );\n}\n\nDashboardLayout.propTypes = {\n header: PropTypes.node,\n sidebar: PropTypes.node,\n children: PropTypes.node.isRequired,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport \"./dashboard.css\";\nimport Icon from \"./atoms/Icon.jsx\";\nimport SkeletonLoader from \"./atoms/SkeletonLoader.jsx\";\nimport Button from \"./atoms/Button.jsx\";\nimport Badge from \"./atoms/Badge.jsx\";\nimport StatCard from \"./molecules/StatCard.jsx\";\nimport FilterPanel from \"./organisms/FilterPanel.jsx\";\nimport ChartCard from \"./organisms/ChartCard.jsx\";\nimport DataTable from \"./organisms/DataTable.jsx\";\nimport { SetupWizard } from \"./SetupWizard.jsx\";\nimport { validateDashboardConfig } from \"../config/createDashboardConfig.js\";\n\n/**\n * ReusableDashboardView — Komponen halaman (Page) dashboard utama.\n *\n * Fitur tambahan (revisi dosen — Opsi B):\n * - Secara otomatis mendeteksi apakah konfigurasi sudah valid.\n * - Jika belum valid, menampilkan SetupWizard (pop-up panduan interaktif).\n * - Developer dapat menutup wizard untuk lanjut tanpa konfigurasi.\n * - Prop `supabase` opsional: mengaktifkan fitur baca tabel langsung di wizard.\n * - Prop `dashboardConfig` opsional: jika diisi (hasil createDashboardConfig),\n * validasi dilakukan otomatis.\n *\n * @param {object} props\n * @param {object} props.config - Konfigurasi widget dashboard.\n * @param {object} props.labels - Objek label i18n.\n * @param {boolean} props.loading - Status loading data.\n * @param {string} [props.error] - Pesan error jika ada.\n * @param {object} [props.filters] - State filter dashboard.\n * @param {Function} props.onFilterChange - Callback perubahan filter.\n * @param {Function} props.onResetFilters - Callback reset filter.\n * @param {Function} props.onRefresh - Callback refresh data.\n * @param {object} [props.data] - Data dashboard.\n * @param {string} [props.dateLocale] - Locale untuk format tanggal.\n * @param {boolean} [props.liveUpdateEnabled] - Apakah live update aktif.\n * @param {object} [props.supabase] - Supabase client (aktifkan fitur baca tabel di wizard).\n * @param {object} [props.dashboardConfig] - Hasil createDashboardConfig() untuk validasi otomatis.\n */\nexport function ReusableDashboardView({\n config, labels, loading, error, filters,\n onFilterChange, onResetFilters, onRefresh,\n data, dateLocale, liveUpdateEnabled,\n supabase, dashboardConfig,\n}) {\n // ── Deteksi apakah setup wizard perlu ditampilkan ──────────────────\n // Validasi dilakukan berdasarkan dashboardConfig (jika ada) atau\n // pengecekan manual pada prop config & labels.\n const [wizardDismissed, setWizardDismissed] = React.useState(false);\n\n const configIssues = React.useMemo(() => {\n if (wizardDismissed) return [];\n\n // Jika developer menyertakan dashboardConfig (dari createDashboardConfig),\n // gunakan validator bawaan factory\n if (dashboardConfig) {\n const { issues } = validateDashboardConfig(dashboardConfig);\n return issues;\n }\n\n // Fallback: validasi manual pada prop langsung\n const issues = [];\n if (!config) issues.push(\"Prop 'config' (widgetConfig) belum diisi.\");\n if (!config?.widgets?.stats?.length) issues.push(\"widgetConfig.widgets.stats kosong. Tambahkan minimal 1 stat card.\");\n if (!config?.widgets?.charts?.length) issues.push(\"widgetConfig.widgets.charts kosong. Tambahkan minimal 1 chart.\");\n if (!config?.widgets?.table?.columns?.length) issues.push(\"widgetConfig.widgets.table.columns kosong.\");\n if (!labels) issues.push(\"Prop 'labels' belum diisi.\");\n if (!labels?.title) issues.push(\"labels.title belum diisi.\");\n if (!labels?.formatStatusLabel) issues.push(\"labels.formatStatusLabel (function) belum diisi.\");\n return issues;\n }, [config, labels, dashboardConfig, wizardDismissed]);\n\n const showWizard = !wizardDismissed && configIssues.length > 0;\n\n // ── Guard: jika config benar-benar null, render wizard saja ────────\n if (!config || !config.widgets) {\n return (\n <div className=\"rdb-view\">\n <SetupWizard\n issues={[\"Prop 'config' (widgetConfig) belum diisi atau tidak valid.\"]}\n onDismiss={() => setWizardDismissed(true)}\n supabase={supabase}\n />\n </div>\n );\n }\n\n return (\n <div className=\"rdb-view\">\n {/* Setup Wizard (muncul saat konfigurasi belum lengkap) */}\n {showWizard && (\n <SetupWizard\n issues={configIssues}\n onDismiss={() => setWizardDismissed(true)}\n supabase={supabase}\n />\n )}\n\n <div className=\"rdb-view-container\">\n\n {/* Header + Filter */}\n <div className=\"rdb-header-panel\">\n <div className=\"rdb-header-top\">\n <div className=\"rdb-header-title-group\">\n <span className=\"rdb-h1\">{labels?.title ?? \"Dashboard\"}</span>\n {liveUpdateEnabled ? (\n <Badge status=\"success\">{labels?.liveUpdate ?? \"Live\"}</Badge>\n ) : null}\n </div>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => onRefresh()} title={labels?.refresh ?? \"Refresh\"}>\n <Icon name=\"RotateCcw\" size={16} />\n </Button>\n </div>\n\n {error ? (\n <div className=\"rdb-error-banner\">\n <span>{error}</span>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => onRefresh()}>\n {labels?.retry ?? \"Retry\"}\n </Button>\n </div>\n ) : null}\n\n <FilterPanel filters={filters} labels={labels}\n onFilterChange={onFilterChange} onResetFilters={onResetFilters} />\n </div>\n\n {/* Stat Cards */}\n <div className=\"rdb-stats-grid\">\n {loading\n ? Array.from({ length: config.widgets.stats.length || 4 }).map((_, i) => (\n <SkeletonLoader key={i} style={{ height: 112 }} />\n ))\n : config.widgets.stats.map(widget => (\n <StatCard key={widget.id}\n label={labels?.[widget.label] ?? widget.label}\n value={data?.stats?.[widget.valueKey] ?? 0}\n icon={widget.icon}\n format={widget.format}\n accentColor={widget.accentColor}\n />\n ))}\n </div>\n\n {/* Chart Cards */}\n <div className=\"rdb-charts-grid\">\n {config.widgets.charts.map(widget => (\n <ChartCard key={widget.id} widget={widget} labels={labels ?? {}}\n loading={loading} filters={filters ?? {}} chartData={data?.charts ?? {}} />\n ))}\n </div>\n\n {/* Data Table */}\n <div className=\"rdb-card\" style={{ padding: 16 }}>\n <div style={{ display:\"flex\", alignItems:\"center\", gap:8, marginBottom:12 }}\n className=\"rdb-h3\">\n <Icon name={config.widgets.table.icon ?? \"Calendar\"} size={18} />\n {labels?.[config.widgets.table.label] ?? config.widgets.table.label}\n </div>\n {loading ? (\n <SkeletonLoader style={{ height: 192 }} />\n ) : (\n <DataTable\n columns={config.widgets.table.columns}\n data={data?.table?.recentBookings ?? []}\n labels={labels ?? {}}\n dateLocale={dateLocale ?? \"id-ID\"}\n emptyLabel={labels?.[config.widgets.table.emptyLabel] ?? config.widgets.table.emptyLabel}\n searchable={true}\n sortable={true}\n pageSize={10}\n />\n )}\n </div>\n\n </div>\n </div>\n );\n}\n\nReusableDashboardView.propTypes = {\n config: PropTypes.object.isRequired,\n labels: PropTypes.object.isRequired,\n loading: PropTypes.bool,\n error: PropTypes.string,\n filters: PropTypes.object,\n onFilterChange: PropTypes.func.isRequired,\n onResetFilters: PropTypes.func.isRequired,\n onRefresh: PropTypes.func.isRequired,\n data: PropTypes.object,\n dateLocale: PropTypes.string,\n liveUpdateEnabled: PropTypes.bool,\n /** Supabase client — aktifkan fitur baca tabel di wizard */\n supabase: PropTypes.object,\n /** Hasil createDashboardConfig() — untuk validasi otomatis wizard */\n dashboardConfig: PropTypes.object,\n};\n","import React, { useState, useEffect, useCallback } from \"react\";\r\nimport PropTypes from \"prop-types\";\r\nimport \"./dashboard.css\";\r\n\r\n// ─── Konstanta kolom standar preset ──────────────────────────────────\r\nconst PRESET_SIGNATURES = {\r\n cidika: {\r\n name: \"Cidika Travel\",\r\n tables: [\"bookings\", \"packages\", \"package_locales\"],\r\n },\r\n tokoSepatu: {\r\n name: \"Toko Sepatu / E-Commerce\",\r\n tables: [\"orders\", \"products\", \"customers\"],\r\n },\r\n};\r\n\r\nfunction detectPreset(tables) {\r\n if (!tables || tables.length === 0) return null;\r\n const tSet = new Set(tables);\r\n if (PRESET_SIGNATURES.cidika.tables.every(t => tSet.has(t))) return \"cidika\";\r\n if (PRESET_SIGNATURES.tokoSepatu.tables.every(t => tSet.has(t))) return \"tokoSepatu\";\r\n return null;\r\n}\r\n\r\n// ─── Code Generator ───────────────────────────────────────────────────\r\n// Menerima mapping yang dipilih user dan menghasilkan kode siap pakai\r\nfunction generateCode(mapping) {\r\n const {\r\n tableName,\r\n colDate, colStatus, colTotal, colCustomer, colItem,\r\n dashTitle, confirmedValue, pendingValue,\r\n } = mapping;\r\n\r\n const safeTitle = dashTitle || \"Dashboard\";\r\n const confirmed = confirmedValue || \"confirmed\";\r\n const pending = pendingValue || \"pending\";\r\n const safeCustomer = colCustomer || \"customer_name\";\r\n const safeItem = colItem || \"-\";\r\n const colTotalFull = colTotal || \"total\";\r\n\r\n const dataSource = `// src/datasources/myDashboardSource.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n// Tabel: ${tableName}\r\n\r\nexport function createMyDashboardSource(supabase) {\r\n return {\r\n async fetchDashboardSnapshot({ fromISO, toISO, statusScope }) {\r\n const allQuery = supabase\r\n .from(\"${tableName}\")\r\n .select(\"id, ${colDate}, ${colStatus}, ${colTotalFull}${colCustomer !== \"customer_name\" ? `, ${colCustomer}` : \", customer_name\"}${colItem !== \"-\" ? `, ${colItem}` : \"\"}\")\r\n .gte(\"${colDate}\", fromISO)\r\n .lte(\"${colDate}\", toISO)\r\n .order(\"${colDate}\", { ascending: true });\r\n\r\n const recentQuery = supabase\r\n .from(\"${tableName}\")\r\n .select(\"id, ${colDate}, ${colStatus}, ${colTotalFull}${colCustomer !== \"customer_name\" ? `, ${colCustomer}` : \", customer_name\"}${colItem !== \"-\" ? `, ${colItem}` : \"\"}\")\r\n .gte(\"${colDate}\", fromISO)\r\n .lte(\"${colDate}\", toISO)\r\n .order(\"${colDate}\", { ascending: false })\r\n .limit(10);\r\n\r\n if (statusScope && statusScope !== \"all\") {\r\n recentQuery.eq(\"${colStatus}\", statusScope);\r\n }\r\n\r\n const [allRes, recentRes] = await Promise.all([allQuery, recentQuery]);\r\n\r\n return {\r\n bookings: allRes.data || [], // semua transaksi (untuk chart & stats)\r\n recent: recentRes.data || [], // 10 terbaru (untuk tabel)\r\n packageLocales: [],\r\n staticCounts: { packages: 0, sections: 0 },\r\n };\r\n },\r\n\r\n subscribeLiveUpdate(onEvent) {\r\n const ch = supabase\r\n .channel(\"rdb-dashboard-live\")\r\n .on(\"postgres_changes\", { event: \"*\", schema: \"public\", table: \"${tableName}\" }, onEvent)\r\n .subscribe();\r\n return () => supabase.removeChannel(ch);\r\n },\r\n };\r\n}`;\r\n\r\n const adapter = `// src/adapters/myDashboardAdapter.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n// Mapping kolom: status=\"${colStatus}\", total=\"${colTotalFull}\", tanggal=\"${colDate}\"\r\n\r\nimport { toNumber, buildDayBuckets } from \"@rozaqi02/reusable-dashboard\";\r\n\r\nexport function createEmptyMyDashboardData() {\r\n return {\r\n stats: { bookingsConfirm: 0, revenueConfirm: 0 },\r\n charts: { dailyTrends: [], statusDistribution: [],\r\n audienceDistribution: [], topPackages: [] },\r\n table: { recentBookings: [] },\r\n };\r\n}\r\n\r\nexport function adaptMyDashboardData({ raw, range, dateLocale, labels }) {\r\n if (!raw) return createEmptyMyDashboardData();\r\n\r\n const buckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\r\n const dayMap = new Map(buckets.map(b => [b.dateKey, b]));\r\n const statusMap = new Map();\r\n let confirmed = 0, revenue = 0;\r\n\r\n (raw.bookings || []).forEach(row => {\r\n const status = String(row[\"${colStatus}\"] || \"pending\").toLowerCase();\r\n const amount = toNumber(row[\"${colTotalFull}\"]);\r\n const dayKey = String(row[\"${colDate}\"] || \"\").slice(0, 10);\r\n\r\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\r\n const bucket = dayMap.get(dayKey);\r\n if (bucket) {\r\n if (status === \"${confirmed}\") { bucket.count++; bucket.revenue += amount; }\r\n if (status === \"${pending}\") { bucket.pendingCount++; }\r\n }\r\n if (status === \"${confirmed}\") { confirmed++; revenue += amount; }\r\n });\r\n\r\n const avgRevenue = confirmed > 0 ? Math.round(revenue / confirmed) : 0;\r\n const totalTx = (raw.bookings || []).length;\r\n const conversionRate = totalTx > 0 ? Math.round((confirmed / totalTx) * 100) : 0;\r\n\r\n return {\r\n stats: {\r\n bookingsConfirm: confirmed,\r\n revenueConfirm: revenue,\r\n avgRevenue,\r\n conversionRate,\r\n },\r\n charts: {\r\n dailyTrends: buckets,\r\n statusDistribution: Array.from(statusMap.entries())\r\n .sort((a, b) => b[1] - a[1])\r\n .map(([status, count]) => ({\r\n status, count,\r\n label: labels?.formatStatusLabel?.(status) || status,\r\n })),\r\n audienceDistribution: [],\r\n topPackages: [],\r\n },\r\n table: {\r\n recentBookings: (raw.recent || []).map(row => ({\r\n id: row.id,\r\n createdAt: row[\"${colDate}\"],\r\n customerName: row[\"${colCustomer}\"] || \"-\",\r\n packageName: ${colItem !== \"-\" ? `row[\"${colItem}\"] || \"-\"` : '\"-\"'},\r\n audienceLabel: \"-\",\r\n totalIDR: toNumber(row[\"${colTotalFull}\"]),\r\n status: String(row[\"${colStatus}\"] || \"pending\").toLowerCase(),\r\n statusLabel: labels?.formatStatusLabel?.(row[\"${colStatus}\"]) || row[\"${colStatus}\"],\r\n })),\r\n },\r\n };\r\n}`;\r\n\r\n const widgetConfig = `// src/config/myDashboardConfig.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n\r\nexport const myDashboardConfig = {\r\n id: \"my.custom.dashboard\",\r\n defaultFilters: {\r\n statusScope: \"${confirmed}\",\r\n daysPreset: 30,\r\n sortPkgBy: \"bookings\",\r\n sortPkgDir: \"desc\",\r\n },\r\n widgets: {\r\n stats: [\r\n { id: \"orders\", label: \"confirmedBookings\", icon: \"TrendingUp\",\r\n valueKey: \"bookingsConfirm\", format: \"number\", accentColor: \"blue\" },\r\n { id: \"revenue\", label: \"confirmedRevenue\", icon: \"DollarSign\",\r\n valueKey: \"revenueConfirm\", format: \"currency\", accentColor: \"green\" },\r\n { id: \"avg\", label: \"avgRevenue\", icon: \"Users\",\r\n valueKey: \"avgRevenue\", format: \"currency\", accentColor: \"violet\" },\r\n { id: \"conversion\", label: \"conversionRate\", icon: \"PieChart\",\r\n valueKey: \"conversionRate\", format: \"percent\", accentColor: \"orange\" },\r\n ],\r\n charts: [\r\n { id: \"trend\", type: \"dailyArea\", label: \"dailyTrends\", icon: \"BarChart3\" },\r\n { id: \"status\", type: \"statusPie\", label: \"statusDistribution\", icon: \"PieChart\" },\r\n ],\r\n table: {\r\n id: \"recentTx\", label: \"recentBookings\", icon: \"Calendar\",\r\n emptyLabel: \"noRecentBookings\",\r\n columns: [\r\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\r\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },${colItem !== \"-\" ? `\r\n { id: \"item\", label: \"package\", accessor: \"packageName\" },` : \"\"}\r\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\r\n { id: \"status\", label: \"status\", accessor: \"statusLabel\",\r\n type: \"statusBadge\", statusAccessor: \"status\" },\r\n ],\r\n },\r\n },\r\n};`;\r\n\r\n const dashboard = `// src/pages/admin/Dashboard.jsx\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n// Salin file ini ke halaman dashboard kamu.\r\n\r\nimport React from \"react\";\r\nimport { supabase } from \"../../lib/supabaseClient.js\";\r\nimport {\r\n ReusableDashboardView,\r\n useReusableDashboard,\r\n createDashboardConfig,\r\n} from \"@rozaqi02/reusable-dashboard\";\r\n\r\n// Import 3 file yang digenerate wizard\r\nimport { myDashboardConfig } from \"./myDashboardConfig\";\r\nimport { createMyDashboardSource } from \"./myDashboardSource\";\r\nimport { adaptMyDashboardData, createEmptyMyDashboardData } from \"./myDashboardAdapter\";\r\n\r\n// Data source — dibuat sekali di luar komponen\r\nconst source = createMyDashboardSource(supabase);\r\n\r\n// Label UI — sesuaikan teks dengan bahasa/konteks bisnis kamu\r\nconst labels = {\r\n title: \"${safeTitle}\",\r\n refresh: \"Refresh\",\r\n liveUpdate: \"Live update\",\r\n loadFailed: \"Gagal memuat data.\",\r\n retry: \"Coba Lagi\",\r\n confirmedOnly: \"Selesai\",\r\n pendingOnly: \"Proses\",\r\n allStatus: \"Semua Status\",\r\n showPendingOverlay: \"Tampilkan pending\",\r\n reset: \"Reset\",\r\n confirmedBookings: \"Total Transaksi\",\r\n confirmedRevenue: \"Total Pendapatan\",\r\n avgRevenue: \"Rata-rata / Transaksi\",\r\n conversionRate: \"Conversion Rate\",\r\n dailyTrends: \"Tren Harian\",\r\n statusDistribution: \"Distribusi Status\",\r\n recentBookings: \"Transaksi Terbaru\",\r\n noRecentBookings: \"Belum ada transaksi\",\r\n date: \"Tanggal\",\r\n customer: \"Pelanggan\",\r\n package: \"Item\",\r\n total: \"Total\",\r\n status: \"Status\",\r\n bookingsMetric: \"Transaksi\",\r\n revenueMetric: \"Pendapatan\",\r\n confirmedBookingMetric: \"Transaksi (Selesai)\",\r\n confirmedRevenueMetric: \"Pendapatan (Selesai)\",\r\n dayLabel: n => n + \" hari\",\r\n formatStatusLabel: s =>\r\n ({ \"${confirmed}\": \"Selesai\", \"${pending}\": \"Proses\" })[s] || (s || \"-\"),\r\n formatAudienceLabel: v => v || \"-\",\r\n};\r\n\r\n// Kemas semua jadi 1 objek\r\nconst dashboardConfig = createDashboardConfig({\r\n widgetConfig: myDashboardConfig,\r\n dataSource: source,\r\n adapter: adaptMyDashboardData,\r\n createEmptyState: createEmptyMyDashboardData,\r\n languageCode: \"id\",\r\n dateLocale: \"id-ID\",\r\n labels,\r\n});\r\n\r\nexport default function Dashboard() {\r\n const state = useReusableDashboard({ ...dashboardConfig, labels });\r\n return (\r\n <ReusableDashboardView\r\n config={dashboardConfig.config}\r\n labels={labels}\r\n loading={state.loading}\r\n error={state.error}\r\n filters={state.filters}\r\n onFilterChange={state.updateFilter}\r\n onResetFilters={state.resetFilters}\r\n onRefresh={state.refresh}\r\n data={state.data}\r\n dateLocale={dashboardConfig.dateLocale}\r\n liveUpdateEnabled={state.liveUpdateEnabled}\r\n supabase={supabase}\r\n dashboardConfig={dashboardConfig}\r\n />\r\n );\r\n}`;\r\n\r\n return { dataSource, adapter, widgetConfig, dashboard };\r\n}\r\n\r\n// ─── Komponen utama ───────────────────────────────────────────────────\r\nexport function SetupWizard({ issues = [], onDismiss, supabase }) {\r\n const [dismissed, setDismissed] = useState(false);\r\n const [step, setStep] = useState(0);\r\n\r\n // Deteksi otomatis\r\n const [detecting, setDetecting] = useState(true);\r\n const [tables, setTables] = useState([]);\r\n const [columns, setColumns] = useState({}); // { tableName: [col1, col2, ...] }\r\n const [supabaseOk, setSupabaseOk] = useState(false);\r\n const [detectionDone, setDetectionDone] = useState(false);\r\n\r\n // Pertanyaan awal\r\n const [userHasDashboard, setUserHasDashboard] = useState(null);\r\n\r\n // Column mapping state\r\n const [selectedTable, setSelectedTable] = useState(\"\");\r\n const [colDate, setColDate] = useState(\"\");\r\n const [colStatus, setColStatus] = useState(\"\");\r\n const [colTotal, setColTotal] = useState(\"\");\r\n const [colCustomer, setColCustomer] = useState(\"\");\r\n const [colItem, setColItem] = useState(\"\");\r\n const [confirmedVal, setConfirmedVal] = useState(\"confirmed\");\r\n const [pendingVal, setPendingVal] = useState(\"pending\");\r\n const [dashTitle, setDashTitle] = useState(\"Dashboard\");\r\n const [loadingColumns, setLoadingColumns] = useState(false);\r\n\r\n // Generated code\r\n const [generatedCode, setGeneratedCode] = useState(null);\r\n const [activeCodeTab, setActiveCodeTab] = useState(\"dataSource\");\r\n const [copied, setCopied] = useState(\"\");\r\n\r\n // ── Deteksi Supabase & tabel saat mount ──────────────────────────\r\n useEffect(() => {\r\n if (!supabase) {\r\n setDetecting(false);\r\n setDetectionDone(true);\r\n return;\r\n }\r\n (async () => {\r\n try {\r\n // Strategi 1: coba RPC get_tables (jika sudah dibuat user)\r\n const { data: rpcData, error: rpcErr } = await supabase.rpc(\"rdb_get_tables\");\r\n if (!rpcErr && Array.isArray(rpcData)) {\r\n setTables(rpcData.map(r => typeof r === \"string\" ? r : (r.table_name || r.name || r)));\r\n setSupabaseOk(true);\r\n } else {\r\n // Strategi 2: coba information_schema via PostgREST\r\n const { data: schemaData, error: schemaErr } = await supabase\r\n .from(\"information_schema.tables\")\r\n .select(\"table_name\")\r\n .eq(\"table_schema\", \"public\")\r\n .eq(\"table_type\", \"BASE TABLE\")\r\n .order(\"table_name\");\r\n if (!schemaErr && schemaData) {\r\n setTables(schemaData.map(r => r.table_name));\r\n setSupabaseOk(true);\r\n } else {\r\n // Strategi 3: Supabase tersambung tapi tidak bisa baca schema\r\n // Cek koneksi saja dengan ping table yang tidak ada\r\n const { error: pingErr } = await supabase\r\n .from(\"_rdb_ping_\").select(\"*\").limit(1);\r\n // Kode 42P01 = table does not exist = koneksi OK tapi tabel tidak ada\r\n // PGRST116 = same thing via PostgREST\r\n const connected = !pingErr\r\n || pingErr.code === \"42P01\"\r\n || pingErr.code === \"PGRST116\"\r\n || (pingErr.message || \"\").includes(\"does not exist\");\r\n setSupabaseOk(connected);\r\n // Tabel harus diisi manual\r\n setTables([]);\r\n }\r\n }\r\n } catch {\r\n setSupabaseOk(false);\r\n } finally {\r\n setDetecting(false);\r\n setDetectionDone(true);\r\n }\r\n })();\r\n }, [supabase]);\r\n\r\n // ── Baca kolom saat tabel dipilih ────────────────────────────────\r\n const loadColumns = useCallback(async (tbl) => {\r\n if (!supabase || !tbl || columns[tbl]) return;\r\n setLoadingColumns(true);\r\n try {\r\n // Strategi 1: RPC rdb_get_columns\r\n const { data: rpcCols, error: rpcErr } = await supabase\r\n .rpc(\"rdb_get_columns\", { p_table: tbl });\r\n if (!rpcErr && Array.isArray(rpcCols)) {\r\n const colObjs = rpcCols.map(c =>\r\n typeof c === \"string\"\r\n ? { column_name: c, data_type: \"unknown\" }\r\n : { column_name: c.column_name || c.name || c, data_type: c.data_type || \"unknown\" }\r\n );\r\n setColumns(prev => ({ ...prev, [tbl]: colObjs }));\r\n autoDetectCols(colObjs);\r\n return;\r\n }\r\n\r\n // Strategi 2: information_schema.columns\r\n const { data: schemaCols, error: schemaErr } = await supabase\r\n .from(\"information_schema.columns\")\r\n .select(\"column_name, data_type\")\r\n .eq(\"table_schema\", \"public\")\r\n .eq(\"table_name\", tbl)\r\n .order(\"ordinal_position\");\r\n if (!schemaErr && schemaCols) {\r\n setColumns(prev => ({ ...prev, [tbl]: schemaCols }));\r\n autoDetectCols(schemaCols);\r\n return;\r\n }\r\n\r\n // Strategi 3: ambil 1 baris dan baca key-nya\r\n const { data: sampleRow, error: sampleErr } = await supabase\r\n .from(tbl).select(\"*\").limit(1);\r\n if (!sampleErr && sampleRow && sampleRow.length > 0) {\r\n const colObjs = Object.keys(sampleRow[0]).map(k => ({\r\n column_name: k,\r\n data_type: typeof sampleRow[0][k],\r\n }));\r\n setColumns(prev => ({ ...prev, [tbl]: colObjs }));\r\n autoDetectCols(colObjs);\r\n return;\r\n }\r\n\r\n // Strategi 4: tabel ada tapi kosong — ambil kolom dari error meta\r\n // Tidak ada cara lain tanpa RPC — beri tahu user\r\n setColumns(prev => ({ ...prev, [tbl]: [] }));\r\n } catch {\r\n setColumns(prev => ({ ...prev, [tbl]: [] }));\r\n } finally {\r\n setLoadingColumns(false);\r\n }\r\n }, [supabase, columns]);\r\n\r\n function autoDetectCols(colObjs) {\r\n const find = (candidates) =>\r\n colObjs.find(c => candidates.includes(c.column_name.toLowerCase()))?.column_name || \"\";\r\n setColDate(find([\"created_at\",\"tanggal\",\"date\",\"transaction_date\",\"order_date\",\"waktu\"]));\r\n setColStatus(find([\"status\",\"state\",\"kondisi\",\"order_status\",\"payment_status\"]));\r\n setColTotal(find([\"total\",\"total_idr\",\"total_amount\",\"total_price\",\"harga_total\",\"amount\",\"nominal\",\"harga\",\"biaya\"]));\r\n setColCustomer(find([\"customer_name\",\"nama_pelanggan\",\"nama\",\"name\",\"client_name\",\"buyer_name\",\"pelanggan\"]));\r\n setColItem(find([\"service_type\",\"item_name\",\"product_name\",\"package_name\",\"layanan\",\"produk\",\"nama_layanan\",\"jenis\",\"nama_produk\"]));\r\n }\r\n\r\n // ── Copy to clipboard ─────────────────────────────────────────────\r\n function copyCode(text, label) {\r\n navigator.clipboard.writeText(text).then(() => {\r\n setCopied(label);\r\n setTimeout(() => setCopied(\"\"), 2000);\r\n });\r\n }\r\n\r\n function handleDismiss() {\r\n setDismissed(true);\r\n if (onDismiss) onDismiss();\r\n }\r\n\r\n // ── Generate kode ─────────────────────────────────────────────────\r\n function handleGenerate() {\r\n if (!selectedTable || !colDate || !colStatus || !colTotal) return;\r\n const code = generateCode({\r\n tableName: selectedTable,\r\n colDate, colStatus, colTotal,\r\n colCustomer: colCustomer || \"customer_name\",\r\n colItem: colItem || \"-\",\r\n dashTitle, confirmedValue: confirmedVal, pendingValue: pendingVal,\r\n });\r\n setGeneratedCode(code);\r\n setStep(3);\r\n }\r\n\r\n if (dismissed) return null;\r\n\r\n const detectedPreset = detectPreset(tables);\r\n const tableColumns = selectedTable ? (columns[selectedTable] || []) : [];\r\n const colNames = tableColumns.map(c => c.column_name);\r\n\r\n // Validasi mapping lengkap\r\n const mappingValid = selectedTable && colDate && colStatus && colTotal;\r\n\r\n // ── Step labels ────────────────────────────────────────────────────\r\n const stepLabels = [\"Deteksi\", \"Pilih Tabel\", \"Mapping Kolom\", \"Kode Siap Pakai\"];\r\n\r\n return (\r\n <div className=\"rdb-wizard-overlay\" role=\"dialog\" aria-modal=\"true\"\r\n aria-label=\"Setup Wizard @rozaqi02/reusable-dashboard\">\r\n <div className=\"rdb-wizard-modal\">\r\n\r\n {/* ── Header ─────────────────────────────────────────────── */}\r\n <div className=\"rdb-wizard-header\">\r\n <div className=\"rdb-wizard-header-title\">\r\n <span className=\"rdb-wizard-logo\">🛠️</span>\r\n <div>\r\n <div className=\"rdb-h2\" style={{ margin: 0 }}>Setup Dashboard</div>\r\n <div className=\"rdb-caption\">\r\n {detecting\r\n ? \"Mendeteksi kondisi project…\"\r\n : supabaseOk\r\n ? `Supabase tersambung · ${tables.length} tabel ditemukan`\r\n : \"Panduan konfigurasi @rozaqi02/reusable-dashboard\"}\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"button\" className=\"rdb-wizard-close\"\r\n onClick={handleDismiss} title=\"Tutup\">✕</button>\r\n </div>\r\n\r\n {/* ── Step Nav ───────────────────────────────────────────── */}\r\n <div className=\"rdb-wizard-steps\">\r\n {stepLabels.map((label, i) => (\r\n <button key={i} type=\"button\"\r\n className={`rdb-wizard-step-btn ${step === i ? \"rdb-wizard-step-active\" : \"\"}`}\r\n onClick={() => { if (i < step || (i === step + 1 && step < 2)) setStep(i); }}>\r\n <span>{step > i ? \"✅\" : i + 1}.</span>\r\n <span>{label}</span>\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* ── Body ───────────────────────────────────────────────── */}\r\n <div className=\"rdb-wizard-body\">\r\n <div className=\"rdb-wizard-section\">\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 0 — DETEKSI OTOMATIS\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 0 && (\r\n <>\r\n {issues.length > 0 && (\r\n <div className=\"rdb-wizard-issues\" style={{ marginBottom: 12 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight: 600, marginBottom: 6 }}>\r\n Konfigurasi belum lengkap:\r\n </div>\r\n {issues.map((iss, i) => (\r\n <div key={i} className=\"rdb-wizard-issue-item\">\r\n <span>❌</span><span className=\"rdb-body\">{iss}</span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className=\"rdb-wizard-flow\" style={{ marginBottom: 12 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight: 600, marginBottom: 10 }}>\r\n 🔍 Hasil deteksi otomatis:\r\n </div>\r\n {detecting ? (\r\n <div className=\"rdb-body\" style={{ color: \"var(--rdb-text-muted)\" }}>\r\n Mendeteksi…\r\n </div>\r\n ) : (\r\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span>{supabaseOk ? \"✅\" : \"❌\"}</span>\r\n <span className=\"rdb-body\">\r\n Supabase {supabaseOk ? \"tersambung\" : \"tidak tersambung — pastikan supabaseClient.js sudah dikonfigurasi dan prop supabase dikirim ke ReusableDashboardView\"}\r\n </span>\r\n </div>\r\n {supabaseOk && (\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span>{tables.length > 0 ? \"✅\" : \"⚠️\"}</span>\r\n <span className=\"rdb-body\">\r\n {tables.length > 0\r\n ? `${tables.length} tabel public ditemukan`\r\n : \"Daftar tabel tidak bisa dibaca otomatis (RLS aktif) — kamu bisa ketik nama tabel di step berikutnya\"}\r\n </span>\r\n </div>\r\n )}\r\n {supabaseOk && tables.length > 0 && detectedPreset && (\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span>✅</span>\r\n <span className=\"rdb-body\">\r\n Tabel cocok dengan preset <strong>{PRESET_SIGNATURES[detectedPreset].name}</strong>\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {!supabaseOk && detectionDone && (\r\n <div className=\"rdb-wizard-alert\" style={{ marginBottom: 12 }}>\r\n <span className=\"rdb-wizard-alert-icon\">ℹ️</span>\r\n <div>\r\n <div className=\"rdb-body\" style={{ fontWeight: 600 }}>Aktifkan koneksi Supabase</div>\r\n <div className=\"rdb-caption\" style={{ marginTop: 4 }}>\r\n Tambahkan prop ke ReusableDashboardView:{\" \"}\r\n <code className=\"rdb-wizard-code-inline\">supabase={\"{supabase}\"}</code>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={handleDismiss}>Lanjutkan tanpa wizard</button>\r\n {supabaseOk && (\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n onClick={() => setStep(1)}>\r\n Lanjut → Pilih Tabel\r\n </button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 1 — PILIH TABEL\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 1 && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">2</span>\r\n <span className=\"rdb-h3\" style={{ margin: 0 }}>Pilih Tabel Transaksi</span>\r\n </div>\r\n <div className=\"rdb-body\" style={{ color: \"var(--rdb-text-muted)\", marginBottom: 16 }}>\r\n Pilih tabel yang berisi data transaksi bisnis kamu.\r\n </div>\r\n\r\n {/* Tabel terbaca otomatis */}\r\n {tables.length > 0 && (\r\n <>\r\n <div className=\"rdb-caption\" style={{ fontWeight: 600, marginBottom: 8 }}>\r\n Tabel yang ditemukan:\r\n </div>\r\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6, marginBottom: 16 }}>\r\n {tables.map(tbl => (\r\n <button key={tbl} type=\"button\"\r\n onClick={() => {\r\n setSelectedTable(tbl);\r\n loadColumns(tbl);\r\n }}\r\n className={`rdb-btn rdb-btn-sm ${selectedTable === tbl ? \"rdb-btn-primary\" : \"rdb-btn-secondary\"}`}\r\n style={{ justifyContent: \"flex-start\", fontFamily: \"monospace\" }}>\r\n {selectedTable === tbl ? \"✅ \" : \"○ \"}{tbl}\r\n </button>\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* Input manual jika tabel tidak terbaca otomatis */}\r\n {tables.length === 0 && (\r\n <div style={{ marginBottom: 16 }}>\r\n <div className=\"rdb-wizard-alert\" style={{ marginBottom: 12 }}>\r\n <span className=\"rdb-wizard-alert-icon\">ℹ️</span>\r\n <div>\r\n <div className=\"rdb-body\" style={{ fontWeight: 600 }}>\r\n Daftar tabel tidak bisa terbaca otomatis\r\n </div>\r\n <div className=\"rdb-caption\" style={{ marginTop: 4 }}>\r\n Ini normal — Supabase memblokir akses ke <code>information_schema</code> via API publik.\r\n Ketik nama tabel secara manual di bawah.\r\n </div>\r\n </div>\r\n </div>\r\n <label className=\"rdb-label\">Nama tabel transaksi kamu</label>\r\n <div style={{ display: \"flex\", gap: 8 }}>\r\n <input className=\"rdb-input\" value={selectedTable}\r\n onChange={e => setSelectedTable(e.target.value)}\r\n placeholder=\"cth: orders, transaksi, bookings, penjualan\"\r\n style={{ maxWidth: 320 }} />\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n disabled={!selectedTable || loadingColumns}\r\n onClick={() => loadColumns(selectedTable)}>\r\n {loadingColumns ? \"Membaca…\" : \"Baca kolom\"}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Input manual tambahan meski tabel sudah terdeteksi */}\r\n {tables.length > 0 && !selectedTable && (\r\n <div className=\"rdb-caption\" style={{ color: \"var(--rdb-text-muted)\", marginBottom: 12 }}>\r\n Atau ketik nama tabel secara manual:\r\n <input className=\"rdb-input\" style={{ marginTop: 6, maxWidth: 280 }}\r\n placeholder=\"nama tabel lain\"\r\n onChange={e => {\r\n setSelectedTable(e.target.value);\r\n if (e.target.value) loadColumns(e.target.value);\r\n }} />\r\n </div>\r\n )}\r\n\r\n {selectedTable && (\r\n <div className=\"rdb-wizard-tip\" style={{ marginBottom: 12 }}>\r\n Tabel <strong>{selectedTable}</strong> dipilih.\r\n {loadingColumns\r\n ? \" Membaca kolom…\"\r\n : tableColumns.length > 0\r\n ? ` ${tableColumns.length} kolom ditemukan — kolom sudah ter-auto-detect di step berikutnya.`\r\n : tableColumns.length === 0 && !loadingColumns && columns[selectedTable] !== undefined\r\n ? \" Tabel kosong atau tidak ada kolom terbaca — kamu bisa ketik nama kolom manual di step berikutnya.\"\r\n : \"\"}\r\n </div>\r\n )}\r\n\r\n <div style={{ marginBottom: 12 }}>\r\n <label className=\"rdb-label\">Judul dashboard (opsional)</label>\r\n <input className=\"rdb-input\" value={dashTitle} style={{ maxWidth: 280 }}\r\n onChange={e => setDashTitle(e.target.value)}\r\n placeholder=\"cth: Dashboard Laundry Bersih\" />\r\n </div>\r\n\r\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(0)}>← Kembali</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n disabled={!selectedTable || loadingColumns}\r\n onClick={() => setStep(2)}>\r\n Lanjut → Mapping Kolom\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 2 — MAPPING KOLOM\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 2 && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">3</span>\r\n <span className=\"rdb-h3\" style={{ margin: 0 }}>\r\n Mapping Kolom — Tabel: <code style={{ fontSize: \"0.9rem\" }}>{selectedTable}</code>\r\n </span>\r\n </div>\r\n <div className=\"rdb-body\" style={{ color: \"var(--rdb-text-muted)\", marginBottom: 16 }}>\r\n Pilih kolom yang berperan sebagai masing-masing data.\r\n Kolom sudah ter-deteksi otomatis — cukup verifikasi dan sesuaikan jika perlu.\r\n </div>\r\n\r\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: 12, marginBottom: 16 }}>\r\n {/* Tanggal */}\r\n <div>\r\n <label className=\"rdb-label\">\r\n Kolom Tanggal <span style={{ color: \"red\" }}>*</span>\r\n </label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={colDate}\r\n onChange={e => setColDate(e.target.value)}>\r\n <option value=\"\">— pilih kolom —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={colDate}\r\n onChange={e => setColDate(e.target.value)}\r\n placeholder=\"cth: created_at\" />\r\n )}\r\n <div className=\"rdb-caption\" style={{ marginTop: 2 }}>Tipe timestamp/date</div>\r\n </div>\r\n\r\n {/* Status */}\r\n <div>\r\n <label className=\"rdb-label\">\r\n Kolom Status <span style={{ color: \"red\" }}>*</span>\r\n </label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={colStatus}\r\n onChange={e => setColStatus(e.target.value)}>\r\n <option value=\"\">— pilih kolom —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={colStatus}\r\n onChange={e => setColStatus(e.target.value)}\r\n placeholder=\"cth: status\" />\r\n )}\r\n <div className=\"rdb-caption\" style={{ marginTop: 2 }}>Nilai selesai/pending</div>\r\n </div>\r\n\r\n {/* Total */}\r\n <div>\r\n <label className=\"rdb-label\">\r\n Kolom Total (uang) <span style={{ color: \"red\" }}>*</span>\r\n </label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={colTotal}\r\n onChange={e => setColTotal(e.target.value)}>\r\n <option value=\"\">— pilih kolom —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={colTotal}\r\n onChange={e => setColTotal(e.target.value)}\r\n placeholder=\"cth: total_amount\" />\r\n )}\r\n <div className=\"rdb-caption\" style={{ marginTop: 2 }}>Integer Rupiah</div>\r\n </div>\r\n\r\n {/* Customer */}\r\n <div>\r\n <label className=\"rdb-label\">Kolom Nama Pelanggan</label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={colCustomer}\r\n onChange={e => setColCustomer(e.target.value)}>\r\n <option value=\"\">— opsional —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={colCustomer}\r\n onChange={e => setColCustomer(e.target.value)}\r\n placeholder=\"cth: customer_name (opsional)\" />\r\n )}\r\n </div>\r\n\r\n {/* Item */}\r\n <div>\r\n <label className=\"rdb-label\">Kolom Nama Item/Layanan</label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={colItem}\r\n onChange={e => setColItem(e.target.value)}>\r\n <option value=\"\">— opsional —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={colItem}\r\n onChange={e => setColItem(e.target.value)}\r\n placeholder=\"cth: service_type (opsional)\" />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Nilai status */}\r\n <div className=\"rdb-wizard-flow\" style={{ marginBottom: 16 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight: 600, marginBottom: 8 }}>\r\n Nilai status di tabel kamu:\r\n </div>\r\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: 12 }}>\r\n <div>\r\n <label className=\"rdb-label\">Nilai \"Selesai/Confirmed\"</label>\r\n <input className=\"rdb-input\" value={confirmedVal}\r\n onChange={e => setConfirmedVal(e.target.value)}\r\n placeholder=\"cth: confirmed, selesai, lunas\" />\r\n </div>\r\n <div>\r\n <label className=\"rdb-label\">Nilai \"Pending/Proses\"</label>\r\n <input className=\"rdb-input\" value={pendingVal}\r\n onChange={e => setPendingVal(e.target.value)}\r\n placeholder=\"cth: pending, proses, menunggu\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {!mappingValid && (\r\n <div className=\"rdb-error-banner\" style={{ marginBottom: 12 }}>\r\n Pilih minimal kolom Tanggal, Status, dan Total untuk generate kode.\r\n </div>\r\n )}\r\n\r\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(1)}>← Kembali</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n disabled={!mappingValid}\r\n onClick={handleGenerate}>\r\n ✨ Generate Kode →\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 3 — KODE SIAP PAKAI\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 3 && generatedCode && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">✅</span>\r\n <span className=\"rdb-h3\" style={{ margin: 0 }}>Kode Siap Pakai</span>\r\n </div>\r\n <div className=\"rdb-wizard-tip\" style={{ marginBottom: 16 }}>\r\n <strong>4 file sudah digenerate.</strong> Salin masing-masing ke project kamu.\r\n Tidak perlu memahami logika di dalamnya — cukup save dan jalankan.\r\n </div>\r\n\r\n {/* Instruksi singkat */}\r\n <div className=\"rdb-wizard-issues\" style={{ marginBottom: 16 }}>\r\n {[\r\n [\"myDashboardSource.js\", \"src/datasources/\", \"File koneksi ke Supabase\"],\r\n [\"myDashboardAdapter.js\", \"src/adapters/\", \"Transformasi data → format dashboard\"],\r\n [\"myDashboardConfig.js\", \"src/config/ (atau langsung di Dashboard.jsx)\", \"Konfigurasi widget\"],\r\n [\"Dashboard.jsx\", \"src/pages/admin/\", \"Ganti halaman dashboard lama\"],\r\n ].map(([file, path, desc], i) => (\r\n <div key={i} className=\"rdb-wizard-issue-item\">\r\n <span style={{ color: \"var(--rdb-blue-500)\", fontWeight: 700 }}>{i + 1}.</span>\r\n <span className=\"rdb-body\">\r\n Simpan <code className=\"rdb-wizard-code-inline\">{file}</code> ke{\" \"}\r\n <code className=\"rdb-wizard-code-inline\">{path}</code> — {desc}\r\n </span>\r\n </div>\r\n ))}\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span style={{ color: \"var(--rdb-blue-500)\", fontWeight: 700 }}>5.</span>\r\n <span className=\"rdb-body\">\r\n Import CSS di <code className=\"rdb-wizard-code-inline\">src/index.css</code>:{\" \"}\r\n <code className=\"rdb-wizard-code-inline\">\r\n @import \"../node_modules/@rozaqi02/reusable-dashboard/dist/index.css\";\r\n </code>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Tab selector */}\r\n <div style={{ display: \"flex\", gap: 4, marginBottom: 8, flexWrap: \"wrap\" }}>\r\n {[\r\n [\"dataSource\", \"myDashboardSource.js\"],\r\n [\"adapter\", \"myDashboardAdapter.js\"],\r\n [\"widgetConfig\",\"myDashboardConfig.js\"],\r\n [\"dashboard\", \"Dashboard.jsx\"],\r\n ].map(([key, label]) => (\r\n <button key={key} type=\"button\"\r\n onClick={() => setActiveCodeTab(key)}\r\n className={`rdb-btn rdb-btn-sm ${activeCodeTab === key ? \"rdb-btn-primary\" : \"rdb-btn-secondary\"}`}\r\n style={{ fontFamily: \"monospace\", fontSize: \"0.75rem\" }}>\r\n {label}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Kode + tombol copy */}\r\n <div style={{ position: \"relative\" }}>\r\n <button type=\"button\"\r\n onClick={() => copyCode(generatedCode[activeCodeTab], activeCodeTab)}\r\n className=\"rdb-btn rdb-btn-sm rdb-btn-secondary\"\r\n style={{ position: \"absolute\", top: 8, right: 8, zIndex: 1 }}>\r\n {copied === activeCodeTab ? \"✅ Disalin!\" : \"📋 Salin\"}\r\n </button>\r\n <pre className=\"rdb-wizard-code\" style={{ maxHeight: 320, overflow: \"auto\" }}>\r\n {generatedCode[activeCodeTab]}\r\n </pre>\r\n </div>\r\n\r\n <div className=\"rdb-wizard-tip\" style={{ marginTop: 12 }}>\r\n Setelah semua file tersimpan dan dev server direstart, wizard tidak akan muncul lagi.\r\n </div>\r\n\r\n <div style={{ display: \"flex\", gap: 8, justifyContent: \"flex-end\", marginTop: 12 }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(2)}>← Edit mapping</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n onClick={handleDismiss}>\r\n Tutup wizard ✓\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nSetupWizard.propTypes = {\r\n issues: PropTypes.arrayOf(PropTypes.string),\r\n onDismiss: PropTypes.func,\r\n supabase: PropTypes.object,\r\n};\r\n","export function createDashboardLabels(t) {\n const labels = {\n title: t(\"admin.dashboard.title\", { defaultValue: \"Dashboard\" }),\n refresh: t(\"admin.dashboard.refresh\", { defaultValue: \"Refresh\" }),\n liveUpdate: t(\"admin.dashboard.liveUpdate\", { defaultValue: \"Live update\" }),\n loadFailed: t(\"admin.dashboard.loadFailed\", {\n defaultValue: \"Failed to load dashboard data.\",\n }),\n retry: t(\"admin.dashboard.retry\", { defaultValue: \"Retry\" }),\n confirmedOnly: t(\"admin.dashboard.filters.confirmedOnly\", {\n defaultValue: \"Confirmed only\",\n }),\n pendingOnly: t(\"admin.dashboard.filters.pendingOnly\", {\n defaultValue: \"Pending only\",\n }),\n allStatus: t(\"admin.dashboard.filters.allStatus\", {\n defaultValue: \"All status\",\n }),\n showPendingOverlay: t(\"admin.dashboard.filters.showPendingOverlay\", {\n defaultValue: \"Show pending overlay\",\n }),\n allAudience: t(\"admin.dashboard.filters.allAudience\", {\n defaultValue: \"All audience\",\n }),\n audienceDomestic: t(\"explore.domestic\", { defaultValue: \"Domestic\" }),\n audienceForeign: t(\"explore.foreign\", { defaultValue: \"Foreign\" }),\n customDate: t(\"admin.dashboard.filters.customDate\", {\n defaultValue: \"Custom\",\n }),\n reset: t(\"admin.dashboard.filters.reset\", { defaultValue: \"Reset\" }),\n topSort: t(\"admin.dashboard.filters.topSort\", {\n defaultValue: \"Top packages sort\",\n }),\n sortBookings: t(\"admin.dashboard.filters.sortBookings\", {\n defaultValue: \"Bookings\",\n }),\n sortRevenue: t(\"admin.dashboard.filters.sortRevenue\", {\n defaultValue: \"Revenue\",\n }),\n sortDesc: t(\"admin.dashboard.filters.sortDesc\", { defaultValue: \"Desc\" }),\n sortAsc: t(\"admin.dashboard.filters.sortAsc\", { defaultValue: \"Asc\" }),\n confirmedBookings: t(\"admin.dashboard.cards.confirmedBookings\", {\n defaultValue: \"Confirmed Bookings\",\n }),\n confirmedRevenue: t(\"admin.dashboard.cards.confirmedRevenue\", {\n defaultValue: \"Revenue (Confirmed)\",\n }),\n avgRevenue: t(\"admin.dashboard.cards.avgRevenue\", {\n defaultValue: \"Avg Revenue / Booking\",\n }),\n conversionRate: t(\"admin.dashboard.cards.conversionRate\", {\n defaultValue: \"Conversion Rate\",\n }),\n totalProducts: t(\"admin.dashboard.cards.totalProducts\", {\n defaultValue: \"Total Products\",\n }),\n totalCustomers: t(\"admin.dashboard.cards.totalCustomers\", {\n defaultValue: \"Total Customers\",\n }),\n dailyTrends: t(\"admin.dashboard.sections.dailyTrends\", {\n defaultValue: \"Daily Trends\",\n }),\n statusDistribution: t(\"admin.dashboard.sections.statusDistribution\", {\n defaultValue: \"Status Distribution\",\n }),\n audienceDistribution: t(\"admin.dashboard.sections.audienceDistribution\", {\n defaultValue: \"Audience Distribution\",\n }),\n topPackages: t(\"admin.dashboard.sections.topPackages\", {\n defaultValue: \"Top Packages\",\n }),\n recentBookings: t(\"admin.dashboard.sections.recentBookings\", {\n defaultValue: \"Recent Bookings\",\n }),\n date: t(\"admin.dashboard.table.date\", { defaultValue: \"Date\" }),\n customer: t(\"admin.dashboard.table.customer\", { defaultValue: \"Customer\" }),\n package: t(\"admin.dashboard.table.package\", { defaultValue: \"Package\" }),\n audience: t(\"admin.dashboard.table.audience\", { defaultValue: \"Audience\" }),\n total: t(\"admin.dashboard.table.total\", { defaultValue: \"Total\" }),\n status: t(\"admin.dashboard.table.status\", { defaultValue: \"Status\" }),\n noRecentBookings: t(\"admin.dashboard.emptyRecent\", {\n defaultValue: \"No recent bookings\",\n }),\n bookingsMetric: t(\"admin.dashboard.metrics.bookings\", {\n defaultValue: \"Bookings\",\n }),\n revenueMetric: t(\"admin.dashboard.metrics.revenue\", {\n defaultValue: \"Revenue\",\n }),\n pendingMetric: t(\"admin.dashboard.metrics.pendingBookings\", {\n defaultValue: \"Bookings (Pending)\",\n }),\n confirmedBookingMetric: t(\"admin.dashboard.metrics.confirmedBookings\", {\n defaultValue: \"Bookings (Confirmed)\",\n }),\n confirmedRevenueMetric: t(\"admin.dashboard.metrics.confirmedRevenue\", {\n defaultValue: \"Revenue (Confirmed)\",\n }),\n unknownAudience: t(\"admin.dashboard.filters.unknownAudience\", {\n defaultValue: \"Unknown\",\n }),\n };\n\n labels.dayLabel = (count) =>\n t(\"admin.dashboard.filters.dayWindow\", {\n count,\n defaultValue: \"{{count}} days\",\n });\n\n labels.formatStatusLabel = (status) => {\n const normalized = String(status || \"pending\").toLowerCase();\n const defaultValue =\n normalized.charAt(0).toUpperCase() + normalized.slice(1);\n\n return t(`admin.dashboard.status.${normalized}`, { defaultValue });\n };\n\n labels.formatAudienceLabel = (value) => {\n if (value === \"domestic\") return labels.audienceDomestic;\n if (value === \"foreign\") return labels.audienceForeign;\n return labels.unknownAudience;\n };\n\n return labels;\n}\n"],"mappings":"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","names":["ensureNoError","import_react","import_react","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","MIN_YEAR","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","import_react","import_prop_types","React","PropTypes","React","_a","issues","PropTypes"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js","../src/config/cidikaWidgetConfig.js","../src/config/dummyUmkmWidgetConfig.js","../src/config/tokoSepatuWidgetConfig.js","../src/config/createDashboardConfig.js","../src/utils/formatters.js","../src/utils/adapterHelpers.js","../src/data-adapter/cidikaDashboardAdapter.js","../src/data-adapter/dummyUmkmDashboardAdapter.js","../src/data-adapter/tokoSepatuDashboardAdapter.js","../src/data-source/cidikaSupabaseSource.js","../src/data-source/tokoSepatuSupabaseSource.js","../src/hooks/useReusableDashboard.js","../src/utils/dateRange.js","../src/hooks/useRealtimeUpdate.js","../src/presentation/atoms/Button.jsx","../src/presentation/atoms/Input.jsx","../src/presentation/atoms/Icon.jsx","../src/presentation/atoms/Typography.jsx","../src/presentation/atoms/Badge.jsx","../src/presentation/atoms/SkeletonLoader.jsx","../src/presentation/molecules/StatCard.jsx","../src/presentation/molecules/SearchBar.jsx","../src/presentation/molecules/DateRangeFilter.jsx","../src/presentation/molecules/ChartHeader.jsx","../src/presentation/organisms/DataTable.jsx","../src/presentation/organisms/ChartCard.jsx","../src/presentation/organisms/FilterPanel.jsx","../src/presentation/organisms/SidebarNavigation.jsx","../src/presentation/organisms/TopbarHeader.jsx","../src/presentation/templates/DashboardLayout.jsx","../src/presentation/ReusableDashboardView.jsx","../src/presentation/SetupWizard.jsx","../src/utils/labels.js"],"sourcesContent":["// ──────────────────────────────────────────────────────────────────────────────\n// Config\n// ──────────────────────────────────────────────────────────────────────────────\nexport { cidikaWidgetConfig } from \"./config/cidikaWidgetConfig.js\";\nexport { dummyUmkmWidgetConfig } from \"./config/dummyUmkmWidgetConfig.js\";\nexport { tokoSepatuWidgetConfig } from \"./config/tokoSepatuWidgetConfig.js\";\n\n// Factory — mengemas semua konfigurasi menjadi 1 objek tunggal (revisi dosen)\nexport {\n createDashboardConfig,\n validateDashboardConfig,\n} from \"./config/createDashboardConfig.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Data Adapter\n// ──────────────────────────────────────────────────────────────────────────────\nexport {\n adaptCidikaDashboardData,\n createEmptyDashboardData,\n} from \"./data-adapter/cidikaDashboardAdapter.js\";\nexport {\n adaptDummyUmkmData,\n createEmptyDummyUmkmData,\n} from \"./data-adapter/dummyUmkmDashboardAdapter.js\";\nexport {\n adaptTokoSepatuData,\n createEmptyTokoSepatuData,\n} from \"./data-adapter/tokoSepatuDashboardAdapter.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Data Source\n// ──────────────────────────────────────────────────────────────────────────────\nexport { createCidikaSupabaseSource } from \"./data-source/cidikaSupabaseSource.js\";\nexport { createTokoSepatuSupabaseSource } from \"./data-source/tokoSepatuSupabaseSource.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Hook\n// ──────────────────────────────────────────────────────────────────────────────\nexport { useReusableDashboard } from \"./hooks/useReusableDashboard.js\";\nexport { useRealtimeUpdate } from \"./hooks/useRealtimeUpdate.js\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Atoms\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as Button } from \"./presentation/atoms/Button.jsx\";\nexport { default as Input } from \"./presentation/atoms/Input.jsx\";\nexport { default as Icon, resolveIcon } from \"./presentation/atoms/Icon.jsx\";\nexport { default as Typography } from \"./presentation/atoms/Typography.jsx\";\nexport { default as Badge } from \"./presentation/atoms/Badge.jsx\";\nexport { default as SkeletonLoader } from \"./presentation/atoms/SkeletonLoader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Molecules\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as StatCard } from \"./presentation/molecules/StatCard.jsx\";\nexport { default as SearchBar } from \"./presentation/molecules/SearchBar.jsx\";\nexport { default as DateRangeFilter } from \"./presentation/molecules/DateRangeFilter.jsx\";\nexport { default as ChartHeader } from \"./presentation/molecules/ChartHeader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Organisms\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as DataTable } from \"./presentation/organisms/DataTable.jsx\";\nexport { default as ChartCard } from \"./presentation/organisms/ChartCard.jsx\";\nexport { default as FilterPanel } from \"./presentation/organisms/FilterPanel.jsx\";\nexport { default as SidebarNavigation } from \"./presentation/organisms/SidebarNavigation.jsx\";\nexport { default as TopbarHeader } from \"./presentation/organisms/TopbarHeader.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Templates\n// ──────────────────────────────────────────────────────────────────────────────\nexport { default as DashboardLayout } from \"./presentation/templates/DashboardLayout.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Presentation — Page-Level View\n// ──────────────────────────────────────────────────────────────────────────────\nexport { ReusableDashboardView } from \"./presentation/ReusableDashboardView.jsx\";\n\n// Setup Wizard — pop-up panduan konfigurasi (revisi dosen Opsi B)\nexport { SetupWizard } from \"./presentation/SetupWizard.jsx\";\n\n// ──────────────────────────────────────────────────────────────────────────────\n// Utils\n// ──────────────────────────────────────────────────────────────────────────────\nexport { createDashboardLabels } from \"./utils/labels.js\";\nexport {\n createDefaultFilters,\n formatYYYYMMDD,\n resolveDateRange,\n} from \"./utils/dateRange.js\";\nexport { formatDate, formatIDR, shortId } from \"./utils/formatters.js\";\nexport {\n toNumber,\n buildDayBuckets,\n sortMapEntries,\n} from \"./utils/adapterHelpers.js\";\n\n","export const cidikaWidgetConfig = {\n id: \"cidika.travel.dashboard\",\n defaultFilters: {\n statusScope: \"confirmed\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n sortPkgBy: \"bookings\",\n sortPkgDir: \"desc\",\n },\n widgets: {\n stats: [\n {\n id: \"bookingsConfirm\",\n label: \"confirmedBookings\",\n icon: \"TrendingUp\",\n valueKey: \"bookingsConfirm\",\n format: \"number\",\n accentColor: \"blue\",\n },\n {\n id: \"revenueConfirm\",\n label: \"confirmedRevenue\",\n icon: \"DollarSign\",\n valueKey: \"revenueConfirm\",\n format: \"currency\",\n accentColor: \"green\",\n },\n {\n id: \"avgRevenue\",\n label: \"avgRevenue\",\n icon: \"Users\",\n valueKey: \"avgRevenue\",\n format: \"currency\",\n accentColor: \"violet\",\n },\n {\n id: \"conversionRate\",\n label: \"conversionRate\",\n icon: \"PieChart\",\n valueKey: \"conversionRate\",\n format: \"percent\",\n accentColor: \"orange\",\n },\n ],\n charts: [\n {\n id: \"dailyTrends\",\n type: \"dailyArea\",\n label: \"dailyTrends\",\n icon: \"BarChart3\",\n },\n {\n id: \"statusDistribution\",\n type: \"statusPie\",\n label: \"statusDistribution\",\n icon: \"PieChart\",\n },\n {\n id: \"audienceDistribution\",\n type: \"audiencePie\",\n label: \"audienceDistribution\",\n icon: \"Users\",\n },\n {\n id: \"topPackages\",\n type: \"topPackagesBar\",\n label: \"topPackages\",\n icon: \"TrendingUp\",\n },\n ],\n table: {\n id: \"recentBookings\",\n label: \"recentBookings\",\n icon: \"Calendar\",\n emptyLabel: \"noRecentBookings\",\n columns: [\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\n { id: \"package\", label: \"package\", accessor: \"packageName\" },\n { id: \"audience\", label: \"audience\", accessor: \"audienceLabel\" },\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\n {\n id: \"status\",\n label: \"status\",\n accessor: \"statusLabel\",\n type: \"statusBadge\",\n statusAccessor: \"status\",\n },\n ],\n },\n },\n};\n","export const dummyUmkmWidgetConfig = {\n id: \"dummy.umkm.dashboard\",\n defaultFilters: {\n statusScope: \"all\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n sortPkgBy: \"revenue\",\n sortPkgDir: \"desc\",\n },\n widgets: {\n stats: [\n {\n id: \"orders\",\n label: \"confirmedBookings\",\n icon: \"TrendingUp\",\n valueKey: \"bookingsConfirm\",\n format: \"number\",\n },\n {\n id: \"revenue\",\n label: \"confirmedRevenue\",\n icon: \"DollarSign\",\n valueKey: \"revenueConfirm\",\n format: \"currency\",\n },\n ],\n charts: [\n {\n id: \"revenueTrend\",\n type: \"dailyArea\",\n label: \"dailyTrends\",\n icon: \"BarChart3\",\n },\n {\n id: \"recentOrderStatus\",\n type: \"statusPie\",\n label: \"statusDistribution\",\n icon: \"PieChart\",\n },\n ],\n table: {\n id: \"recentOrders\",\n label: \"recentBookings\",\n icon: \"Calendar\",\n emptyLabel: \"noRecentBookings\",\n columns: [\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\n ],\n },\n },\n};\n","/**\r\n * Widget Configuration — Toko Sepatu Online (Studi Kasus Dummy UMKM Non-Travel)\r\n *\r\n * Konfigurasi ini membuktikan bahwa modul reusable dashboard dapat digunakan\r\n * pada domain bisnis yang berbeda (retail sepatu) hanya dengan mendefinisikan\r\n * konfigurasi baru tanpa mengubah komponen inti.\r\n *\r\n * Perbedaan dengan cidikaWidgetConfig:\r\n * - 4 stat cards (orders, revenue, avg order, products)\r\n * - 2 charts (daily trends, status distribution)\r\n * - 1 tabel (recent orders) dengan 5 kolom\r\n * - Filter lebih sederhana (tanpa audience, tanpa pending overlay)\r\n */\r\nexport const tokoSepatuWidgetConfig = {\r\n id: \"toko.sepatu.dashboard\",\r\n defaultFilters: {\r\n statusScope: \"all\",\r\n includePendingOverlay: false,\r\n audience: \"\",\r\n daysPreset: 30,\r\n sortPkgBy: \"revenue\",\r\n sortPkgDir: \"desc\",\r\n },\r\n widgets: {\r\n stats: [\r\n {\r\n id: \"totalOrders\",\r\n label: \"confirmedBookings\",\r\n icon: \"TrendingUp\",\r\n valueKey: \"bookingsConfirm\",\r\n format: \"number\",\r\n accentColor: \"sky\",\r\n },\r\n {\r\n id: \"totalRevenue\",\r\n label: \"confirmedRevenue\",\r\n icon: \"DollarSign\",\r\n valueKey: \"revenueConfirm\",\r\n format: \"currency\",\r\n accentColor: \"green\",\r\n },\r\n {\r\n id: \"avgOrderValue\",\r\n label: \"avgRevenue\",\r\n icon: \"BarChart3\",\r\n valueKey: \"avgRevenue\",\r\n format: \"currency\",\r\n accentColor: \"violet\",\r\n },\r\n {\r\n id: \"totalProducts\",\r\n label: \"totalProducts\",\r\n icon: \"PieChart\",\r\n valueKey: \"packages\",\r\n format: \"number\",\r\n accentColor: \"orange\",\r\n },\r\n ],\r\n charts: [\r\n {\r\n id: \"dailyOrderTrends\",\r\n type: \"dailyArea\",\r\n label: \"dailyTrends\",\r\n icon: \"BarChart3\",\r\n },\r\n {\r\n id: \"orderStatusDistribution\",\r\n type: \"statusPie\",\r\n label: \"statusDistribution\",\r\n icon: \"PieChart\",\r\n },\r\n {\r\n id: \"topProducts\",\r\n type: \"topPackagesBar\",\r\n label: \"topPackages\",\r\n icon: \"TrendingUp\",\r\n },\r\n ],\r\n table: {\r\n id: \"recentOrders\",\r\n label: \"recentBookings\",\r\n icon: \"Calendar\",\r\n emptyLabel: \"noRecentBookings\",\r\n columns: [\r\n { id: \"date\", label: \"date\", accessor: \"createdAt\", type: \"date\" },\r\n { id: \"customer\", label: \"customer\", accessor: \"customerName\" },\r\n { id: \"product\", label: \"package\", accessor: \"packageName\" },\r\n { id: \"total\", label: \"total\", accessor: \"totalIDR\", type: \"currency\" },\r\n {\r\n id: \"status\",\r\n label: \"status\",\r\n accessor: \"statusLabel\",\r\n type: \"statusBadge\",\r\n statusAccessor: \"status\",\r\n },\r\n ],\r\n },\r\n },\r\n};\r\n","/**\r\n * createDashboardConfig — Factory function untuk mengemas semua konfigurasi\r\n * dashboard dalam satu objek tunggal.\r\n *\r\n * Sebelum adanya factory ini, developer harus menyiapkan 3 file terpisah\r\n * (widgetConfig, adapter, dataSource) dan mengimpornya satu per satu ke hook.\r\n * Dengan factory ini cukup 1 objek yang diserahkan ke useReusableDashboard.\r\n *\r\n * @param {object} options\r\n * @param {object} options.widgetConfig - Konfigurasi widget deklaratif.\r\n * @param {object} options.dataSource - Objek data source (fetchDashboardSnapshot, subscribeLiveUpdate).\r\n * @param {Function} options.adapter - Fungsi adapter pure function.\r\n * @param {Function} options.createEmptyState - Fungsi pembuat state kosong.\r\n * @param {object} [options.labels] - Objek label UI (opsional, bisa di-override di komponen).\r\n * @param {string} [options.languageCode=\"id\"] - Kode bahasa (id / en).\r\n * @param {string} [options.dateLocale=\"id-ID\"] - Locale format tanggal.\r\n *\r\n * @returns {object} Objek config terpadu yang siap dipakai useReusableDashboard.\r\n *\r\n * @example\r\n * // Sebelum (3 import terpisah):\r\n * const source = createCidikaSupabaseSource(supabase);\r\n * useReusableDashboard({ config: cidikaWidgetConfig, dataSource: source,\r\n * adapter: adaptCidikaDashboardData, createEmptyState: createEmptyDashboardData, ... })\r\n *\r\n * // Sesudah (1 file config):\r\n * const dashboardConfig = createDashboardConfig({\r\n * widgetConfig: cidikaWidgetConfig,\r\n * dataSource: createCidikaSupabaseSource(supabase),\r\n * adapter: adaptCidikaDashboardData,\r\n * createEmptyState: createEmptyDashboardData,\r\n * });\r\n * useReusableDashboard(dashboardConfig)\r\n */\r\nexport function createDashboardConfig({\r\n widgetConfig,\r\n dataSource,\r\n adapter,\r\n createEmptyState,\r\n labels,\r\n languageCode = \"id\",\r\n dateLocale = \"id-ID\",\r\n}) {\r\n // Validasi minimal — membantu developer yang lupa mengisi bagian penting\r\n const missing = [];\r\n if (!widgetConfig) missing.push(\"widgetConfig\");\r\n if (!dataSource) missing.push(\"dataSource\");\r\n if (!adapter) missing.push(\"adapter\");\r\n if (!createEmptyState) missing.push(\"createEmptyState\");\r\n\r\n return {\r\n // Properti yang langsung dibaca useReusableDashboard\r\n config: widgetConfig,\r\n dataSource,\r\n adapter,\r\n createEmptyState,\r\n languageCode,\r\n dateLocale,\r\n labels,\r\n\r\n // Metadata untuk setup wizard & validasi\r\n _meta: {\r\n isValid: missing.length === 0,\r\n missing,\r\n hasDataSource: Boolean(dataSource?.fetchDashboardSnapshot),\r\n hasRealtimeSupport: Boolean(dataSource?.subscribeLiveUpdate),\r\n hasLabels: Boolean(labels),\r\n widgetCount: {\r\n stats: widgetConfig?.widgets?.stats?.length ?? 0,\r\n charts: widgetConfig?.widgets?.charts?.length ?? 0,\r\n tableColumns: widgetConfig?.widgets?.table?.columns?.length ?? 0,\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Memvalidasi apakah sebuah dashboardConfig sudah lengkap dan siap dipakai.\r\n * Digunakan oleh SetupWizard untuk menentukan apakah perlu menampilkan panduan.\r\n *\r\n * @param {object} dashboardConfig - Hasil dari createDashboardConfig.\r\n * @returns {{ valid: boolean, issues: string[] }}\r\n */\r\nexport function validateDashboardConfig(dashboardConfig) {\r\n const issues = [];\r\n\r\n if (!dashboardConfig) {\r\n return { valid: false, issues: [\"dashboardConfig tidak ditemukan. Pastikan sudah memanggil createDashboardConfig().\"] };\r\n }\r\n\r\n const meta = dashboardConfig?._meta;\r\n\r\n if (!meta) {\r\n issues.push(\"Config tidak dibuat melalui createDashboardConfig(). Gunakan factory function ini untuk validasi otomatis.\");\r\n } else {\r\n if (meta.missing.length > 0) {\r\n meta.missing.forEach(m => issues.push(`Properti wajib belum diisi: \"${m}\"`));\r\n }\r\n if (!meta.hasDataSource) {\r\n issues.push(\"dataSource.fetchDashboardSnapshot() tidak ditemukan. Pastikan sudah membuat data source yang benar.\");\r\n }\r\n }\r\n\r\n if (!dashboardConfig.config?.widgets?.stats?.length) {\r\n issues.push(\"widgetConfig.widgets.stats kosong. Tambahkan minimal 1 stat card.\");\r\n }\r\n if (!dashboardConfig.config?.widgets?.charts?.length) {\r\n issues.push(\"widgetConfig.widgets.charts kosong. Tambahkan minimal 1 chart.\");\r\n }\r\n if (!dashboardConfig.config?.widgets?.table?.columns?.length) {\r\n issues.push(\"widgetConfig.widgets.table.columns kosong. Tambahkan minimal 1 kolom tabel.\");\r\n }\r\n if (!dashboardConfig.labels) {\r\n issues.push(\"labels belum diisi. Sediakan objek labels agar teks UI tampil dengan benar.\");\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n","export function formatIDR(value) {\n try {\n return (Number(value) || 0).toLocaleString(\"id-ID\");\n } catch (_error) {\n return String(value ?? 0);\n }\n}\n\nexport function shortId(value, length = 8) {\n if (!value) return \"-\";\n return String(value).slice(0, length);\n}\n\nexport function formatDate(value, locale) {\n if (!value) return \"-\";\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return \"-\";\n return date.toLocaleDateString(locale);\n}\n","/**\n * adapterHelpers — Fungsi utilitas bersama yang digunakan oleh semua data-adapter.\n * Diekstrak dari adapter individu untuk menghindari duplikasi kode (prinsip DRY).\n */\n\n/**\n * Mengkonversi nilai apapun ke angka yang valid.\n * Mengembalikan 0 jika nilai tidak valid atau bukan angka finite.\n *\n * @param {*} value - Nilai yang akan dikonversi.\n * @returns {number} Angka finite, atau 0 jika tidak valid.\n */\nexport function toNumber(value) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\n/**\n * Membangun array bucket harian untuk chart tren.\n * Setiap bucket berisi dateKey, label terformat, dan counter awal (0).\n *\n * @param {number} daysWindow - Jumlah hari dalam rentang.\n * @param {string} fromISO - Tanggal awal dalam format ISO.\n * @param {string} dateLocale - Locale untuk format tanggal (misal: \"id-ID\").\n * @returns {Array<{dateKey: string, label: string, count: number, revenue: number, pendingCount: number}>}\n */\nexport function buildDayBuckets(daysWindow, fromISO, dateLocale) {\n const start = new Date(fromISO);\n return Array.from({ length: daysWindow }).map((_, index) => {\n const day = new Date(start);\n day.setDate(start.getDate() + index);\n return {\n dateKey: day.toISOString().slice(0, 10),\n label: day.toLocaleDateString(dateLocale, {\n day: \"2-digit\",\n month: \"short\",\n }),\n count: 0,\n revenue: 0,\n pendingCount: 0,\n };\n });\n}\n\n/**\n * Mengurutkan entri Map berdasarkan nilai numerik.\n *\n * @param {Map} map - Map yang akan diurutkan.\n * @param {\"asc\"|\"desc\"} direction - Arah pengurutan.\n * @returns {Array<[string, number]>} Array entri terurut.\n */\nexport function sortMapEntries(map, direction) {\n return Array.from(map.entries()).sort((a, b) =>\n direction === \"asc\" ? a[1] - b[1] : b[1] - a[1]\n );\n}\n","import { shortId } from \"../utils/formatters.js\";\nimport { toNumber, buildDayBuckets, sortMapEntries } from \"../utils/adapterHelpers.js\";\n\nfunction createPackageTitleResolver(packageLocales, languageCode) {\n const byPackage = new Map();\n\n packageLocales.forEach((row) => {\n if (!row.package_id) return;\n const current = byPackage.get(row.package_id) || {};\n byPackage.set(row.package_id, {\n ...current,\n [row.lang]: row.title,\n });\n });\n\n return (packageId) => {\n if (!packageId) return \"-\";\n const labels = byPackage.get(packageId);\n if (!labels) return shortId(packageId, 6);\n return (\n labels[languageCode] ||\n labels.en ||\n labels.id ||\n Object.values(labels).find(Boolean) ||\n shortId(packageId, 6)\n );\n };\n}\n\nexport function createEmptyDashboardData() {\n return {\n stats: {\n bookingsConfirm: 0,\n bookingsPending: 0,\n revenueConfirm: 0,\n packages: 0,\n sections: 0,\n avgRevenue: 0,\n conversionRate: 0,\n },\n charts: {\n dailyTrends: [],\n statusDistribution: [],\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings: [],\n },\n };\n}\n\nexport function adaptCidikaDashboardData({\n raw,\n filters,\n range,\n dateLocale,\n languageCode,\n labels,\n}) {\n if (!raw) return createEmptyDashboardData();\n\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\n const dayLookup = new Map(\n dailyBuckets.map((bucket) => [bucket.dateKey, bucket])\n );\n\n const statusMap = new Map();\n const audienceMap = new Map();\n const packageCountMap = new Map();\n const packageRevenueMap = new Map();\n const getPackageTitle = createPackageTitleResolver(\n raw.packageLocales || [],\n languageCode\n );\n\n let bookingsConfirm = 0;\n let bookingsPending = 0;\n let revenueConfirm = 0;\n\n (raw.bookings || []).forEach((row) => {\n const dayKey = String(row.created_at || \"\").slice(0, 10);\n const status = String(row.status || \"pending\").toLowerCase();\n const total = toNumber(row.total_idr);\n const audience = row.audience || \"unknown\";\n\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\n audienceMap.set(audience, (audienceMap.get(audience) || 0) + 1);\n\n const bucket = dayLookup.get(dayKey);\n if (bucket) {\n if (status === \"confirmed\") {\n bucket.count += 1;\n bucket.revenue += total;\n }\n if (status === \"pending\") {\n bucket.pendingCount += 1;\n }\n }\n\n if (status === \"confirmed\") {\n bookingsConfirm += 1;\n revenueConfirm += total;\n packageCountMap.set(\n row.package_id,\n (packageCountMap.get(row.package_id) || 0) + 1\n );\n packageRevenueMap.set(\n row.package_id,\n (packageRevenueMap.get(row.package_id) || 0) + total\n );\n } else if (status === \"pending\") {\n bookingsPending += 1;\n }\n });\n\n const statusDistribution = sortMapEntries(statusMap, \"desc\").map(\n ([status, count]) => ({\n status,\n label: labels.formatStatusLabel(status),\n count,\n })\n );\n\n const audienceDistribution = sortMapEntries(audienceMap, \"desc\").map(\n ([audience, count]) => ({\n audience,\n label: labels.formatAudienceLabel(audience),\n count,\n })\n );\n\n const metricMap =\n filters.sortPkgBy === \"revenue\" ? packageRevenueMap : packageCountMap;\n\n const topPackages = sortMapEntries(metricMap, filters.sortPkgDir)\n .slice(0, 5)\n .map(([packageId, value]) => ({\n packageId,\n name: getPackageTitle(packageId),\n value: toNumber(value),\n }));\n\n const recentBookings = (raw.recent || []).map((row) => {\n const status = String(row.status || \"pending\").toLowerCase();\n return {\n id: row.id,\n createdAt: row.created_at,\n customerName: row.customer_name || \"-\",\n packageName: getPackageTitle(row.package_id),\n audienceLabel: labels.formatAudienceLabel(row.audience),\n totalIDR: toNumber(row.total_idr),\n status,\n statusLabel: labels.formatStatusLabel(status),\n };\n });\n\n const avgRevenue =\n bookingsConfirm > 0 ? Math.round(revenueConfirm / bookingsConfirm) : 0;\n const conversionRate =\n bookingsConfirm + bookingsPending > 0\n ? Math.round((bookingsConfirm / (bookingsConfirm + bookingsPending)) * 100)\n : 0;\n\n return {\n stats: {\n bookingsConfirm,\n bookingsPending,\n revenueConfirm,\n packages: toNumber(raw.staticCounts?.packages),\n sections: toNumber(raw.staticCounts?.sections),\n avgRevenue,\n conversionRate,\n },\n charts: {\n dailyTrends: dailyBuckets,\n statusDistribution,\n audienceDistribution,\n topPackages,\n },\n table: {\n recentBookings,\n },\n };\n}\n","/**\n * dummyUmkmDashboardAdapter — Data-adapter layer untuk studi kasus\n * aplikasi dummy UMKM non-travel (penjualan produk).\n *\n * Adapter ini membuktikan bahwa modul reusable dashboard dapat digunakan\n * pada domain bisnis yang berbeda dari Cidika Travel hanya dengan\n * mengganti adapter, tanpa mengubah komponen inti.\n *\n * Struktur data Supabase dummy UMKM yang diharapkan:\n * - Tabel `orders` : id, created_at, total_amount, status, customer_name, product_id\n * - Tabel `products` : id, name\n * - Tabel `customers`: id, name\n */\n\nimport { toNumber, buildDayBuckets } from \"../utils/adapterHelpers.js\";\n\n/**\n * Membuat state kosong yang sesuai dengan kontrak data dummy UMKM.\n * Dipanggil oleh useReusableDashboard sebagai initial state dan saat error.\n *\n * @returns {object} Empty dashboard data object.\n */\nexport function createEmptyDummyUmkmData() {\n return {\n stats: {\n bookingsConfirm: 0,\n revenueConfirm: 0,\n totalProducts: 0,\n totalCustomers: 0,\n },\n charts: {\n dailyTrends: [],\n statusDistribution: [],\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings: [],\n },\n };\n}\n\n/**\n * Memetakan data mentah dari Supabase dummy UMKM ke format standar widget.\n *\n * Format `raw` yang diharapkan dari dataSource:\n * ```\n * {\n * bookings: Array<{ id, created_at, total_amount, status, customer_name, product_id }>,\n * recent: Array<{ id, created_at, customer_name, total_amount, status, product_id }>,\n * staticCounts: { packages: number, sections: number } // opsional\n * }\n * ```\n *\n * @param {object} params\n * @param {object} params.raw - Data mentah dari dataSource.\n * @param {object} params.filters - State filter aktif.\n * @param {object} params.range - Rentang tanggal { fromISO, toISO, daysWindow }.\n * @param {string} params.dateLocale - Locale untuk format tanggal (misal: \"id-ID\").\n * @param {object} [params.labels] - Label i18n (opsional, untuk format status).\n * @returns {object} Objek data standar { stats, charts, table }.\n */\nexport function adaptDummyUmkmData({ raw, filters, range, dateLocale, labels }) {\n if (!raw) return createEmptyDummyUmkmData();\n\n const orders = raw.bookings || [];\n const recent = raw.recent || [];\n\n // Bangun bucket harian untuk chart tren\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\n const dayLookup = new Map(dailyBuckets.map((b) => [b.dateKey, b]));\n\n const statusMap = new Map();\n let totalOrders = 0;\n let totalRevenue = 0;\n\n orders.forEach((row) => {\n const dayKey = String(row.created_at || \"\").slice(0, 10);\n const status = String(row.status || \"pending\").toLowerCase();\n const amount = toNumber(row.total_amount);\n\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\n\n const bucket = dayLookup.get(dayKey);\n if (bucket) {\n if (status === \"confirmed\") {\n bucket.count += 1;\n bucket.revenue += amount;\n }\n if (status === \"pending\") {\n bucket.pendingCount += 1;\n }\n }\n\n if (status === \"confirmed\") {\n totalOrders += 1;\n totalRevenue += amount;\n }\n });\n\n // Distribusi status untuk pie chart\n const statusDistribution = Array.from(statusMap.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([status, count]) => ({\n status,\n label: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\n count,\n }));\n\n // Tabel recent orders — field mapping ke kontrak standar\n const recentBookings = recent.map((row) => {\n const status = String(row.status || \"pending\").toLowerCase();\n return {\n id: row.id,\n createdAt: row.created_at,\n customerName: row.customer_name || \"-\",\n packageName: row.product_name || row.product_id || \"-\",\n totalIDR: toNumber(row.total_amount),\n status,\n statusLabel: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\n };\n });\n\n return {\n stats: {\n bookingsConfirm: totalOrders,\n revenueConfirm: totalRevenue,\n totalProducts: toNumber(raw.staticCounts?.packages),\n totalCustomers: toNumber(raw.staticCounts?.sections),\n },\n charts: {\n dailyTrends: dailyBuckets,\n statusDistribution,\n audienceDistribution: [],\n topPackages: [],\n },\n table: {\n recentBookings,\n },\n };\n}\n","/**\r\n * tokoSepatuDashboardAdapter — Data-adapter layer untuk studi kasus\r\n * Toko Sepatu Online (domain retail/e-commerce).\r\n *\r\n * Adapter ini membuktikan bahwa modul reusable dashboard dapat digunakan\r\n * pada domain bisnis yang berbeda dari Cidika Travel hanya dengan\r\n * mengganti adapter, tanpa mengubah komponen inti.\r\n *\r\n * Struktur data Supabase Toko Sepatu yang diharapkan:\r\n * - Tabel `orders` : id, created_at, total_amount, status, customer_id\r\n * - Tabel `products` : id, name, brand, category, price_idr, stock\r\n * - Tabel `customers` : id, name, email, phone, city\r\n * - Tabel `order_items` : id, order_id, product_id, qty, price_idr, subtotal\r\n */\r\n\r\nimport { shortId } from \"../utils/formatters.js\";\r\nimport { toNumber, buildDayBuckets, sortMapEntries } from \"../utils/adapterHelpers.js\";\r\n\r\n/**\r\n * Membuat state kosong yang sesuai dengan kontrak data toko sepatu.\r\n * @returns {object} Empty dashboard data object.\r\n */\r\nexport function createEmptyTokoSepatuData() {\r\n return {\r\n stats: {\r\n bookingsConfirm: 0,\r\n bookingsPending: 0,\r\n revenueConfirm: 0,\r\n packages: 0,\r\n sections: 0,\r\n avgRevenue: 0,\r\n conversionRate: 0,\r\n },\r\n charts: {\r\n dailyTrends: [],\r\n statusDistribution: [],\r\n audienceDistribution: [],\r\n topPackages: [],\r\n },\r\n table: {\r\n recentBookings: [],\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Memetakan data mentah dari Supabase Toko Sepatu ke format standar widget.\r\n *\r\n * @param {object} params\r\n * @param {object} params.raw - Data mentah dari dataSource.\r\n * @param {object} params.filters - State filter aktif.\r\n * @param {object} params.range - Rentang tanggal { fromISO, toISO, daysWindow }.\r\n * @param {string} params.dateLocale - Locale untuk format tanggal.\r\n * @param {object} [params.labels] - Label i18n.\r\n * @returns {object} Objek data standar { stats, charts, table }.\r\n */\r\nexport function adaptTokoSepatuData({ raw, filters, range, dateLocale, labels }) {\r\n if (!raw) return createEmptyTokoSepatuData();\r\n\r\n const orders = raw.bookings || [];\r\n const recent = raw.recent || [];\r\n\r\n // Bangun bucket harian untuk chart tren\r\n const dailyBuckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\r\n const dayLookup = new Map(dailyBuckets.map((b) => [b.dateKey, b]));\r\n\r\n const statusMap = new Map();\r\n const productCountMap = new Map();\r\n const productRevenueMap = new Map();\r\n\r\n let ordersConfirm = 0;\r\n let ordersPending = 0;\r\n let revenueConfirm = 0;\r\n\r\n // Buat lookup nama produk\r\n const productNameMap = new Map();\r\n (raw.products || []).forEach((p) => {\r\n productNameMap.set(p.id, p.name);\r\n });\r\n\r\n orders.forEach((row) => {\r\n const dayKey = String(row.created_at || \"\").slice(0, 10);\r\n const status = String(row.status || \"pending\").toLowerCase();\r\n const total = toNumber(row.total_amount);\r\n\r\n statusMap.set(status, (statusMap.get(status) || 0) + 1);\r\n\r\n const bucket = dayLookup.get(dayKey);\r\n if (bucket) {\r\n if (status === \"confirmed\") {\r\n bucket.count += 1;\r\n bucket.revenue += total;\r\n }\r\n if (status === \"pending\") {\r\n bucket.pendingCount += 1;\r\n }\r\n }\r\n\r\n if (status === \"confirmed\") {\r\n ordersConfirm += 1;\r\n revenueConfirm += total;\r\n\r\n // Hitung produk terlaris dari order_items\r\n const items = row.order_items || [];\r\n items.forEach((item) => {\r\n const pid = item.product_id;\r\n productCountMap.set(pid, (productCountMap.get(pid) || 0) + toNumber(item.qty));\r\n productRevenueMap.set(pid, (productRevenueMap.get(pid) || 0) + toNumber(item.subtotal));\r\n });\r\n } else if (status === \"pending\") {\r\n ordersPending += 1;\r\n }\r\n });\r\n\r\n // Distribusi status\r\n const statusDistribution = sortMapEntries(statusMap, \"desc\").map(\r\n ([status, count]) => ({\r\n status,\r\n label: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\r\n count,\r\n })\r\n );\r\n\r\n // Top products\r\n const metricMap =\r\n filters.sortPkgBy === \"revenue\" ? productRevenueMap : productCountMap;\r\n\r\n const topPackages = sortMapEntries(metricMap, filters.sortPkgDir || \"desc\")\r\n .slice(0, 5)\r\n .map(([productId, value]) => ({\r\n packageId: productId,\r\n name: productNameMap.get(productId) || shortId(productId, 6),\r\n value: toNumber(value),\r\n }));\r\n\r\n // Tabel recent orders\r\n const recentBookings = recent.map((row) => {\r\n const status = String(row.status || \"pending\").toLowerCase();\r\n // Ambil nama produk dari item pertama atau dari join\r\n const productName =\r\n row.product_name ||\r\n (row.order_items && row.order_items[0]\r\n ? productNameMap.get(row.order_items[0].product_id)\r\n : null) ||\r\n \"-\";\r\n\r\n return {\r\n id: row.id,\r\n createdAt: row.created_at,\r\n customerName: row.customer_name || \"-\",\r\n packageName: productName,\r\n totalIDR: toNumber(row.total_amount),\r\n status,\r\n statusLabel: labels?.formatStatusLabel ? labels.formatStatusLabel(status) : status,\r\n };\r\n });\r\n\r\n const avgRevenue =\r\n ordersConfirm > 0 ? Math.round(revenueConfirm / ordersConfirm) : 0;\r\n const conversionRate =\r\n ordersConfirm + ordersPending > 0\r\n ? Math.round((ordersConfirm / (ordersConfirm + ordersPending)) * 100)\r\n : 0;\r\n\r\n return {\r\n stats: {\r\n bookingsConfirm: ordersConfirm,\r\n bookingsPending: ordersPending,\r\n revenueConfirm,\r\n packages: toNumber(raw.staticCounts?.products),\r\n sections: toNumber(raw.staticCounts?.customers),\r\n avgRevenue,\r\n conversionRate,\r\n },\r\n charts: {\r\n dailyTrends: dailyBuckets,\r\n statusDistribution,\r\n audienceDistribution: [],\r\n topPackages,\r\n },\r\n table: {\r\n recentBookings,\r\n },\r\n };\r\n}\r\n","function ensureNoError(response, message) {\n if (response?.error) {\n const err = new Error(message);\n err.cause = response.error;\n throw err;\n }\n}\n\nexport function createCidikaSupabaseSource(supabase) {\n return {\n async fetchDashboardSnapshot({\n fromISO,\n toISO,\n audience,\n statusScope,\n languageCode,\n }) {\n const bookingsQuery = supabase\n .from(\"bookings\")\n .select(\n \"id, created_at, total_idr, status, package_id, audience, customer_name\"\n )\n .gte(\"created_at\", fromISO)\n .lte(\"created_at\", toISO)\n .order(\"created_at\", { ascending: true });\n\n if (audience) bookingsQuery.eq(\"audience\", audience);\n\n const recentQuery = supabase\n .from(\"bookings\")\n .select(\n \"id, created_at, customer_name, total_idr, status, package_id, audience\"\n )\n .gte(\"created_at\", fromISO)\n .lte(\"created_at\", toISO)\n .order(\"created_at\", { ascending: false })\n .limit(10);\n\n if (audience) recentQuery.eq(\"audience\", audience);\n if (statusScope && statusScope !== \"all\") {\n recentQuery.eq(\"status\", statusScope);\n }\n\n const [bookingsRes, recentRes, packagesRes, sectionsRes] = await Promise.all(\n [\n bookingsQuery,\n recentQuery,\n supabase.from(\"packages\").select(\"*\", { count: \"exact\", head: true }),\n supabase\n .from(\"page_sections\")\n .select(\"*\", { count: \"exact\", head: true }),\n ]\n );\n\n ensureNoError(bookingsRes, \"Failed to load booking rows.\");\n ensureNoError(recentRes, \"Failed to load recent rows.\");\n\n const bookings = bookingsRes.data || [];\n const recent = recentRes.data || [];\n\n const packageIds = Array.from(\n new Set(\n [...bookings, ...recent]\n .map((row) => row.package_id)\n .filter((value) => Boolean(value))\n )\n );\n\n let packageLocales = [];\n if (packageIds.length > 0) {\n const localeRes = await supabase\n .from(\"package_locales\")\n .select(\"package_id,title,lang\")\n .in(\"package_id\", packageIds)\n .in(\"lang\", [languageCode, \"en\", \"id\"]);\n\n if (!localeRes.error) {\n packageLocales = localeRes.data || [];\n }\n }\n\n return {\n bookings,\n recent,\n packageLocales,\n staticCounts: {\n packages: packagesRes.error ? 0 : packagesRes.count || 0,\n sections: sectionsRes.error ? 0 : sectionsRes.count || 0,\n },\n };\n },\n\n subscribeLiveUpdate(onEvent) {\n const channel = supabase\n .channel(\"reusable-dashboard-live\")\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"bookings\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"packages\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"page_sections\" },\n onEvent\n )\n .on(\n \"postgres_changes\",\n { event: \"*\", schema: \"public\", table: \"package_locales\" },\n onEvent\n )\n .subscribe();\n\n return () => {\n supabase.removeChannel(channel);\n };\n },\n };\n}\n","/**\r\n * tokoSepatuSupabaseSource — Data-source layer untuk studi kasus\r\n * Toko Sepatu Online.\r\n *\r\n * Mengimplementasikan kontrak yang sama dengan cidikaSupabaseSource:\r\n * - fetchDashboardSnapshot({ fromISO, toISO, statusScope })\r\n * - subscribeLiveUpdate(onEvent)\r\n *\r\n * Tabel yang diquery: orders, order_items, products, customers\r\n */\r\n\r\nfunction ensureNoError(response, message) {\r\n if (response?.error) {\r\n const err = new Error(message);\r\n err.cause = response.error;\r\n throw err;\r\n }\r\n}\r\n\r\n/**\r\n * Membuat data source untuk Toko Sepatu Online.\r\n *\r\n * @param {object} supabase - Instance Supabase client.\r\n * @returns {object} Objek data source { fetchDashboardSnapshot, subscribeLiveUpdate }.\r\n */\r\nexport function createTokoSepatuSupabaseSource(supabase) {\r\n return {\r\n /**\r\n * Mengambil snapshot data dashboard dari Supabase.\r\n */\r\n async fetchDashboardSnapshot({\r\n fromISO,\r\n toISO,\r\n audience,\r\n statusScope,\r\n }) {\r\n // Query semua orders dalam rentang waktu (dengan order_items untuk top products)\r\n const ordersQuery = supabase\r\n .from(\"orders\")\r\n .select(\r\n \"id, created_at, total_amount, status, customer_id, order_items(product_id, qty, price_idr, subtotal)\"\r\n )\r\n .gte(\"created_at\", fromISO)\r\n .lte(\"created_at\", toISO)\r\n .order(\"created_at\", { ascending: true });\r\n\r\n // Query recent orders (10 terbaru) dengan nama customer\r\n const recentQuery = supabase\r\n .from(\"orders\")\r\n .select(\r\n \"id, created_at, total_amount, status, customers(name), order_items(product_id, qty, products(name))\"\r\n )\r\n .gte(\"created_at\", fromISO)\r\n .lte(\"created_at\", toISO)\r\n .order(\"created_at\", { ascending: false })\r\n .limit(10);\r\n\r\n if (statusScope && statusScope !== \"all\") {\r\n recentQuery.eq(\"status\", statusScope);\r\n }\r\n\r\n const [ordersRes, recentRes, productsRes, customersRes] =\r\n await Promise.all([\r\n ordersQuery,\r\n recentQuery,\r\n supabase\r\n .from(\"products\")\r\n .select(\"id, name, brand, category, price_idr\"),\r\n supabase\r\n .from(\"customers\")\r\n .select(\"*\", { count: \"exact\", head: true }),\r\n ]);\r\n\r\n ensureNoError(ordersRes, \"Failed to load orders.\");\r\n ensureNoError(recentRes, \"Failed to load recent orders.\");\r\n\r\n const orders = ordersRes.data || [];\r\n const recentRaw = recentRes.data || [];\r\n const products = productsRes.data || [];\r\n\r\n // Map recent orders ke format yang adapter harapkan\r\n const recent = recentRaw.map((row) => ({\r\n id: row.id,\r\n created_at: row.created_at,\r\n total_amount: row.total_amount,\r\n status: row.status,\r\n customer_name: row.customers?.name || \"-\",\r\n product_name:\r\n row.order_items?.[0]?.products?.name || \"-\",\r\n order_items: row.order_items,\r\n }));\r\n\r\n return {\r\n bookings: orders,\r\n recent,\r\n products,\r\n packageLocales: [],\r\n staticCounts: {\r\n products: products.length,\r\n customers: customersRes.error ? 0 : customersRes.count || 0,\r\n },\r\n };\r\n },\r\n\r\n /**\r\n * Subscribe ke perubahan realtime pada tabel orders dan products.\r\n */\r\n subscribeLiveUpdate(onEvent) {\r\n const channel = supabase\r\n .channel(\"toko-sepatu-dashboard-live\")\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"orders\" },\r\n onEvent\r\n )\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"products\" },\r\n onEvent\r\n )\r\n .on(\r\n \"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"order_items\" },\r\n onEvent\r\n )\r\n .subscribe();\r\n\r\n return () => {\r\n supabase.removeChannel(channel);\r\n };\r\n },\r\n };\r\n}\r\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { createDefaultFilters, resolveDateRange } from \"../utils/dateRange.js\";\nimport { useRealtimeUpdate } from \"./useRealtimeUpdate.js\";\n\nexport function useReusableDashboard({\n config,\n dataSource,\n adapter,\n createEmptyState,\n languageCode,\n dateLocale,\n labels,\n}) {\n const [filters, setFilters] = useState(() =>\n createDefaultFilters(config?.defaultFilters)\n );\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n const [lastUpdatedAt, setLastUpdatedAt] = useState(null);\n const [data, setData] = useState(() => createEmptyState());\n\n\n const range = useMemo(\n () =>\n resolveDateRange({\n daysPreset: filters.daysPreset,\n dateFrom: filters.dateFrom,\n dateTo: filters.dateTo,\n }),\n [filters.daysPreset, filters.dateFrom, filters.dateTo]\n );\n\n const refresh = useCallback(\n async ({ silent = false } = {}) => {\n if (!dataSource?.fetchDashboardSnapshot) return;\n\n if (!silent) {\n setLoading(true);\n setError(\"\");\n }\n\n try {\n const raw = await dataSource.fetchDashboardSnapshot({\n fromISO: range.fromISO,\n toISO: range.toISO,\n audience: filters.audience,\n statusScope: filters.statusScope,\n languageCode,\n });\n\n const adapted = adapter({\n raw,\n filters,\n range,\n dateLocale,\n languageCode,\n labels,\n });\n\n setData(adapted);\n setLastUpdatedAt(new Date());\n if (!silent) setError(\"\");\n } catch (loadError) {\n console.error(loadError);\n if (!silent) {\n setError(labels.loadFailed);\n setData(createEmptyState());\n }\n } finally {\n if (!silent) setLoading(false);\n }\n },\n [\n dataSource,\n range,\n filters,\n languageCode,\n adapter,\n dateLocale,\n labels,\n createEmptyState,\n ]\n );\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const { liveUpdateEnabled } = useRealtimeUpdate({\n dataSource,\n onUpdate: () => refresh({ silent: true }),\n });\n\n const updateFilter = useCallback((field, value) => {\n setFilters((current) => ({\n ...current,\n [field]: value,\n }));\n }, []);\n\n const resetFilters = useCallback(() => {\n setFilters(createDefaultFilters(config?.defaultFilters));\n }, [config?.defaultFilters]);\n\n return {\n filters,\n updateFilter,\n resetFilters,\n loading,\n error,\n data,\n refresh,\n range,\n liveUpdateEnabled,\n lastUpdatedAt,\n };\n}\n","function startOfDayISO(date) {\n const value = new Date(date);\n value.setHours(0, 0, 0, 0);\n return value.toISOString();\n}\n\nfunction endOfDayISO(date) {\n const value = new Date(date);\n value.setHours(23, 59, 59, 999);\n return value.toISOString();\n}\n\nexport function formatYYYYMMDD(date) {\n const value = new Date(date);\n const year = value.getFullYear();\n const month = String(value.getMonth() + 1).padStart(2, \"0\");\n const day = String(value.getDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n\nexport function createDefaultFilters(base = {}) {\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - 29);\n\n return {\n statusScope: \"confirmed\",\n includePendingOverlay: false,\n audience: \"\",\n daysPreset: 30,\n dateFrom: formatYYYYMMDD(fromDate),\n dateTo: formatYYYYMMDD(new Date()),\n sortPkgBy: \"bookings\",\n sortPkgDir: \"desc\",\n ...base,\n };\n}\n\n/** Tahun minimum yang diizinkan untuk input tanggal kustom. */\nconst MIN_YEAR = 2000;\n/** Batas maksimum rentang hari untuk mencegah loop tak terhingga (5 tahun). */\nconst MAX_DAYS_WINDOW = 365 * 5;\n\n/**\n * Memvalidasi apakah tanggal masuk akal (tahun >= MIN_YEAR dan <= tahun sekarang + 1).\n * @param {Date} date\n * @returns {boolean}\n */\nfunction isReasonableDate(date) {\n if (!date || Number.isNaN(date.getTime())) return false;\n const year = date.getFullYear();\n return year >= MIN_YEAR && year <= new Date().getFullYear() + 1;\n}\n\nexport function resolveDateRange({ daysPreset, dateFrom, dateTo }) {\n if (Number(daysPreset) > 0) {\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - (Number(daysPreset) - 1));\n const toDate = new Date();\n return {\n fromISO: startOfDayISO(fromDate),\n toISO: endOfDayISO(toDate),\n daysWindow: Number(daysPreset),\n };\n }\n\n const fallbackFrom = new Date(Date.now() - 29 * 24 * 60 * 60 * 1000);\n const fallbackTo = new Date();\n\n let from = dateFrom ? new Date(dateFrom) : fallbackFrom;\n let to = dateTo ? new Date(dateTo) : fallbackTo;\n\n // Jika tanggal tidak masuk akal (misal tahun 0202), gunakan fallback\n if (!isReasonableDate(from)) from = fallbackFrom;\n if (!isReasonableDate(to)) to = fallbackTo;\n\n if (from.getTime() > to.getTime()) {\n const swap = from;\n from = to;\n to = swap;\n }\n\n const fromISO = startOfDayISO(from);\n const toISO = endOfDayISO(to);\n const diffMs = new Date(toISO).getTime() - new Date(fromISO).getTime();\n // Cap daysWindow agar tidak pernah melebihi MAX_DAYS_WINDOW\n const daysWindow = Math.min(\n MAX_DAYS_WINDOW,\n Math.max(1, Math.round(diffMs / 86400000) + 1)\n );\n\n return { fromISO, toISO, daysWindow };\n}\n","import { useEffect, useState } from \"react\";\n\n/**\n * useRealtimeUpdate — Custom hook untuk mengelola subscription live update\n * melalui mekanisme Supabase Realtime (Postgres Changes).\n *\n * Hook ini mengabstraksikan logika subscription dan debounce sehingga dapat\n * digunakan secara independen oleh consumer yang membutuhkan live update\n * tanpa menggunakan useReusableDashboard secara penuh.\n *\n * @param {object} params\n * @param {object} params.dataSource - Objek data source yang mengimplementasikan\n * `subscribeLiveUpdate(callback): unsubscribeFn`.\n * @param {Function} params.onUpdate - Callback yang dipanggil saat ada perubahan data.\n * Dipanggil setelah debounce selesai.\n * @param {number} [params.debounceMs=350] - Durasi debounce dalam milidetik.\n *\n * @returns {{ liveUpdateEnabled: boolean }} State apakah live update aktif.\n *\n * @example\n * const { liveUpdateEnabled } = useRealtimeUpdate({\n * dataSource,\n * onUpdate: () => refresh({ silent: true }),\n * });\n */\nexport function useRealtimeUpdate({ dataSource, onUpdate, debounceMs = 350 }) {\n const [liveUpdateEnabled, setLiveUpdateEnabled] = useState(false);\n\n useEffect(() => {\n if (!dataSource?.subscribeLiveUpdate) return undefined;\n\n let debounceId;\n setLiveUpdateEnabled(true);\n\n const unsubscribe = dataSource.subscribeLiveUpdate(() => {\n clearTimeout(debounceId);\n debounceId = setTimeout(() => {\n onUpdate?.();\n }, debounceMs);\n });\n\n return () => {\n clearTimeout(debounceId);\n setLiveUpdateEnabled(false);\n unsubscribe?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dataSource, debounceMs]);\n // Note: onUpdate sengaja tidak dimasukkan dependency array untuk menghindari\n // re-subscribe yang tidak perlu saat parent re-render. Consumer harus\n // memoize callback-nya dengan useCallback jika ingin reaktivitas penuh.\n\n return { liveUpdateEnabled };\n}\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function Button({\n variant = \"primary\",\n size = \"md\",\n disabled = false,\n className = \"\",\n onClick,\n children,\n ...rest\n}) {\n const classes = [\n \"rdb-btn\",\n `rdb-btn-${variant}`,\n `rdb-btn-${size}`,\n className,\n ].filter(Boolean).join(\" \");\n\n return (\n <button type=\"button\" className={classes} disabled={disabled} onClick={onClick} {...rest}>\n {children}\n </button>\n );\n}\n\nButton.propTypes = {\n variant: PropTypes.oneOf([\"primary\", \"secondary\", \"ghost\"]),\n size: PropTypes.oneOf([\"sm\", \"md\", \"lg\"]),\n disabled: PropTypes.bool,\n className: PropTypes.string,\n onClick: PropTypes.func,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function Input({\n type = \"text\",\n value,\n onChange,\n placeholder,\n label,\n disabled = false,\n className = \"\",\n ...rest\n}) {\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n {label ? <label className=\"rdb-label\">{label}</label> : null}\n <input\n type={type}\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n disabled={disabled}\n className={[\"rdb-input\", className].filter(Boolean).join(\" \")}\n {...rest}\n />\n </div>\n );\n}\n\nInput.propTypes = {\n type: PropTypes.string,\n value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n onChange: PropTypes.func,\n placeholder: PropTypes.string,\n label: PropTypes.string,\n disabled: PropTypes.bool,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport {\n BarChart3,\n Calendar,\n DollarSign,\n PieChart,\n RotateCcw,\n TrendingUp,\n TrendingDown,\n Users,\n Search,\n ChevronLeft,\n ChevronRight,\n ArrowUp,\n ArrowDown,\n AlertCircle,\n} from \"lucide-react\";\n\n/**\n * Registry ikon yang tersedia di modul dashboard.\n * @type {Object.<string, React.ComponentType>}\n */\nconst ICON_REGISTRY = {\n BarChart3,\n Calendar,\n DollarSign,\n PieChart,\n RotateCcw,\n TrendingUp,\n TrendingDown,\n Users,\n Search,\n ChevronLeft,\n ChevronRight,\n ArrowUp,\n ArrowDown,\n AlertCircle,\n};\n\n/**\n * Icon — Atom komponen ikon berbasis SVG menggunakan Lucide React.\n *\n * @param {object} props\n * @param {string} props.name - Nama ikon dari registry (misal: \"TrendingUp\").\n * @param {number} [props.size=20] - Ukuran ikon dalam piksel.\n * @param {string} [props.className=\"\"] - ClassName tambahan.\n */\nexport default function Icon({ name, size = 20, className = \"\", ...rest }) {\n const IconComponent = ICON_REGISTRY[name] || BarChart3;\n\n return <IconComponent size={size} className={className} {...rest} />;\n}\n\n/**\n * Resolves an icon name to its Lucide React component.\n * Backward-compatible utility used internally.\n *\n * @param {string} name - Nama ikon.\n * @returns {React.ComponentType} Komponen ikon.\n */\nexport function resolveIcon(name) {\n return ICON_REGISTRY[name] || BarChart3;\n}\n\nIcon.propTypes = {\n /** Nama ikon dari registry Lucide React. */\n name: PropTypes.string.isRequired,\n /** Ukuran ikon dalam piksel. */\n size: PropTypes.number,\n /** ClassName tambahan. */\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst VARIANT_CLASS = {\n h1: \"rdb-h1\",\n h2: \"rdb-h2\",\n h3: \"rdb-h3\",\n subheading: \"rdb-subheading\",\n body: \"rdb-body\",\n caption: \"rdb-caption\",\n metric: \"rdb-metric\",\n};\n\nconst VARIANT_TAG = {\n h1: \"h1\", h2: \"h2\", h3: \"h3\",\n subheading: \"p\", body: \"p\", caption: \"span\", metric: \"span\",\n};\n\nexport default function Typography({ variant = \"body\", className = \"\", children, ...rest }) {\n const Tag = VARIANT_TAG[variant] || \"p\";\n const cls = [VARIANT_CLASS[variant] || \"rdb-body\", className].filter(Boolean).join(\" \");\n return <Tag className={cls} {...rest}>{children}</Tag>;\n}\n\nTypography.propTypes = {\n variant: PropTypes.oneOf([\"h1\",\"h2\",\"h3\",\"subheading\",\"body\",\"caption\",\"metric\"]),\n className: PropTypes.string,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst STATUS_CLASS = {\n confirmed: \"rdb-badge-confirmed\",\n pending: \"rdb-badge-pending\",\n cancelled: \"rdb-badge-cancelled\",\n success: \"rdb-badge-success\",\n info: \"rdb-badge-info\",\n default: \"rdb-badge-default\",\n};\n\nexport default function Badge({ status = \"default\", className = \"\", children, ...rest }) {\n const statusClass = STATUS_CLASS[status] || STATUS_CLASS.default;\n return (\n <span className={[\"rdb-badge\", statusClass, className].filter(Boolean).join(\" \")} {...rest}>\n {children}\n </span>\n );\n}\n\nBadge.propTypes = {\n status: PropTypes.string,\n className: PropTypes.string,\n children: PropTypes.node.isRequired,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function SkeletonLoader({ className = \"\", style = {} }) {\n return (\n <div\n className={[\"rdb-skeleton\", className].filter(Boolean).join(\" \")}\n style={{ minHeight: 20, ...style }}\n role=\"status\"\n aria-label=\"Loading...\"\n />\n );\n}\n\nSkeletonLoader.propTypes = {\n className: PropTypes.string,\n style: PropTypes.object,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\nimport { formatIDR } from \"../../utils/formatters.js\";\n\nfunction renderValue(format, value) {\n if (format === \"currency\") return `Rp ${formatIDR(value)}`;\n if (format === \"percent\") return `${Number(value) || 0}%`;\n return String(Number(value) || 0);\n}\n\nexport default function StatCard({\n label,\n value,\n icon = \"TrendingUp\",\n format = \"number\",\n trend = null,\n accentColor = \"blue\",\n className = \"\",\n}) {\n return (\n <div className={[\"rdb-card rdb-statcard\", `rdb-accent-${accentColor}`, className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-statcard-header\">\n <div className=\"rdb-statcard-label-group\">\n <div className=\"rdb-statcard-icon\">\n <Icon name={icon} size={16} />\n </div>\n <span className=\"rdb-statcard-label\">{label}</span>\n </div>\n {trend ? (\n <Icon\n name={trend === \"up\" ? \"TrendingUp\" : \"TrendingDown\"}\n size={16}\n style={{ color: trend === \"up\" ? \"#10b981\" : \"#ef4444\" }}\n />\n ) : null}\n </div>\n <div className=\"rdb-statcard-value\">{renderValue(format, value)}</div>\n </div>\n );\n}\n\nStatCard.propTypes = {\n label: PropTypes.string.isRequired,\n value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n icon: PropTypes.string,\n format: PropTypes.oneOf([\"number\", \"currency\", \"percent\"]),\n trend: PropTypes.oneOf([\"up\", \"down\", null]),\n accentColor: PropTypes.string,\n className: PropTypes.string,\n};\n","import React, { useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function SearchBar({\n value: controlledValue,\n onChange,\n onSearch,\n placeholder = \"Search...\",\n className = \"\",\n}) {\n const [internalValue, setInternalValue] = useState(\"\");\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const handleChange = useCallback((event) => {\n const v = event.target.value;\n if (!isControlled) setInternalValue(v);\n if (onChange) onChange(v);\n if (onSearch) onSearch(v);\n }, [isControlled, onChange, onSearch]);\n\n const handleKeyDown = useCallback((event) => {\n if (event.key === \"Enter\" && onSearch) onSearch(currentValue);\n }, [currentValue, onSearch]);\n\n return (\n <div className={[\"rdb-searchbar\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-searchbar-icon\">\n <Icon name=\"Search\" size={16} />\n </div>\n <input\n type=\"search\"\n value={currentValue}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n className=\"rdb-input rdb-searchbar-input\"\n style={{ width: \"100%\" }}\n />\n </div>\n );\n}\n\nSearchBar.propTypes = {\n value: PropTypes.string,\n onChange: PropTypes.func,\n onSearch: PropTypes.func,\n placeholder: PropTypes.string,\n className: PropTypes.string,\n};\n","import React, { useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\n\nconst CURRENT_YEAR = new Date().getFullYear();\nconst MIN_YEAR = 2020;\nconst MAX_YEAR = CURRENT_YEAR + 1;\nconst MONTHS = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\n\nfunction getYears() {\n const y = [];\n for (let i = MAX_YEAR; i >= MIN_YEAR; i--) y.push(i);\n return y;\n}\n\nfunction getDaysInMonth(year, month) {\n return new Date(year, month, 0).getDate();\n}\n\nfunction parseDate(value) {\n if (value && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [y, m, d] = value.split(\"-\").map(Number);\n if (y >= MIN_YEAR && y <= MAX_YEAR && m >= 1 && m <= 12)\n return { year: y, month: m, day: d };\n }\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth() + 1, day: now.getDate() };\n}\n\nfunction fmt({ year, month, day }) {\n return `${year}-${String(month).padStart(2,\"0\")}-${String(day).padStart(2,\"0\")}`;\n}\n\nfunction DatePicker({ value, onChange, disabled = false, label = \"\" }) {\n const p = parseDate(value);\n const years = getYears();\n const maxDay = getDaysInMonth(p.year, p.month);\n\n const handleChange = useCallback((field, val) => {\n const u = { ...p, [field]: Number(val) };\n const max = getDaysInMonth(u.year, u.month);\n if (u.day > max) u.day = max;\n onChange(fmt(u));\n }, [p, onChange]);\n\n return (\n <div style={{ display:\"flex\", flexDirection:\"column\", gap:2 }}>\n {label ? <span className=\"rdb-caption rdb-label\">{label}</span> : null}\n <div style={{ display:\"flex\", gap:4, alignItems:\"center\" }}>\n <select className=\"rdb-select\" style={{ width:52 }} value={p.day}\n onChange={e => handleChange(\"day\", e.target.value)} disabled={disabled}>\n {Array.from({ length: maxDay }, (_,i) => i+1).map(d => (\n <option key={d} value={d}>{String(d).padStart(2,\"0\")}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width:62 }} value={p.month}\n onChange={e => handleChange(\"month\", e.target.value)} disabled={disabled}>\n {MONTHS.map((name, idx) => (\n <option key={idx+1} value={idx+1}>{name}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width:72 }} value={p.year}\n onChange={e => handleChange(\"year\", e.target.value)} disabled={disabled}>\n {years.map(y => <option key={y} value={y}>{y}</option>)}\n </select>\n </div>\n </div>\n );\n}\n\nexport default function DateRangeFilter({\n dateFrom, dateTo, onRangeChange,\n disabled = false, labelFrom = \"From\", labelTo = \"To\", className = \"\",\n}) {\n const handleFrom = useCallback(v => onRangeChange?.({ dateFrom: v, dateTo }), [dateTo, onRangeChange]);\n const handleTo = useCallback(v => onRangeChange?.({ dateFrom, dateTo: v }), [dateFrom, onRangeChange]);\n\n return (\n <div className={[\"rdb-daterange\", className].filter(Boolean).join(\" \")}>\n <DatePicker value={dateFrom} onChange={handleFrom} disabled={disabled} label={labelFrom} />\n <DatePicker value={dateTo} onChange={handleTo} disabled={disabled} label={labelTo} />\n </div>\n );\n}\n\nDateRangeFilter.propTypes = {\n dateFrom: PropTypes.string.isRequired,\n dateTo: PropTypes.string.isRequired,\n onRangeChange: PropTypes.func.isRequired,\n disabled: PropTypes.bool,\n labelFrom: PropTypes.string,\n labelTo: PropTypes.string,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function ChartHeader({ title, icon = \"BarChart3\", actions = null, className = \"\" }) {\n return (\n <div className={[\"rdb-chart-title-wrap\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-chart-title\">\n <Icon name={icon} size={18} />\n {title}\n </div>\n {actions}\n </div>\n );\n}\n\nChartHeader.propTypes = {\n title: PropTypes.string.isRequired,\n icon: PropTypes.string,\n actions: PropTypes.node,\n className: PropTypes.string,\n};\n","import React, { useMemo, useState, useCallback } from \"react\";\nimport PropTypes from \"prop-types\";\nimport SearchBar from \"../molecules/SearchBar.jsx\";\nimport Badge from \"../atoms/Badge.jsx\";\nimport Icon from \"../atoms/Icon.jsx\";\nimport { formatDate, formatIDR } from \"../../utils/formatters.js\";\n\nexport default function DataTable({\n columns, data = [], labels = {}, dateLocale = \"id-ID\",\n searchable = true, sortable = true, pageSize = 10,\n emptyLabel = \"No data\", searchPlaceholder = \"Search...\", className = \"\",\n}) {\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [sortField, setSortField] = useState(null);\n const [sortDirection, setSortDirection] = useState(\"asc\");\n const [currentPage, setCurrentPage] = useState(1);\n\n const filteredData = useMemo(() => {\n if (!searchQuery.trim()) return data;\n const q = searchQuery.toLowerCase();\n return data.filter(row =>\n columns.some(col => {\n const v = row[col.accessor];\n return v != null && String(v).toLowerCase().includes(q);\n })\n );\n }, [data, searchQuery, columns]);\n\n const sortedData = useMemo(() => {\n if (!sortField) return filteredData;\n return [...filteredData].sort((a, b) => {\n const aV = a[sortField] ?? \"\";\n const bV = b[sortField] ?? \"\";\n if (typeof aV === \"number\" && typeof bV === \"number\")\n return sortDirection === \"asc\" ? aV - bV : bV - aV;\n const cmp = String(aV).localeCompare(String(bV), undefined, { numeric: true });\n return sortDirection === \"asc\" ? cmp : -cmp;\n });\n }, [filteredData, sortField, sortDirection]);\n\n const totalPages = Math.max(1, Math.ceil(sortedData.length / pageSize));\n const safePage = Math.min(currentPage, totalPages);\n const paginatedData = useMemo(() => {\n const start = (safePage - 1) * pageSize;\n return sortedData.slice(start, start + pageSize);\n }, [sortedData, safePage, pageSize]);\n\n const handleSearch = useCallback(v => { setSearchQuery(v); setCurrentPage(1); }, []);\n const handleSort = useCallback(acc => {\n if (!sortable) return;\n if (sortField === acc) setSortDirection(p => p === \"asc\" ? \"desc\" : \"asc\");\n else { setSortField(acc); setSortDirection(\"asc\"); }\n setCurrentPage(1);\n }, [sortable, sortField]);\n const handlePrev = useCallback(() => setCurrentPage(p => Math.max(1, p-1)), []);\n const handleNext = useCallback(() => setCurrentPage(p => Math.min(totalPages, p+1)), [totalPages]);\n\n return (\n <div style={{ display:\"flex\", flexDirection:\"column\", gap:12 }} className={className}>\n {searchable ? (\n <SearchBar value={searchQuery} onSearch={handleSearch} placeholder={searchPlaceholder} />\n ) : null}\n\n <div className=\"rdb-table-wrapper\">\n <table className=\"rdb-table\">\n <thead>\n <tr>\n {columns.map(col => (\n <th key={col.id} onClick={() => handleSort(col.accessor)}>\n <div style={{ display:\"flex\", alignItems:\"center\", gap:4 }}>\n <span>{labels[col.label] || col.label}</span>\n {sortable && sortField === col.accessor ? (\n <Icon name={sortDirection === \"asc\" ? \"ArrowUp\" : \"ArrowDown\"} size={13}\n style={{ color: \"var(--rdb-blue-500)\" }} />\n ) : null}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {paginatedData.map(row => (\n <tr key={row.id}>\n {columns.map(col => (\n <td key={`${row.id}-${col.id}`}>{renderCell(col, row, dateLocale)}</td>\n ))}\n </tr>\n ))}\n {paginatedData.length === 0 ? (\n <tr>\n <td className=\"rdb-table-empty\" colSpan={columns.length}>{emptyLabel}</td>\n </tr>\n ) : null}\n </tbody>\n </table>\n </div>\n\n {sortedData.length > pageSize ? (\n <div className=\"rdb-pagination\">\n <span className=\"rdb-pagination-info\">\n {(safePage-1)*pageSize+1}–{Math.min(safePage*pageSize, sortedData.length)} of {sortedData.length}\n </span>\n <div className=\"rdb-pagination-controls\">\n <button type=\"button\" className=\"rdb-page-btn\" onClick={handlePrev} disabled={safePage <= 1} aria-label=\"Previous\">\n <Icon name=\"ChevronLeft\" size={16} />\n </button>\n <span className=\"rdb-pagination-page\">{safePage} / {totalPages}</span>\n <button type=\"button\" className=\"rdb-page-btn\" onClick={handleNext} disabled={safePage >= totalPages} aria-label=\"Next\">\n <Icon name=\"ChevronRight\" size={16} />\n </button>\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction renderCell(column, row, dateLocale) {\n const value = row[column.accessor];\n if (column.type === \"date\") return formatDate(value, dateLocale);\n if (column.type === \"currency\") return `Rp ${formatIDR(value)}`;\n if (column.type === \"statusBadge\") {\n const status = row[column.statusAccessor] || \"pending\";\n return <Badge status={status}>{value}</Badge>;\n }\n return value || \"-\";\n}\n\nDataTable.propTypes = {\n columns: PropTypes.arrayOf(PropTypes.shape({\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n accessor: PropTypes.string.isRequired,\n type: PropTypes.oneOf([\"date\",\"currency\",\"statusBadge\"]),\n statusAccessor: PropTypes.string,\n })).isRequired,\n data: PropTypes.arrayOf(PropTypes.object),\n labels: PropTypes.object,\n dateLocale: PropTypes.string,\n searchable: PropTypes.bool,\n sortable: PropTypes.bool,\n pageSize: PropTypes.number,\n emptyLabel: PropTypes.string,\n searchPlaceholder: PropTypes.string,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Legend,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport ChartHeader from \"../molecules/ChartHeader.jsx\";\nimport SkeletonLoader from \"../atoms/SkeletonLoader.jsx\";\nimport { formatIDR } from \"../../utils/formatters.js\";\n\n/**\n * Palet warna default untuk grafik.\n * @type {string[]}\n */\nconst COLORS = [\n \"#0ea5e9\",\n \"#a78bfa\",\n \"#f59e0b\",\n \"#10b981\",\n \"#ef4444\",\n \"#22d3ee\",\n];\n\n/**\n * ChartCard — Organism kartu grafik yang mengintegrasikan ChartHeader\n * dengan area visualisasi. Mendukung tipe grafik area, pie, dan bar.\n *\n * @param {object} props\n * @param {object} props.widget - Konfigurasi widget chart.\n * @param {object} props.labels - Objek label i18n.\n * @param {boolean} props.loading - Apakah sedang loading.\n * @param {object} props.filters - State filter dashboard.\n * @param {object} props.chartData - Data untuk semua jenis chart.\n * @param {string} [props.className=\"\"] - ClassName tambahan.\n */\nexport default function ChartCard({\n widget,\n labels,\n loading,\n filters,\n chartData,\n className = \"\",\n}) {\n const content = (() => {\n if (loading) return <SkeletonLoader style={{ height: 256 }} />;\n\n if (widget.type === \"dailyArea\") {\n return renderDailyArea(labels, filters, chartData.dailyTrends);\n }\n if (widget.type === \"statusPie\") {\n return renderPie(chartData.statusDistribution);\n }\n if (widget.type === \"audiencePie\") {\n return renderPie(chartData.audienceDistribution);\n }\n if (widget.type === \"topPackagesBar\") {\n return renderTopPackages(chartData.topPackages, labels, filters.sortPkgBy);\n }\n\n return <div className=\"rdb-muted\">Unsupported chart type.</div>;\n })();\n\n return (\n <div className={`rdb-card rdb-chart-card ${className}`}>\n <ChartHeader\n title={labels[widget.label] || widget.label}\n icon={widget.icon}\n />\n {content}\n </div>\n );\n}\n\n/**\n * Merender grafik area harian (daily area chart).\n * @param {object} labels - Label i18n.\n * @param {object} filters - Filter dashboard.\n * @param {Array} dailyData - Data daily trends.\n * @returns {React.ReactElement} Komponen AreaChart.\n */\nfunction renderDailyArea(labels, filters, dailyData = []) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <AreaChart data={dailyData}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"label\" />\n <YAxis yAxisId=\"left\" />\n <YAxis yAxisId=\"right\" orientation=\"right\" />\n <Tooltip\n formatter={(value, name) =>\n name === \"revenue\"\n ? [`Rp ${formatIDR(value)}`, labels.revenueMetric]\n : [value, labels.bookingsMetric]\n }\n />\n <Legend />\n <Area\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"count\"\n name={labels.confirmedBookingMetric}\n stroke=\"#0ea5e9\"\n fill=\"#0ea5e9\"\n fillOpacity={0.3}\n />\n <Area\n yAxisId=\"right\"\n type=\"monotone\"\n dataKey=\"revenue\"\n name={labels.confirmedRevenueMetric}\n stroke=\"#a78bfa\"\n fill=\"#a78bfa\"\n fillOpacity={0.3}\n />\n {filters.includePendingOverlay ? (\n <Area\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey=\"pendingCount\"\n name={labels.pendingMetric}\n stroke=\"#ef4444\"\n fill=\"#ef4444\"\n fillOpacity={0.1}\n strokeDasharray=\"4 4\"\n />\n ) : null}\n </AreaChart>\n </ResponsiveContainer>\n );\n}\n\n/**\n * Merender diagram lingkaran (Pie/Donut Chart).\n * @param {Array} data - Data distribusi.\n * @returns {React.ReactElement} Komponen PieChart.\n */\nfunction renderPie(data = []) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <PieChart>\n <Pie\n data={data}\n dataKey=\"count\"\n nameKey=\"label\"\n innerRadius={60}\n outerRadius={100}\n paddingAngle={2}\n >\n {data.map((_, index) => (\n <Cell\n key={`${index}-${data[index].label}`}\n fill={COLORS[index % COLORS.length]}\n />\n ))}\n </Pie>\n <Tooltip />\n <Legend />\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\n/**\n * Merender grafik batang (Bar Chart) untuk paket teratas.\n * @param {Array} data - Data top packages.\n * @param {object} labels - Label i18n.\n * @param {string} sortPkgBy - Metrik pengurutan (bookings/revenue).\n * @returns {React.ReactElement} Komponen BarChart.\n */\nfunction renderTopPackages(data = [], labels, sortPkgBy) {\n return (\n <ResponsiveContainer width=\"100%\" height={256}>\n <BarChart data={data} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" allowDecimals={false} />\n <YAxis type=\"category\" dataKey=\"name\" width={120} />\n <Tooltip\n formatter={(value) =>\n sortPkgBy === \"revenue\"\n ? [`Rp ${formatIDR(value)}`, labels.revenueMetric]\n : [value, labels.bookingsMetric]\n }\n />\n <Bar\n dataKey=\"value\"\n name={\n sortPkgBy === \"revenue\"\n ? labels.revenueMetric\n : labels.bookingsMetric\n }\n fill=\"#10b981\"\n radius={[4, 4, 4, 4]}\n />\n </BarChart>\n </ResponsiveContainer>\n );\n}\n\nChartCard.propTypes = {\n /** Konfigurasi widget chart. */\n widget: PropTypes.shape({\n id: PropTypes.string.isRequired,\n type: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.string,\n }).isRequired,\n /** Objek label i18n. */\n labels: PropTypes.object.isRequired,\n /** Apakah sedang loading. */\n loading: PropTypes.bool,\n /** State filter dashboard. */\n filters: PropTypes.object,\n /** Data untuk semua jenis chart. */\n chartData: PropTypes.object,\n /** ClassName tambahan. */\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Button from \"../atoms/Button.jsx\";\nimport DateRangeFilter from \"../molecules/DateRangeFilter.jsx\";\n\nconst STATUS_OPTIONS = [\"confirmed\", \"pending\", \"all\"];\nconst AUDIENCE_OPTIONS = [\"\", \"domestic\", \"foreign\"];\nconst DAY_PRESETS = [7, 30, 90, 0];\nconst SORT_BY_OPTIONS = [\"bookings\", \"revenue\"];\nconst SORT_DIR_OPTIONS = [\"desc\", \"asc\"];\n\nexport default function FilterPanel({ filters, labels, onFilterChange, onResetFilters, className = \"\" }) {\n return (\n <div className={[\"rdb-filter-panel\", className].filter(Boolean).join(\" \")}>\n {/* Row 1 */}\n <div className=\"rdb-filter-row\">\n <select className=\"rdb-select\" value={filters.statusScope}\n onChange={e => onFilterChange(\"statusScope\", e.target.value)}>\n {STATUS_OPTIONS.map(s => (\n <option key={s} value={s}>\n {s === \"confirmed\" ? labels.confirmedOnly : s === \"pending\" ? labels.pendingOnly : labels.allStatus}\n </option>\n ))}\n </select>\n\n <label className=\"rdb-filter-overlay-label\">\n <input type=\"checkbox\" checked={filters.includePendingOverlay}\n onChange={e => onFilterChange(\"includePendingOverlay\", e.target.checked)} />\n <span className=\"rdb-body\">{labels.showPendingOverlay}</span>\n </label>\n\n <select className=\"rdb-select\" value={filters.audience}\n onChange={e => onFilterChange(\"audience\", e.target.value)}>\n {AUDIENCE_OPTIONS.map(a => (\n <option key={a || \"all\"} value={a}>\n {a === \"domestic\" ? labels.audienceDomestic : a === \"foreign\" ? labels.audienceForeign : labels.allAudience}\n </option>\n ))}\n </select>\n\n <select className=\"rdb-select\" value={String(filters.daysPreset)}\n onChange={e => onFilterChange(\"daysPreset\", Number(e.target.value))}>\n {DAY_PRESETS.map(d => (\n <option key={String(d)} value={String(d)}>\n {d === 0 ? labels.customDate : labels.dayLabel(d)}\n </option>\n ))}\n </select>\n\n <DateRangeFilter\n dateFrom={filters.dateFrom || \"\"}\n dateTo={filters.dateTo || \"\"}\n onRangeChange={({ dateFrom, dateTo }) => {\n if (dateFrom !== filters.dateFrom) onFilterChange(\"dateFrom\", dateFrom);\n if (dateTo !== filters.dateTo) onFilterChange(\"dateTo\", dateTo);\n }}\n disabled={filters.daysPreset !== 0}\n className=\"rdb-filter-date\"\n />\n </div>\n\n {/* Row 2 */}\n <div className=\"rdb-filter-actions\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onResetFilters}>{labels.reset}</Button>\n <div className=\"rdb-filter-sort\">\n <span className=\"rdb-caption\">{labels.topSort}:</span>\n <select className=\"rdb-select\" style={{ width: \"auto\" }} value={filters.sortPkgBy}\n onChange={e => onFilterChange(\"sortPkgBy\", e.target.value)}>\n {SORT_BY_OPTIONS.map(s => (\n <option key={s} value={s}>{s === \"bookings\" ? labels.sortBookings : labels.sortRevenue}</option>\n ))}\n </select>\n <select className=\"rdb-select\" style={{ width: \"auto\" }} value={filters.sortPkgDir}\n onChange={e => onFilterChange(\"sortPkgDir\", e.target.value)}>\n {SORT_DIR_OPTIONS.map(d => (\n <option key={d} value={d}>{d === \"desc\" ? labels.sortDesc : labels.sortAsc}</option>\n ))}\n </select>\n </div>\n </div>\n </div>\n );\n}\n\nFilterPanel.propTypes = {\n filters: PropTypes.object.isRequired,\n labels: PropTypes.object.isRequired,\n onFilterChange: PropTypes.func.isRequired,\n onResetFilters: PropTypes.func.isRequired,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport Icon from \"../atoms/Icon.jsx\";\n\nexport default function SidebarNavigation({ items = [], activeItem = \"\", onItemClick, logo = null, className = \"\" }) {\n return (\n <aside className={[\"rdb-sidebar\", className].filter(Boolean).join(\" \")}>\n {logo ? <div className=\"rdb-sidebar-logo\">{logo}</div> : null}\n <nav className=\"rdb-sidebar-nav\" aria-label=\"Sidebar navigation\">\n {items.map(item => {\n const isActive = item.id === activeItem;\n return (\n <button key={item.id} type=\"button\"\n onClick={() => onItemClick?.(item.id)}\n aria-current={isActive ? \"page\" : undefined}\n className={[\"rdb-nav-item\", isActive ? \"rdb-nav-item-active\" : \"\"].filter(Boolean).join(\" \")}>\n {item.icon ? (\n <Icon name={item.icon} size={18}\n style={{ color: isActive ? \"var(--rdb-blue-600)\" : \"var(--rdb-text-subtle)\" }} />\n ) : null}\n <span>{item.label}</span>\n {isActive ? <span className=\"rdb-nav-dot\" /> : null}\n </button>\n );\n })}\n </nav>\n </aside>\n );\n}\n\nSidebarNavigation.propTypes = {\n items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, icon: PropTypes.string })),\n activeItem: PropTypes.string,\n onItemClick: PropTypes.func,\n logo: PropTypes.node,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function TopbarHeader({ title = \"\", actions = null, leading = null, className = \"\" }) {\n return (\n <header className={[\"rdb-topbar\", className].filter(Boolean).join(\" \")}>\n <div className=\"rdb-topbar-left\">\n {leading}\n {title ? <span className=\"rdb-h2\" style={{ overflow:\"hidden\", textOverflow:\"ellipsis\", whiteSpace:\"nowrap\" }}>{title}</span> : null}\n </div>\n {actions ? <div className=\"rdb-topbar-right\">{actions}</div> : null}\n </header>\n );\n}\n\nTopbarHeader.propTypes = {\n title: PropTypes.string,\n actions: PropTypes.node,\n leading: PropTypes.node,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\n\nexport default function DashboardLayout({ header = null, sidebar = null, children, className = \"\" }) {\n return (\n <div className={[\"rdb-layout\", className].filter(Boolean).join(\" \")}>\n {header}\n <div className=\"rdb-layout-body\">\n {sidebar}\n <main className=\"rdb-layout-main\">{children}</main>\n </div>\n </div>\n );\n}\n\nDashboardLayout.propTypes = {\n header: PropTypes.node,\n sidebar: PropTypes.node,\n children: PropTypes.node.isRequired,\n className: PropTypes.string,\n};\n","import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport \"./dashboard.css\";\nimport Icon from \"./atoms/Icon.jsx\";\nimport SkeletonLoader from \"./atoms/SkeletonLoader.jsx\";\nimport Button from \"./atoms/Button.jsx\";\nimport Badge from \"./atoms/Badge.jsx\";\nimport StatCard from \"./molecules/StatCard.jsx\";\nimport FilterPanel from \"./organisms/FilterPanel.jsx\";\nimport ChartCard from \"./organisms/ChartCard.jsx\";\nimport DataTable from \"./organisms/DataTable.jsx\";\nimport { SetupWizard } from \"./SetupWizard.jsx\";\nimport { validateDashboardConfig } from \"../config/createDashboardConfig.js\";\n\n/**\n * ReusableDashboardView — Komponen halaman (Page) dashboard utama.\n *\n * Fitur tambahan (revisi dosen — Opsi B):\n * - Secara otomatis mendeteksi apakah konfigurasi sudah valid.\n * - Jika belum valid, menampilkan SetupWizard (pop-up panduan interaktif).\n * - Developer dapat menutup wizard untuk lanjut tanpa konfigurasi.\n * - Prop `supabase` opsional: mengaktifkan fitur baca tabel langsung di wizard.\n * - Prop `dashboardConfig` opsional: jika diisi (hasil createDashboardConfig),\n * validasi dilakukan otomatis.\n *\n * @param {object} props\n * @param {object} props.config - Konfigurasi widget dashboard.\n * @param {object} props.labels - Objek label i18n.\n * @param {boolean} props.loading - Status loading data.\n * @param {string} [props.error] - Pesan error jika ada.\n * @param {object} [props.filters] - State filter dashboard.\n * @param {Function} props.onFilterChange - Callback perubahan filter.\n * @param {Function} props.onResetFilters - Callback reset filter.\n * @param {Function} props.onRefresh - Callback refresh data.\n * @param {object} [props.data] - Data dashboard.\n * @param {string} [props.dateLocale] - Locale untuk format tanggal.\n * @param {boolean} [props.liveUpdateEnabled] - Apakah live update aktif.\n * @param {object} [props.supabase] - Supabase client (aktifkan fitur baca tabel di wizard).\n * @param {object} [props.dashboardConfig] - Hasil createDashboardConfig() untuk validasi otomatis.\n */\nexport function ReusableDashboardView({\n config, labels, loading, error, filters,\n onFilterChange, onResetFilters, onRefresh,\n data, dateLocale, liveUpdateEnabled,\n supabase, dashboardConfig,\n}) {\n // ── Deteksi apakah setup wizard perlu ditampilkan ──────────────────\n // Validasi dilakukan berdasarkan dashboardConfig (jika ada) atau\n // pengecekan manual pada prop config & labels.\n const [wizardDismissed, setWizardDismissed] = React.useState(false);\n\n const configIssues = React.useMemo(() => {\n if (wizardDismissed) return [];\n\n // Jika developer menyertakan dashboardConfig (dari createDashboardConfig),\n // gunakan validator bawaan factory\n if (dashboardConfig) {\n const { issues } = validateDashboardConfig(dashboardConfig);\n return issues;\n }\n\n // Fallback: validasi manual pada prop langsung\n const issues = [];\n if (!config) issues.push(\"Prop 'config' (widgetConfig) belum diisi.\");\n if (!config?.widgets?.stats?.length) issues.push(\"widgetConfig.widgets.stats kosong. Tambahkan minimal 1 stat card.\");\n if (!config?.widgets?.charts?.length) issues.push(\"widgetConfig.widgets.charts kosong. Tambahkan minimal 1 chart.\");\n if (!config?.widgets?.table?.columns?.length) issues.push(\"widgetConfig.widgets.table.columns kosong.\");\n if (!labels) issues.push(\"Prop 'labels' belum diisi.\");\n if (!labels?.title) issues.push(\"labels.title belum diisi.\");\n if (!labels?.formatStatusLabel) issues.push(\"labels.formatStatusLabel (function) belum diisi.\");\n return issues;\n }, [config, labels, dashboardConfig, wizardDismissed]);\n\n const showWizard = !wizardDismissed && configIssues.length > 0;\n\n // ── Guard: jika config benar-benar null, render wizard saja ────────\n if (!config || !config.widgets) {\n return (\n <div className=\"rdb-view\">\n <SetupWizard\n issues={[\"Prop 'config' (widgetConfig) belum diisi atau tidak valid.\"]}\n onDismiss={() => setWizardDismissed(true)}\n supabase={supabase}\n />\n </div>\n );\n }\n\n return (\n <div className=\"rdb-view\">\n {/* Setup Wizard (muncul saat konfigurasi belum lengkap) */}\n {showWizard && (\n <SetupWizard\n issues={configIssues}\n onDismiss={() => setWizardDismissed(true)}\n supabase={supabase}\n />\n )}\n\n <div className=\"rdb-view-container\">\n\n {/* Header + Filter */}\n <div className=\"rdb-header-panel\">\n <div className=\"rdb-header-top\">\n <div className=\"rdb-header-title-group\">\n <span className=\"rdb-h1\">{labels?.title ?? \"Dashboard\"}</span>\n {liveUpdateEnabled ? (\n <Badge status=\"success\">{labels?.liveUpdate ?? \"Live\"}</Badge>\n ) : null}\n </div>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => onRefresh()} title={labels?.refresh ?? \"Refresh\"}>\n <Icon name=\"RotateCcw\" size={16} />\n </Button>\n </div>\n\n {error ? (\n <div className=\"rdb-error-banner\">\n <span>{error}</span>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => onRefresh()}>\n {labels?.retry ?? \"Retry\"}\n </Button>\n </div>\n ) : null}\n\n <FilterPanel filters={filters} labels={labels}\n onFilterChange={onFilterChange} onResetFilters={onResetFilters} />\n </div>\n\n {/* Stat Cards */}\n <div className=\"rdb-stats-grid\">\n {loading\n ? Array.from({ length: config.widgets.stats.length || 4 }).map((_, i) => (\n <SkeletonLoader key={i} style={{ height: 112 }} />\n ))\n : config.widgets.stats.map(widget => (\n <StatCard key={widget.id}\n label={labels?.[widget.label] ?? widget.label}\n value={data?.stats?.[widget.valueKey] ?? 0}\n icon={widget.icon}\n format={widget.format}\n accentColor={widget.accentColor}\n />\n ))}\n </div>\n\n {/* Chart Cards */}\n <div className=\"rdb-charts-grid\">\n {config.widgets.charts.map(widget => (\n <ChartCard key={widget.id} widget={widget} labels={labels ?? {}}\n loading={loading} filters={filters ?? {}} chartData={data?.charts ?? {}} />\n ))}\n </div>\n\n {/* Data Table */}\n <div className=\"rdb-card\" style={{ padding: 16 }}>\n <div style={{ display:\"flex\", alignItems:\"center\", gap:8, marginBottom:12 }}\n className=\"rdb-h3\">\n <Icon name={config.widgets.table.icon ?? \"Calendar\"} size={18} />\n {labels?.[config.widgets.table.label] ?? config.widgets.table.label}\n </div>\n {loading ? (\n <SkeletonLoader style={{ height: 192 }} />\n ) : (\n <DataTable\n columns={config.widgets.table.columns}\n data={data?.table?.recentBookings ?? []}\n labels={labels ?? {}}\n dateLocale={dateLocale ?? \"id-ID\"}\n emptyLabel={labels?.[config.widgets.table.emptyLabel] ?? config.widgets.table.emptyLabel}\n searchable={true}\n sortable={true}\n pageSize={10}\n />\n )}\n </div>\n\n </div>\n </div>\n );\n}\n\nReusableDashboardView.propTypes = {\n config: PropTypes.object.isRequired,\n labels: PropTypes.object.isRequired,\n loading: PropTypes.bool,\n error: PropTypes.string,\n filters: PropTypes.object,\n onFilterChange: PropTypes.func.isRequired,\n onResetFilters: PropTypes.func.isRequired,\n onRefresh: PropTypes.func.isRequired,\n data: PropTypes.object,\n dateLocale: PropTypes.string,\n liveUpdateEnabled: PropTypes.bool,\n /** Supabase client — aktifkan fitur baca tabel di wizard */\n supabase: PropTypes.object,\n /** Hasil createDashboardConfig() — untuk validasi otomatis wizard */\n dashboardConfig: PropTypes.object,\n};\n","import React, { useState, useEffect, useCallback } from \"react\";\r\nimport PropTypes from \"prop-types\";\r\nimport \"./dashboard.css\";\r\n\r\n// ─── Preset signatures ────────────────────────────────────────────────\r\nconst PRESET_SIGNATURES = {\r\n cidika: { name: \"Cidika Travel\", tables: [\"bookings\",\"packages\",\"package_locales\"] },\r\n tokoSepatu:{ name: \"Toko Sepatu / E-Commerce\", tables: [\"orders\",\"products\",\"customers\"] },\r\n};\r\nfunction detectPreset(tables) {\r\n if (!tables?.length) return null;\r\n const s = new Set(tables);\r\n if (PRESET_SIGNATURES.cidika.tables.every(t => s.has(t))) return \"cidika\";\r\n if (PRESET_SIGNATURES.tokoSepatu.tables.every(t => s.has(t))) return \"tokoSepatu\";\r\n return null;\r\n}\r\n\r\n// ─── SQL helpers ──────────────────────────────────────────────────────\r\nconst SQL_GRANT_SCHEMA = `GRANT SELECT ON information_schema.tables TO anon;\r\nGRANT SELECT ON information_schema.columns TO anon;`;\r\n\r\nconst sqlRls = (tbl) =>\r\n`-- Pilih salah satu sesuai kebutuhan (jalankan di Supabase SQL Editor):\r\n\r\n-- Opsi 1: Untuk DEVELOPMENT — nonaktifkan RLS (paling cepat)\r\nALTER TABLE public.${tbl} DISABLE ROW LEVEL SECURITY;\r\n\r\n-- Opsi 2: Untuk PRODUCTION — izinkan semua orang baca\r\nALTER TABLE public.${tbl} ENABLE ROW LEVEL SECURITY;\r\nCREATE POLICY \"dashboard_read\" ON public.${tbl}\r\n FOR SELECT TO anon USING (true);\r\n\r\n-- Opsi 3: Untuk PRODUCTION — hanya user yang login\r\nALTER TABLE public.${tbl} ENABLE ROW LEVEL SECURITY;\r\nCREATE POLICY \"dashboard_auth\" ON public.${tbl}\r\n FOR SELECT TO authenticated USING (true);`;\r\n\r\n// ─── Code generator ───────────────────────────────────────────────────\r\n// SEMUA nama file lowercase agar tidak ada case-mismatch di webpack\r\nfunction generateCode({ tableName, colDate, colStatus, colTotal,\r\n colCustomer, colItem, dashTitle,\r\n confirmedValue, pendingValue }) {\r\n const title = dashTitle || \"Dashboard\";\r\n const confirmed = confirmedValue || \"confirmed\";\r\n const pending = pendingValue || \"pending\";\r\n const custCol = colCustomer || \"customer_name\";\r\n const itemCol = colItem || \"-\";\r\n const totalCol = colTotal || \"total\";\r\n\r\n const cols = [\"id\", colDate, colStatus, totalCol,\r\n ...(custCol !== \"customer_name\" ? [custCol] : [\"customer_name\"]),\r\n ...(itemCol !== \"-\" ? [itemCol] : []),\r\n ].filter(Boolean).join(\", \");\r\n\r\n const dataSource =\r\n`// src/datasources/myDashboardSource.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n\r\nexport function createMyDashboardSource(supabase) {\r\n return {\r\n async fetchDashboardSnapshot({ fromISO, toISO, statusScope }) {\r\n const allQ = supabase\r\n .from(\"${tableName}\")\r\n .select(\"${cols}\")\r\n .gte(\"${colDate}\", fromISO)\r\n .lte(\"${colDate}\", toISO)\r\n .order(\"${colDate}\", { ascending: true });\r\n\r\n const recentQ = supabase\r\n .from(\"${tableName}\")\r\n .select(\"${cols}\")\r\n .gte(\"${colDate}\", fromISO)\r\n .lte(\"${colDate}\", toISO)\r\n .order(\"${colDate}\", { ascending: false })\r\n .limit(10);\r\n\r\n if (statusScope && statusScope !== \"all\") {\r\n recentQ.eq(\"${colStatus}\", statusScope);\r\n }\r\n\r\n const [all, recent] = await Promise.all([allQ, recentQ]);\r\n return {\r\n bookings: all.data || [],\r\n recent: recent.data || [],\r\n packageLocales: [],\r\n staticCounts: { packages: 0, sections: 0 },\r\n };\r\n },\r\n\r\n subscribeLiveUpdate(onEvent) {\r\n const ch = supabase.channel(\"rdb-${tableName}-live\")\r\n .on(\"postgres_changes\",\r\n { event: \"*\", schema: \"public\", table: \"${tableName}\" }, onEvent)\r\n .subscribe();\r\n return () => supabase.removeChannel(ch);\r\n },\r\n };\r\n}`;\r\n\r\n const adapter =\r\n`// src/adapters/myDashboardAdapter.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n\r\nimport { toNumber, buildDayBuckets } from \"@rozaqi02/reusable-dashboard\";\r\n\r\nexport function createEmptyMyDashboardData() {\r\n return {\r\n stats: { bookingsConfirm: 0, revenueConfirm: 0, avgRevenue: 0, conversionRate: 0 },\r\n charts: { dailyTrends: [], statusDistribution: [], audienceDistribution: [], topPackages: [] },\r\n table: { recentBookings: [] },\r\n };\r\n}\r\n\r\nexport function adaptMyDashboardData({ raw, range, dateLocale, labels }) {\r\n if (!raw) return createEmptyMyDashboardData();\r\n\r\n const buckets = buildDayBuckets(range.daysWindow, range.fromISO, dateLocale);\r\n const dayMap = new Map(buckets.map(b => [b.dateKey, b]));\r\n const statusMap = new Map();\r\n let confirmed = 0, revenue = 0;\r\n\r\n (raw.bookings || []).forEach(row => {\r\n const st = String(row[\"${colStatus}\"] || \"\").toLowerCase();\r\n const amt = toNumber(row[\"${totalCol}\"]);\r\n const dk = String(row[\"${colDate}\"] || \"\").slice(0, 10);\r\n\r\n statusMap.set(st, (statusMap.get(st) || 0) + 1);\r\n const b = dayMap.get(dk);\r\n if (b) {\r\n if (st === \"${confirmed}\") { b.count++; b.revenue += amt; }\r\n if (st === \"${pending}\") { b.pendingCount++; }\r\n }\r\n if (st === \"${confirmed}\") { confirmed++; revenue += amt; }\r\n });\r\n\r\n const total = (raw.bookings || []).length;\r\n return {\r\n stats: {\r\n bookingsConfirm: confirmed,\r\n revenueConfirm: revenue,\r\n avgRevenue: confirmed > 0 ? Math.round(revenue / confirmed) : 0,\r\n conversionRate: total > 0 ? Math.round((confirmed / total) * 100) : 0,\r\n },\r\n charts: {\r\n dailyTrends: buckets,\r\n statusDistribution: Array.from(statusMap.entries())\r\n .sort((a, b) => b[1] - a[1])\r\n .map(([s, c]) => ({ status: s, count: c, label: labels?.formatStatusLabel?.(s) || s })),\r\n audienceDistribution: [],\r\n topPackages: [],\r\n },\r\n table: {\r\n recentBookings: (raw.recent || []).map(row => ({\r\n id: row.id,\r\n createdAt: row[\"${colDate}\"],\r\n customerName: row[\"${custCol}\"] || \"-\",\r\n packageName: ${itemCol !== \"-\" ? `row[\"${itemCol}\"] || \"-\"` : '\"-\"'},\r\n audienceLabel: \"-\",\r\n totalIDR: toNumber(row[\"${totalCol}\"]),\r\n status: String(row[\"${colStatus}\"] || \"\").toLowerCase(),\r\n statusLabel: labels?.formatStatusLabel?.(row[\"${colStatus}\"]) || row[\"${colStatus}\"] || \"-\",\r\n })),\r\n },\r\n };\r\n}`;\r\n\r\n const widgetConfig =\r\n`// src/config/myDashboardConfig.js\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n\r\nexport const myDashboardConfig = {\r\n id: \"my.custom.dashboard\",\r\n defaultFilters: { statusScope: \"${confirmed}\", daysPreset: 30,\r\n sortPkgBy: \"bookings\", sortPkgDir: \"desc\" },\r\n widgets: {\r\n stats: [\r\n { id:\"orders\", label:\"confirmedBookings\", icon:\"TrendingUp\",\r\n valueKey:\"bookingsConfirm\", format:\"number\", accentColor:\"blue\" },\r\n { id:\"revenue\", label:\"confirmedRevenue\", icon:\"DollarSign\",\r\n valueKey:\"revenueConfirm\", format:\"currency\", accentColor:\"green\" },\r\n { id:\"avg\", label:\"avgRevenue\", icon:\"Users\",\r\n valueKey:\"avgRevenue\", format:\"currency\", accentColor:\"violet\" },\r\n { id:\"conversion\", label:\"conversionRate\", icon:\"PieChart\",\r\n valueKey:\"conversionRate\", format:\"percent\", accentColor:\"orange\" },\r\n ],\r\n charts: [\r\n { id:\"trend\", type:\"dailyArea\", label:\"dailyTrends\", icon:\"BarChart3\" },\r\n { id:\"status\", type:\"statusPie\", label:\"statusDistribution\", icon:\"PieChart\" },\r\n ],\r\n table: {\r\n id:\"recentTx\", label:\"recentBookings\", icon:\"Calendar\", emptyLabel:\"noRecentBookings\",\r\n columns: [\r\n { id:\"date\", label:\"date\", accessor:\"createdAt\", type:\"date\" },\r\n { id:\"customer\", label:\"customer\", accessor:\"customerName\" },${itemCol !== \"-\" ? `\r\n { id:\"item\", label:\"package\", accessor:\"packageName\" },` : \"\"}\r\n { id:\"total\", label:\"total\", accessor:\"totalIDR\", type:\"currency\" },\r\n { id:\"status\", label:\"status\", accessor:\"statusLabel\",\r\n type:\"statusBadge\", statusAccessor:\"status\" },\r\n ],\r\n },\r\n },\r\n};`;\r\n\r\n // PENTING: path import RELATIF dari src/pages/admin/ ke folder lain\r\n const dashboard =\r\n`// src/pages/admin/Dashboard.jsx\r\n// AUTO-GENERATED oleh Setup Wizard @rozaqi02/reusable-dashboard\r\n\r\nimport React from \"react\";\r\nimport { supabase } from \"../../lib/supabaseClient.js\";\r\nimport {\r\n ReusableDashboardView, useReusableDashboard, createDashboardConfig,\r\n} from \"@rozaqi02/reusable-dashboard\";\r\n\r\n// Tiga file hasil generate wizard\r\nimport { myDashboardConfig } from \"../../config/myDashboardConfig\";\r\nimport { createMyDashboardSource } from \"../../datasources/myDashboardSource\";\r\nimport { adaptMyDashboardData, createEmptyMyDashboardData } from \"../../adapters/myDashboardAdapter\";\r\n\r\nconst source = createMyDashboardSource(supabase);\r\n\r\nconst labels = {\r\n title: \"${title}\", refresh: \"Refresh\", liveUpdate: \"Live update\",\r\n loadFailed: \"Gagal memuat data.\", retry: \"Coba Lagi\",\r\n confirmedOnly: \"Selesai\", pendingOnly: \"Proses\", allStatus: \"Semua Status\",\r\n showPendingOverlay: \"Tampilkan pending\", reset: \"Reset\",\r\n confirmedBookings: \"Total Transaksi\", confirmedRevenue: \"Total Pendapatan\",\r\n avgRevenue: \"Rata-rata / Transaksi\", conversionRate: \"Conversion Rate\",\r\n dailyTrends: \"Tren Harian\", statusDistribution: \"Distribusi Status\",\r\n recentBookings: \"Transaksi Terbaru\", noRecentBookings: \"Belum ada transaksi\",\r\n date: \"Tanggal\", customer: \"Pelanggan\", package: \"Item\",\r\n total: \"Total\", status: \"Status\",\r\n bookingsMetric: \"Transaksi\", revenueMetric: \"Pendapatan\",\r\n confirmedBookingMetric: \"Transaksi (Selesai)\",\r\n confirmedRevenueMetric: \"Pendapatan (Selesai)\",\r\n dayLabel: n => n + \" hari\",\r\n formatStatusLabel: s => ({ \"${confirmed}\":\"Selesai\", \"${pending}\":\"Proses\" })[s] || s || \"-\",\r\n formatAudienceLabel: v => v || \"-\",\r\n};\r\n\r\nconst dashboardConfig = createDashboardConfig({\r\n widgetConfig: myDashboardConfig, dataSource: source,\r\n adapter: adaptMyDashboardData, createEmptyState: createEmptyMyDashboardData,\r\n languageCode: \"id\", dateLocale: \"id-ID\", labels,\r\n});\r\n\r\nexport default function Dashboard() {\r\n const state = useReusableDashboard({ ...dashboardConfig, labels });\r\n return (\r\n <ReusableDashboardView\r\n config={dashboardConfig.config} labels={labels}\r\n loading={state.loading} error={state.error}\r\n filters={state.filters} onFilterChange={state.updateFilter}\r\n onResetFilters={state.resetFilters} onRefresh={state.refresh}\r\n data={state.data} dateLocale={dashboardConfig.dateLocale}\r\n liveUpdateEnabled={state.liveUpdateEnabled}\r\n supabase={supabase} dashboardConfig={dashboardConfig}\r\n />\r\n );\r\n}`;\r\n\r\n return { dataSource, adapter, widgetConfig, dashboard };\r\n}\r\n\r\n// ─── Komponen utama ───────────────────────────────────────────────────\r\nexport function SetupWizard({ issues = [], onDismiss, supabase }) {\r\n const [dismissed, setDismissed] = useState(false);\r\n const [step, setStep] = useState(0);\r\n\r\n // Deteksi Supabase\r\n const [detecting, setDetecting] = useState(true);\r\n const [tables, setTables] = useState([]);\r\n const [columns, setColumns] = useState({}); // { tbl: [{column_name,data_type}] }\r\n const [sampleData, setSampleData] = useState({}); // { tbl: [row,...] }\r\n const [statusValues, setStatusValues] = useState({}); // { tbl: {colName: [val,...]} }\r\n const [supabaseOk, setSupabaseOk] = useState(false);\r\n const [detectionDone, setDetectionDone] = useState(false);\r\n const [tableBlocked, setTableBlocked] = useState(false);\r\n\r\n // Mapping\r\n const [selectedTable, setSelectedTable] = useState(\"\");\r\n const [colDate, setColDate] = useState(\"\");\r\n const [colStatus, setColStatus] = useState(\"\");\r\n const [colTotal, setColTotal] = useState(\"\");\r\n const [colCustomer, setColCustomer] = useState(\"\");\r\n const [colItem, setColItem] = useState(\"\");\r\n const [confirmedVal, setConfirmedVal] = useState(\"\");\r\n const [pendingVal, setPendingVal] = useState(\"\");\r\n const [dashTitle, setDashTitle] = useState(\"Dashboard\");\r\n const [loadingCols, setLoadingCols] = useState(false);\r\n const [colsBlocked, setColsBlocked] = useState(false);\r\n\r\n // Generated\r\n const [generatedCode, setGeneratedCode] = useState(null);\r\n const [activeTab, setActiveTab] = useState(\"dashboard\");\r\n const [copied, setCopied] = useState(\"\");\r\n const [showRls, setShowRls] = useState(false);\r\n\r\n // ── 1. Deteksi Supabase + baca tabel ─────────────────────────────\r\n useEffect(() => {\r\n if (!supabase) { setDetecting(false); setDetectionDone(true); return; }\r\n (async () => {\r\n try {\r\n const { data: d1, error: e1 } = await supabase\r\n .from(\"information_schema.tables\").select(\"table_name\")\r\n .eq(\"table_schema\",\"public\").eq(\"table_type\",\"BASE TABLE\").order(\"table_name\");\r\n if (!e1 && d1?.length) { setTables(d1.map(r=>r.table_name)); setSupabaseOk(true); return; }\r\n\r\n const { data: d2, error: e2 } = await supabase.rpc(\"rdb_get_tables\");\r\n if (!e2 && Array.isArray(d2)) {\r\n setTables(d2.map(r=> typeof r===\"string\"?r:r.table_name||r));\r\n setSupabaseOk(true); return;\r\n }\r\n\r\n // Cek koneksi saja\r\n const { error: ping } = await supabase.from(\"_rdb_\").select(\"*\").limit(1);\r\n const ok = !ping||ping.code===\"42P01\"||ping.code===\"PGRST116\"||(ping.message||\"\").includes(\"does not exist\");\r\n setSupabaseOk(ok);\r\n if (ok) setTableBlocked(true);\r\n } catch { setSupabaseOk(false); }\r\n finally { setDetecting(false); setDetectionDone(true); }\r\n })();\r\n }, [supabase]);\r\n\r\n // ── 2. Baca kolom + sample data + nilai status otomatis ──────────\r\n const analyzeTable = useCallback(async (tbl) => {\r\n if (!supabase || !tbl) return;\r\n if (columns[tbl]) { autoDetect(tbl, columns[tbl]); return; }\r\n setLoadingCols(true);\r\n setColsBlocked(false);\r\n\r\n try {\r\n let cols = null;\r\n\r\n // Strategi A: information_schema.columns\r\n const { data: ca, error: ea } = await supabase\r\n .from(\"information_schema.columns\")\r\n .select(\"column_name, data_type\")\r\n .eq(\"table_schema\",\"public\").eq(\"table_name\",tbl).order(\"ordinal_position\");\r\n if (!ea && ca?.length) cols = ca;\r\n\r\n // Strategi B: baca 1 baris → ambil keys\r\n if (!cols) {\r\n const { data: sb, error: eb } = await supabase.from(tbl).select(\"*\").limit(1);\r\n if (!eb && sb?.length > 0)\r\n cols = Object.keys(sb[0]).map(k => ({ column_name:k, data_type: typeof sb[0][k] }));\r\n }\r\n\r\n if (cols) {\r\n setColumns(p => ({ ...p, [tbl]: cols }));\r\n autoDetect(tbl, cols);\r\n } else {\r\n setColsBlocked(true);\r\n }\r\n\r\n // Baca sample data (5 baris terbaru)\r\n const { data: sample } = await supabase.from(tbl).select(\"*\").limit(5);\r\n if (sample?.length > 0) {\r\n setSampleData(p => ({ ...p, [tbl]: sample }));\r\n\r\n // Auto-detect nilai status dari data nyata\r\n const statusCol = (cols || []).find(c =>\r\n [\"status\",\"state\",\"kondisi\",\"order_status\"].includes(c.column_name.toLowerCase())\r\n )?.column_name;\r\n if (statusCol) {\r\n const uniqVals = [...new Set(sample.map(r => r[statusCol]).filter(Boolean))];\r\n setStatusValues(p => ({ ...p, [tbl]: { [statusCol]: uniqVals } }));\r\n // Auto-pilih confirmed/pending dari nilai nyata\r\n const vals = uniqVals.map(v => String(v).toLowerCase());\r\n const cfm = uniqVals.find(v => [\"confirmed\",\"selesai\",\"lunas\",\"paid\",\"done\",\"completed\",\"approve\"].includes(String(v).toLowerCase()));\r\n const pnd = uniqVals.find(v => [\"pending\",\"proses\",\"menunggu\",\"processing\",\"waiting\",\"draft\"].includes(String(v).toLowerCase()));\r\n if (cfm) setConfirmedVal(String(cfm));\r\n if (pnd) setPendingVal(String(pnd));\r\n }\r\n }\r\n } catch { setColsBlocked(true); }\r\n finally { setLoadingCols(false); }\r\n }, [supabase, columns]);\r\n\r\n function autoDetect(tbl, cols) {\r\n const f = (opts) => cols.find(c => opts.includes(c.column_name.toLowerCase()))?.column_name || \"\";\r\n setColDate(f([\"created_at\",\"tanggal\",\"date\",\"transaction_date\",\"order_date\",\"waktu\"]));\r\n setColStatus(f([\"status\",\"state\",\"kondisi\",\"order_status\",\"payment_status\"]));\r\n setColTotal(f([\"total\",\"total_idr\",\"total_amount\",\"total_price\",\"harga_total\",\"amount\",\"nominal\",\"harga\",\"grand_total\"]));\r\n setColCustomer(f([\"customer_name\",\"nama_pelanggan\",\"nama\",\"name\",\"client_name\",\"buyer_name\",\"pelanggan\"]));\r\n setColItem(f([\"service_type\",\"item_name\",\"product_name\",\"package_name\",\"layanan\",\"produk\",\"jenis\",\"paket\"]));\r\n }\r\n\r\n function copyCode(text, key) {\r\n navigator.clipboard?.writeText(text).then(() => { setCopied(key); setTimeout(()=>setCopied(\"\"),2200); });\r\n }\r\n\r\n function handleDismiss() { setDismissed(true); onDismiss?.(); }\r\n\r\n function handleGenerate() {\r\n if (!selectedTable || !colDate || !colStatus || !colTotal) return;\r\n setGeneratedCode(generateCode({\r\n tableName: selectedTable.trim(),\r\n colDate, colStatus, colTotal,\r\n colCustomer: colCustomer || \"customer_name\",\r\n colItem: colItem || \"-\",\r\n dashTitle,\r\n confirmedValue: confirmedVal || \"confirmed\",\r\n pendingValue: pendingVal || \"pending\",\r\n }));\r\n setStep(3);\r\n }\r\n\r\n if (dismissed) return null;\r\n\r\n const preset = detectPreset(tables);\r\n const tblCols = selectedTable ? (columns[selectedTable] || []) : [];\r\n const colNames = tblCols.map(c => c.column_name);\r\n const sample = selectedTable ? (sampleData[selectedTable] || []) : [];\r\n const stVals = selectedTable && colStatus ? (statusValues[selectedTable]?.[colStatus] || []) : [];\r\n const canGen = selectedTable.trim() && colDate && colStatus && colTotal;\r\n\r\n const TAB_INFO = {\r\n dashboard: { label: \"Dashboard.jsx\", path: \"src/pages/admin/Dashboard.jsx\" },\r\n dataSource: { label: \"myDashboardSource.js\", path: \"src/datasources/myDashboardSource.js\" },\r\n adapter: { label: \"myDashboardAdapter.js\", path: \"src/adapters/myDashboardAdapter.js\" },\r\n widgetConfig:{ label: \"myDashboardConfig.js\", path: \"src/config/myDashboardConfig.js\" },\r\n };\r\n\r\n // ── Helper: mini preview table ────────────────────────────────────\r\n function PreviewTable({ rows, cols: previewCols }) {\r\n if (!rows?.length || !previewCols?.length) return null;\r\n const validCols = previewCols.filter(c => c && rows[0]?.[c] !== undefined);\r\n if (!validCols.length) return null;\r\n return (\r\n <div className=\"rdb-table-wrapper\" style={{ marginTop: 8, fontSize: \"0.75rem\" }}>\r\n <table className=\"rdb-table\" style={{ fontSize: \"0.75rem\" }}>\r\n <thead>\r\n <tr>\r\n {validCols.map(c => (\r\n <th key={c} style={{ padding:\"4px 8px\", fontSize:\"0.7rem\" }}>{c}</th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {rows.slice(0, 3).map((row, i) => (\r\n <tr key={i}>\r\n {validCols.map(c => (\r\n <td key={c} style={{ padding:\"3px 8px\" }}>\r\n {String(row[c] ?? \"-\").slice(0, 30)}\r\n </td>\r\n ))}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n <div className=\"rdb-caption\" style={{ marginTop: 4, color: \"var(--rdb-text-muted)\" }}>\r\n Preview 3 baris data nyata dari database kamu\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"rdb-wizard-overlay\" role=\"dialog\" aria-modal=\"true\">\r\n <div className=\"rdb-wizard-modal\">\r\n\r\n {/* Header */}\r\n <div className=\"rdb-wizard-header\">\r\n <div className=\"rdb-wizard-header-title\">\r\n <span className=\"rdb-wizard-logo\">🛠️</span>\r\n <div>\r\n <div className=\"rdb-h2\" style={{ margin:0 }}>Setup Dashboard Wizard</div>\r\n <div className=\"rdb-caption\">\r\n {detecting ? \"Menghubungi Supabase…\"\r\n : supabaseOk\r\n ? tables.length > 0\r\n ? `✅ Tersambung · ${tables.length} tabel ditemukan`\r\n : \"✅ Tersambung · ketik nama tabel di Step 2\"\r\n : \"Ikuti langkah di bawah untuk menghubungkan Supabase\"}\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"button\" className=\"rdb-wizard-close\" onClick={handleDismiss}>✕</button>\r\n </div>\r\n\r\n {/* Step Nav */}\r\n <div className=\"rdb-wizard-steps\">\r\n {[\"1. Koneksi\", \"2. Pilih Tabel\", \"3. Konfirmasi\", \"4. Kode Jadi\"].map((lbl, i) => (\r\n <button key={i} type=\"button\"\r\n className={`rdb-wizard-step-btn ${step===i?\"rdb-wizard-step-active\":\"\"}`}\r\n onClick={() => setStep(i)}>\r\n {step > i ? \"✅ \" : \"\"}{lbl}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rdb-wizard-body\">\r\n <div className=\"rdb-wizard-section\">\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 0 — KONEKSI & STATUS\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 0 && (\r\n <>\r\n {issues.length > 0 && (\r\n <div className=\"rdb-wizard-issues\" style={{ marginBottom: 12 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:6 }}>\r\n Konfigurasi yang belum lengkap:\r\n </div>\r\n {issues.map((iss,i) => (\r\n <div key={i} className=\"rdb-wizard-issue-item\">\r\n <span>❌</span><span className=\"rdb-body\">{iss}</span>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Status */}\r\n <div className=\"rdb-wizard-flow\" style={{ marginBottom:16 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:10 }}>\r\n 🔍 Status koneksi Supabase:\r\n </div>\r\n {detecting ? (\r\n <div className=\"rdb-body\" style={{ color:\"var(--rdb-text-muted)\" }}>Mendeteksi…</div>\r\n ) : (\r\n <div style={{ display:\"flex\", flexDirection:\"column\", gap:8 }}>\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span>{supabaseOk?\"✅\":\"❌\"}</span>\r\n <span className=\"rdb-body\">\r\n {supabaseOk ? \"Supabase tersambung\"\r\n : 'Tidak tersambung — tambahkan prop supabase={supabase} ke <ReusableDashboardView>'}\r\n </span>\r\n </div>\r\n {supabaseOk && (\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span>{tables.length>0?\"✅\":\"⚠️\"}</span>\r\n <span className=\"rdb-body\">\r\n {tables.length>0\r\n ? `Wizard membaca ${tables.length} tabel langsung dari database`\r\n : \"Daftar tabel belum bisa terbaca (butuh izin — lihat SQL di bawah)\"}\r\n </span>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* SQL izin baca tabel */}\r\n {supabaseOk && tableBlocked && (\r\n <div style={{ marginBottom:16 }}>\r\n <div className=\"rdb-wizard-alert\" style={{ marginBottom:8 }}>\r\n <span className=\"rdb-wizard-alert-icon\">🔑</span>\r\n <div>\r\n <div className=\"rdb-body\" style={{ fontWeight:600 }}>\r\n Agar wizard bisa baca daftar tabel otomatis\r\n </div>\r\n <div className=\"rdb-caption\" style={{ marginTop:4 }}>\r\n Jalankan SQL ini <strong>sekali</strong> di Supabase SQL Editor,\r\n lalu refresh halaman. Atau lewati dan ketik nama tabel manual di Step 2.\r\n </div>\r\n </div>\r\n </div>\r\n <div style={{ position:\"relative\" }}>\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n style={{ position:\"absolute\", top:6, right:6 }}\r\n onClick={() => copyCode(SQL_GRANT_SCHEMA,\"grant\")}>\r\n {copied===\"grant\"?\"✅\":\"📋\"} Salin\r\n </button>\r\n <pre className=\"rdb-wizard-code\" style={{ fontSize:\"0.72rem\" }}>\r\n {SQL_GRANT_SCHEMA}\r\n </pre>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* RLS guide (collapsible) */}\r\n {supabaseOk && (\r\n <div style={{ marginBottom:16 }}>\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setShowRls(r=>!r)}>\r\n {showRls?\"▲ Sembunyikan\":\"▼ Lihat\"} panduan RLS — agar data tabel bisa terbaca dashboard\r\n </button>\r\n {showRls && (\r\n <div className=\"rdb-wizard-flow\" style={{ marginTop:10 }}>\r\n <div className=\"rdb-body\" style={{ fontWeight:600, marginBottom:6 }}>\r\n Apa itu RLS?\r\n </div>\r\n <div className=\"rdb-body\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:10 }}>\r\n Row Level Security (RLS) adalah fitur Supabase yang mengontrol siapa\r\n yang boleh membaca data. Jika aktif tanpa aturan, dashboard tidak\r\n bisa mengambil data apapun.\r\n </div>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:6 }}>\r\n SQL — ganti <code>nama_tabel</code> dengan nama tabelmu:\r\n </div>\r\n <div style={{ position:\"relative\" }}>\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n style={{ position:\"absolute\", top:6, right:6 }}\r\n onClick={() => copyCode(sqlRls(\"nama_tabel\"),\"rls\")}>\r\n {copied===\"rls\"?\"✅\":\"📋\"} Salin\r\n </button>\r\n <pre className=\"rdb-wizard-code\" style={{ fontSize:\"0.7rem\" }}>\r\n {sqlRls(\"nama_tabel\")}\r\n </pre>\r\n </div>\r\n <div className=\"rdb-caption\" style={{ marginTop:8, color:\"var(--rdb-text-muted)\" }}>\r\n 💡 <strong>Development:</strong> pakai Opsi 1.\r\n <strong> Production:</strong> pakai Opsi 2 atau 3.\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n <div style={{ display:\"flex\", gap:8, justifyContent:\"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={handleDismiss}>Lanjutkan tanpa wizard</button>\r\n {supabaseOk && (\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n onClick={() => setStep(1)}>\r\n Lanjut → Pilih Tabel\r\n </button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 1 — PILIH TABEL + AUTO-ANALYZE\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 1 && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">2</span>\r\n <span className=\"rdb-h3\" style={{ margin:0 }}>Pilih Tabel Transaksi</span>\r\n </div>\r\n <div className=\"rdb-body\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:16 }}>\r\n Klik tabel yang berisi data transaksi bisnis kamu. Wizard akan\r\n <strong> otomatis membaca kolom dan sample data</strong> dari tabel tersebut.\r\n </div>\r\n\r\n {/* Daftar tabel */}\r\n {tables.length > 0 && (\r\n <div style={{ display:\"flex\", flexWrap:\"wrap\", gap:6, marginBottom:16 }}>\r\n {tables.map(tbl => {\r\n const isSelected = selectedTable === tbl;\r\n const hasSample = sampleData[tbl]?.length > 0;\r\n const hasColumns = columns[tbl]?.length > 0;\r\n return (\r\n <button key={tbl} type=\"button\"\r\n onClick={() => { setSelectedTable(tbl); analyzeTable(tbl); }}\r\n className={`rdb-btn rdb-btn-sm ${isSelected?\"rdb-btn-primary\":\"rdb-btn-secondary\"}`}\r\n style={{ fontFamily:\"monospace\", fontSize:\"0.82rem\" }}>\r\n {isSelected ? \"✅ \" : \"\"}\r\n {tbl}\r\n {isSelected && hasColumns ? ` (${columns[tbl].length} kolom)` : \"\"}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {/* Input manual */}\r\n <div style={{ marginBottom:16 }}>\r\n <label className=\"rdb-label\">\r\n {tables.length > 0 ? \"Atau ketik nama tabel lain:\" : \"Ketik nama tabel kamu:\"}\r\n </label>\r\n <div style={{ display:\"flex\", gap:8 }}>\r\n <input className=\"rdb-input\" value={selectedTable}\r\n onChange={e => setSelectedTable(e.target.value.replace(/[,\\s].*/,\"\"))}\r\n placeholder=\"cth: orders / transaksi / bookings\"\r\n style={{ maxWidth:280 }} />\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n disabled={!selectedTable||loadingCols}\r\n onClick={() => analyzeTable(selectedTable)}>\r\n {loadingCols ? \"Menganalisis…\" : \"Analisis tabel\"}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n {/* Hasil analisis */}\r\n {selectedTable && !loadingCols && (\r\n <>\r\n {colNames.length > 0 && (\r\n <>\r\n <div className=\"rdb-wizard-tip\" style={{ marginBottom:8 }}>\r\n ✅ <strong>{colNames.length} kolom</strong> ditemukan.\r\n {sample.length > 0 && ` ${sample.length} baris sample data terbaca.`}\r\n {\" \"}Kolom sudah otomatis diisi di step berikutnya.\r\n </div>\r\n {/* Preview sample */}\r\n {sample.length > 0 && (\r\n <PreviewTable\r\n rows={sample}\r\n cols={[colDate, colStatus, colTotal, colCustomer].filter(Boolean)}\r\n />\r\n )}\r\n </>\r\n )}\r\n {colsBlocked && (\r\n <div className=\"rdb-wizard-alert\">\r\n <span className=\"rdb-wizard-alert-icon\">ℹ️</span>\r\n <div>\r\n <div className=\"rdb-body\" style={{ fontWeight:600 }}>\r\n Kolom tidak bisa terbaca otomatis\r\n </div>\r\n <div className=\"rdb-caption\" style={{ marginTop:4 }}>\r\n Kemungkinan RLS aktif. Kamu tetap bisa lanjut dan\r\n ketik nama kolom manual di step berikutnya.\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n <div style={{ marginBottom:12, marginTop:12 }}>\r\n <label className=\"rdb-label\">Judul dashboard:</label>\r\n <input className=\"rdb-input\" value={dashTitle} style={{ maxWidth:280 }}\r\n onChange={e => setDashTitle(e.target.value)}\r\n placeholder=\"cth: Dashboard Laundry / Dashboard Klinik\" />\r\n </div>\r\n\r\n <div style={{ display:\"flex\", gap:8, justifyContent:\"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(0)}>← Kembali</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n disabled={!selectedTable || loadingCols}\r\n onClick={() => setStep(2)}>\r\n Lanjut → Konfirmasi Kolom\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 2 — KONFIRMASI KOLOM (bukan mapping manual)\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 2 && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">3</span>\r\n <span className=\"rdb-h3\" style={{ margin:0 }}>\r\n Konfirmasi — Tabel: <code style={{ fontSize:\"0.9em\" }}>{selectedTable}</code>\r\n </span>\r\n </div>\r\n <div className=\"rdb-body\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:16 }}>\r\n Wizard sudah mengisi kolom secara otomatis.\r\n Periksa sebentar dan sesuaikan jika ada yang salah.\r\n </div>\r\n\r\n {/* Kolom tersedia */}\r\n {colNames.length > 0 && (\r\n <div className=\"rdb-wizard-supabase-reader\" style={{ marginBottom:16 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:6 }}>\r\n Semua kolom di tabel {selectedTable}:\r\n </div>\r\n <div className=\"rdb-wizard-table-chips\">\r\n {colNames.map(c => (\r\n <span key={c} className=\"rdb-wizard-chip\" style={{ cursor:\"default\" }}>{c}</span>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* 5 field mapping */}\r\n <div style={{ display:\"grid\", gridTemplateColumns:\"1fr 1fr\", gap:12, marginBottom:16 }}>\r\n {[\r\n { label:\"Kolom Tanggal *\", hint:\"Tipe timestamp/date\", val:colDate, set:setColDate, ph:\"created_at\" },\r\n { label:\"Kolom Status *\", hint:\"Berisi nilai selesai/pending\", val:colStatus, set:setColStatus, ph:\"status\" },\r\n { label:\"Kolom Total (uang) *\", hint:\"Integer Rupiah\", val:colTotal, set:setColTotal, ph:\"total_amount\" },\r\n { label:\"Kolom Nama Pelanggan\", hint:\"Opsional\", val:colCustomer, set:setColCustomer, ph:\"customer_name (opsional)\" },\r\n { label:\"Kolom Nama Item / Layanan\", hint:\"Opsional\", val:colItem, set:setColItem, ph:\"product_name (opsional)\" },\r\n ].map(({ label, hint, val, set, ph }) => (\r\n <div key={label}>\r\n <label className=\"rdb-label\">{label}</label>\r\n {colNames.length > 0 ? (\r\n <select className=\"rdb-select\" value={val} onChange={e => set(e.target.value)}>\r\n <option value=\"\">— pilih —</option>\r\n {colNames.map(c => <option key={c} value={c}>{c}</option>)}\r\n </select>\r\n ) : (\r\n <input className=\"rdb-input\" value={val} onChange={e=>set(e.target.value)} placeholder={ph} />\r\n )}\r\n <div className=\"rdb-caption\" style={{ marginTop:2 }}>{hint}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Nilai status — AUTO DETECT dari data nyata */}\r\n <div className=\"rdb-wizard-flow\" style={{ marginBottom:16 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:4 }}>\r\n Nilai status yang ditemukan di data kamu:\r\n </div>\r\n {stVals.length > 0 ? (\r\n <>\r\n <div className=\"rdb-caption\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:8 }}>\r\n Wizard membaca nilai unik dari kolom <strong>{colStatus}</strong>.\r\n Klik nilai yang sesuai:\r\n </div>\r\n <div style={{ display:\"flex\", gap:8, flexWrap:\"wrap\", marginBottom:12 }}>\r\n {stVals.map(v => (\r\n <div key={v} style={{ display:\"flex\", gap:4, alignItems:\"center\" }}>\r\n <button type=\"button\"\r\n className={`rdb-btn rdb-btn-sm ${confirmedVal===String(v)?\"rdb-btn-primary\":\"rdb-btn-secondary\"}`}\r\n onClick={() => setConfirmedVal(String(v))}>\r\n {confirmedVal===String(v)?\"✅ \":\"\"}Selesai = <strong>{String(v)}</strong>\r\n </button>\r\n <button type=\"button\"\r\n className={`rdb-btn rdb-btn-sm ${pendingVal===String(v)?\"rdb-btn-primary\":\"rdb-btn-secondary\"}`}\r\n onClick={() => setPendingVal(String(v))}>\r\n {pendingVal===String(v)?\"✅ \":\"\"}Proses = <strong>{String(v)}</strong>\r\n </button>\r\n </div>\r\n ))}\r\n </div>\r\n </>\r\n ) : (\r\n <div className=\"rdb-caption\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:8 }}>\r\n Nilai status tidak terbaca otomatis. Ketik manual:\r\n </div>\r\n )}\r\n\r\n <div style={{ display:\"grid\", gridTemplateColumns:\"1fr 1fr\", gap:12 }}>\r\n <div>\r\n <label className=\"rdb-label\">Nilai \"Selesai/Confirmed\"</label>\r\n <input className=\"rdb-input\" value={confirmedVal}\r\n onChange={e=>setConfirmedVal(e.target.value)} placeholder=\"confirmed\" />\r\n </div>\r\n <div>\r\n <label className=\"rdb-label\">Nilai \"Pending/Proses\"</label>\r\n <input className=\"rdb-input\" value={pendingVal}\r\n onChange={e=>setPendingVal(e.target.value)} placeholder=\"pending\" />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Preview data nyata sesuai mapping */}\r\n {sample.length > 0 && colDate && colStatus && colTotal && (\r\n <div style={{ marginBottom:16 }}>\r\n <div className=\"rdb-caption\" style={{ fontWeight:600, marginBottom:4 }}>\r\n Preview data nyata sesuai mapping kamu:\r\n </div>\r\n <PreviewTable\r\n rows={sample}\r\n cols={[colDate, colStatus, colTotal, colCustomer, colItem].filter(c=>c&&c!==\"-\")}\r\n />\r\n </div>\r\n )}\r\n\r\n {!canGen && (\r\n <div className=\"rdb-error-banner\" style={{ marginBottom:12 }}>\r\n Isi Kolom Tanggal, Status, dan Total untuk melanjutkan.\r\n </div>\r\n )}\r\n\r\n <div style={{ display:\"flex\", gap:8, justifyContent:\"flex-end\" }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(1)}>← Kembali</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n disabled={!canGen} onClick={handleGenerate}>\r\n ✨ Generate Kode →\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* ══════════════════════════════════════════════════════\r\n STEP 3 — KODE SIAP PAKAI\r\n ══════════════════════════════════════════════════════ */}\r\n {step === 3 && generatedCode && (\r\n <>\r\n <div className=\"rdb-wizard-step-title\">\r\n <span className=\"rdb-wizard-step-num\">✅</span>\r\n <span className=\"rdb-h3\" style={{ margin:0 }}>Kode Sudah Jadi!</span>\r\n </div>\r\n\r\n <div className=\"rdb-wizard-tip\" style={{ marginBottom:12 }}>\r\n <strong>4 file digenerate.</strong> Klik tab file → Salin → Simpan ke lokasi yang tertera di bawah tab.\r\n Tidak perlu mengubah isi kode — langsung save dan jalankan.\r\n </div>\r\n\r\n {/* Checklist */}\r\n <div className=\"rdb-wizard-issues\" style={{ marginBottom:12 }}>\r\n {Object.entries(TAB_INFO).map(([key, info], i) => (\r\n <div key={key} className=\"rdb-wizard-issue-item\">\r\n <span style={{ color:\"var(--rdb-blue-500)\", fontWeight:700, minWidth:18 }}>{i+1}.</span>\r\n <span className=\"rdb-body\">\r\n Salin <code className=\"rdb-wizard-code-inline\">{info.label}</code>\r\n {\" → simpan ke \"}<code className=\"rdb-wizard-code-inline\">{info.path}</code>\r\n </span>\r\n </div>\r\n ))}\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span style={{ color:\"var(--rdb-blue-500)\", fontWeight:700, minWidth:18 }}>5.</span>\r\n <span className=\"rdb-body\">\r\n Di <code className=\"rdb-wizard-code-inline\">src/index.css</code>, tambahkan:{\" \"}\r\n <code className=\"rdb-wizard-code-inline\">\r\n @import \"../node_modules/@rozaqi02/reusable-dashboard/dist/index.css\";\r\n </code>\r\n </span>\r\n </div>\r\n <div className=\"rdb-wizard-issue-item\">\r\n <span style={{ color:\"var(--rdb-blue-500)\", fontWeight:700, minWidth:18 }}>6.</span>\r\n <span className=\"rdb-body\">Restart dev server (<code className=\"rdb-wizard-code-inline\">npm start</code>) → buka halaman dashboard → selesai!</span>\r\n </div>\r\n </div>\r\n\r\n {/* Tab file */}\r\n <div style={{ display:\"flex\", gap:4, flexWrap:\"wrap\", marginBottom:4 }}>\r\n {Object.entries(TAB_INFO).map(([key, info]) => (\r\n <button key={key} type=\"button\"\r\n onClick={() => setActiveTab(key)}\r\n className={`rdb-btn rdb-btn-sm ${activeTab===key?\"rdb-btn-primary\":\"rdb-btn-secondary\"}`}\r\n style={{ fontFamily:\"monospace\", fontSize:\"0.73rem\" }}>\r\n {info.label}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n <div className=\"rdb-caption\" style={{ color:\"var(--rdb-text-muted)\", marginBottom:6 }}>\r\n 📁 Simpan ke: <code className=\"rdb-wizard-code-inline\">{TAB_INFO[activeTab]?.path}</code>\r\n </div>\r\n\r\n <div style={{ position:\"relative\" }}>\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n style={{ position:\"absolute\", top:8, right:8, zIndex:1 }}\r\n onClick={() => copyCode(generatedCode[activeTab], activeTab)}>\r\n {copied===activeTab ? \"✅ Tersalin!\" : \"📋 Salin kode\"}\r\n </button>\r\n <pre className=\"rdb-wizard-code\" style={{ maxHeight:280, overflow:\"auto\" }}>\r\n {generatedCode[activeTab]}\r\n </pre>\r\n </div>\r\n\r\n {/* Reminder RLS */}\r\n <div className=\"rdb-wizard-alert\" style={{ marginTop:10, marginBottom:4 }}>\r\n <span className=\"rdb-wizard-alert-icon\">⚠️</span>\r\n <div>\r\n <div className=\"rdb-body\" style={{ fontWeight:600 }}>Data tidak muncul di dashboard?</div>\r\n <div className=\"rdb-caption\" style={{ marginTop:4 }}>\r\n Jalankan SQL ini di Supabase SQL Editor:\r\n </div>\r\n <div style={{ position:\"relative\", marginTop:6 }}>\r\n <button type=\"button\"\r\n className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n style={{ position:\"absolute\", top:4, right:4 }}\r\n onClick={() => copyCode(`ALTER TABLE public.${selectedTable} DISABLE ROW LEVEL SECURITY;`, \"rlsquick\")}>\r\n {copied===\"rlsquick\"?\"✅\":\"📋\"}\r\n </button>\r\n <pre className=\"rdb-wizard-code\" style={{ fontSize:\"0.72rem\" }}>\r\n {`ALTER TABLE public.${selectedTable} DISABLE ROW LEVEL SECURITY;`}\r\n </pre>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div style={{ display:\"flex\", gap:8, justifyContent:\"flex-end\", marginTop:10 }}>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-secondary rdb-btn-sm\"\r\n onClick={() => setStep(2)}>← Edit mapping</button>\r\n <button type=\"button\" className=\"rdb-btn rdb-btn-primary rdb-btn-sm\"\r\n onClick={handleDismiss}>Tutup wizard ✓</button>\r\n </div>\r\n </>\r\n )}\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nSetupWizard.propTypes = {\r\n issues: PropTypes.arrayOf(PropTypes.string),\r\n onDismiss: PropTypes.func,\r\n supabase: PropTypes.object,\r\n};\r\n","export function createDashboardLabels(t) {\n const labels = {\n title: t(\"admin.dashboard.title\", { defaultValue: \"Dashboard\" }),\n refresh: t(\"admin.dashboard.refresh\", { defaultValue: \"Refresh\" }),\n liveUpdate: t(\"admin.dashboard.liveUpdate\", { defaultValue: \"Live update\" }),\n loadFailed: t(\"admin.dashboard.loadFailed\", {\n defaultValue: \"Failed to load dashboard data.\",\n }),\n retry: t(\"admin.dashboard.retry\", { defaultValue: \"Retry\" }),\n confirmedOnly: t(\"admin.dashboard.filters.confirmedOnly\", {\n defaultValue: \"Confirmed only\",\n }),\n pendingOnly: t(\"admin.dashboard.filters.pendingOnly\", {\n defaultValue: \"Pending only\",\n }),\n allStatus: t(\"admin.dashboard.filters.allStatus\", {\n defaultValue: \"All status\",\n }),\n showPendingOverlay: t(\"admin.dashboard.filters.showPendingOverlay\", {\n defaultValue: \"Show pending overlay\",\n }),\n allAudience: t(\"admin.dashboard.filters.allAudience\", {\n defaultValue: \"All audience\",\n }),\n audienceDomestic: t(\"explore.domestic\", { defaultValue: \"Domestic\" }),\n audienceForeign: t(\"explore.foreign\", { defaultValue: \"Foreign\" }),\n customDate: t(\"admin.dashboard.filters.customDate\", {\n defaultValue: \"Custom\",\n }),\n reset: t(\"admin.dashboard.filters.reset\", { defaultValue: \"Reset\" }),\n topSort: t(\"admin.dashboard.filters.topSort\", {\n defaultValue: \"Top packages sort\",\n }),\n sortBookings: t(\"admin.dashboard.filters.sortBookings\", {\n defaultValue: \"Bookings\",\n }),\n sortRevenue: t(\"admin.dashboard.filters.sortRevenue\", {\n defaultValue: \"Revenue\",\n }),\n sortDesc: t(\"admin.dashboard.filters.sortDesc\", { defaultValue: \"Desc\" }),\n sortAsc: t(\"admin.dashboard.filters.sortAsc\", { defaultValue: \"Asc\" }),\n confirmedBookings: t(\"admin.dashboard.cards.confirmedBookings\", {\n defaultValue: \"Confirmed Bookings\",\n }),\n confirmedRevenue: t(\"admin.dashboard.cards.confirmedRevenue\", {\n defaultValue: \"Revenue (Confirmed)\",\n }),\n avgRevenue: t(\"admin.dashboard.cards.avgRevenue\", {\n defaultValue: \"Avg Revenue / Booking\",\n }),\n conversionRate: t(\"admin.dashboard.cards.conversionRate\", {\n defaultValue: \"Conversion Rate\",\n }),\n totalProducts: t(\"admin.dashboard.cards.totalProducts\", {\n defaultValue: \"Total Products\",\n }),\n totalCustomers: t(\"admin.dashboard.cards.totalCustomers\", {\n defaultValue: \"Total Customers\",\n }),\n dailyTrends: t(\"admin.dashboard.sections.dailyTrends\", {\n defaultValue: \"Daily Trends\",\n }),\n statusDistribution: t(\"admin.dashboard.sections.statusDistribution\", {\n defaultValue: \"Status Distribution\",\n }),\n audienceDistribution: t(\"admin.dashboard.sections.audienceDistribution\", {\n defaultValue: \"Audience Distribution\",\n }),\n topPackages: t(\"admin.dashboard.sections.topPackages\", {\n defaultValue: \"Top Packages\",\n }),\n recentBookings: t(\"admin.dashboard.sections.recentBookings\", {\n defaultValue: \"Recent Bookings\",\n }),\n date: t(\"admin.dashboard.table.date\", { defaultValue: \"Date\" }),\n customer: t(\"admin.dashboard.table.customer\", { defaultValue: \"Customer\" }),\n package: t(\"admin.dashboard.table.package\", { defaultValue: \"Package\" }),\n audience: t(\"admin.dashboard.table.audience\", { defaultValue: \"Audience\" }),\n total: t(\"admin.dashboard.table.total\", { defaultValue: \"Total\" }),\n status: t(\"admin.dashboard.table.status\", { defaultValue: \"Status\" }),\n noRecentBookings: t(\"admin.dashboard.emptyRecent\", {\n defaultValue: \"No recent bookings\",\n }),\n bookingsMetric: t(\"admin.dashboard.metrics.bookings\", {\n defaultValue: \"Bookings\",\n }),\n revenueMetric: t(\"admin.dashboard.metrics.revenue\", {\n defaultValue: \"Revenue\",\n }),\n pendingMetric: t(\"admin.dashboard.metrics.pendingBookings\", {\n defaultValue: \"Bookings (Pending)\",\n }),\n confirmedBookingMetric: t(\"admin.dashboard.metrics.confirmedBookings\", {\n defaultValue: \"Bookings (Confirmed)\",\n }),\n confirmedRevenueMetric: t(\"admin.dashboard.metrics.confirmedRevenue\", {\n defaultValue: \"Revenue (Confirmed)\",\n }),\n unknownAudience: t(\"admin.dashboard.filters.unknownAudience\", {\n defaultValue: \"Unknown\",\n }),\n };\n\n labels.dayLabel = (count) =>\n t(\"admin.dashboard.filters.dayWindow\", {\n count,\n defaultValue: \"{{count}} days\",\n });\n\n labels.formatStatusLabel = (status) => {\n const normalized = String(status || \"pending\").toLowerCase();\n const defaultValue =\n normalized.charAt(0).toUpperCase() + normalized.slice(1);\n\n return t(`admin.dashboard.status.${normalized}`, { defaultValue });\n };\n\n labels.formatAudienceLabel = (value) => {\n if (value === \"domestic\") return labels.audienceDomestic;\n if (value === \"foreign\") return labels.audienceForeign;\n return labels.unknownAudience;\n };\n\n return labels;\n}\n"],"mappings":"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","names":["ensureNoError","import_react","import_react","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","MIN_YEAR","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","React","PropTypes","import_react","import_prop_types","import_react","import_prop_types","_a","sample","React","_b","PropTypes","React","_a","issues","PropTypes"]}
|