// data.jsx — INDIECASH demo scenarios (single / couple / family) // Each scenario seeds: family, members, accounts, categories, transactions, // budgets, goals, debts, activity feed. // ─── Category catalog ──────────────────────────────────────────── // Lucide icon names (loaded via CDN). Color is the brand-level hint — // shown as soft tinted disc, never as bold fills (Jenius vibe). const CATEGORIES = { // Income gaji: { id: 'gaji', kind: 'income', label: 'Gaji', icon: 'briefcase', color: '#10b981' }, bonus: { id: 'bonus', kind: 'income', label: 'Bonus', icon: 'gift', color: '#14b8a6' }, freelance: { id: 'freelance', kind: 'income', label: 'Freelance', icon: 'laptop', color: '#0ea5e9' }, investasi: { id: 'investasi', kind: 'income', label: 'Investasi', icon: 'trending-up', color: '#8b5cf6' }, lainnya_in: { id: 'lainnya_in', kind: 'income', label: 'Lainnya', icon: 'plus-circle', color: '#64748b' }, // Expense makan: { id: 'makan', kind: 'expense', label: 'Makan', icon: 'utensils', color: '#f59e0b' }, belanja: { id: 'belanja', kind: 'expense', label: 'Belanja', icon: 'shopping-bag', color: '#ec4899' }, transport: { id: 'transport', kind: 'expense', label: 'Transport', icon: 'car', color: '#3b82f6' }, tagihan: { id: 'tagihan', kind: 'expense', label: 'Tagihan', icon: 'receipt', color: '#ef4444' }, hiburan: { id: 'hiburan', kind: 'expense', label: 'Hiburan', icon: 'film', color: '#a855f7' }, kesehatan: { id: 'kesehatan', kind: 'expense', label: 'Kesehatan', icon: 'heart-pulse', color: '#f43f5e' }, pendidikan: { id: 'pendidikan', kind: 'expense', label: 'Pendidikan', icon: 'graduation-cap', color: '#06b6d4' }, rumah: { id: 'rumah', kind: 'expense', label: 'Rumah', icon: 'home', color: '#84cc16' }, anak: { id: 'anak', kind: 'expense', label: 'Anak', icon: 'baby', color: '#fb7185' }, hadiah: { id: 'hadiah', kind: 'expense', label: 'Hadiah', icon: 'gift', color: '#d946ef' }, donasi: { id: 'donasi', kind: 'expense', label: 'Donasi', icon: 'hand-heart', color: '#10b981' }, transfer: { id: 'transfer', kind: 'expense', label: 'Transfer', icon: 'arrow-right-left', color: '#0d9488' }, lainnya_ex: { id: 'lainnya_ex', kind: 'expense', label: 'Lainnya', icon: 'more-horizontal', color: '#64748b' }, }; // ─── Member avatar helpers ─────────────────────────────────────── // Solid colored disc with initials — matches the INDIE Group circular-badge // vocabulary without redrawing each face. Hue is stable per member. function memberInitials(name) { if (!name || typeof name !== 'string') return '?'; const parts = name.trim().split(/\s+/); if (!parts[0]) return '?'; return (parts[0][0] + (parts[1]?.[0] || '')).toUpperCase(); } // ─── Scenarios ────────────────────────────────────────────────── // Three scenarios. Each describes a `Keluarga` with N members and a slice // of life — bills, salaries, kids, debts, goals. Numbers are realistic // Jakarta middle-class figures (Rp 8-25 jt/month spend), not generic. const SCENARIOS = { // ── 1. PASANGAN MUDA — 2 people, no kids, dual income ───────── couple: { id: 'couple', label: 'Pasangan Muda', family: { name: 'Keluarga Wijaya', code: 'WIJAYA-2024' }, members: [ { id: 'm1', name: 'Budi Wijaya', short: 'Budi', role: 'Suami', color: '#0d9488' }, { id: 'm2', name: 'Sari Wijaya', short: 'Sari', role: 'Istri', color: '#ec4899' }, ], balance: 18_420_000, monthlyIncome: 22_500_000, monthlyExpense: 14_800_000, monthlySavings: 7_700_000, // 7-day chart series (expense per day, oldest → newest) week: [320_000, 580_000, 145_000, 720_000, 410_000, 950_000, 285_000], weekLabels: ['Sen','Sel','Rab','Kam','Jum','Sab','Min'], // Budgets for the current month budgets: [ { cat: 'makan', limit: 3_500_000, used: 2_180_000 }, { cat: 'transport', limit: 1_500_000, used: 1_240_000 }, { cat: 'belanja', limit: 2_000_000, used: 1_950_000 }, { cat: 'hiburan', limit: 1_000_000, used: 460_000 }, { cat: 'tagihan', limit: 2_800_000, used: 2_800_000 }, { cat: 'kesehatan', limit: 800_000, used: 120_000 }, ], goals: [ { id: 'g1', name: 'Honeymoon Bali', emoji: '🏝️', target: 18_000_000, saved: 12_400_000, due: '2026-08-01', contribs: [{ m: 'm1', v: 7_400_000 }, { m: 'm2', v: 5_000_000 }] }, { id: 'g2', name: 'DP Apartemen', emoji: '🏢', target: 150_000_000, saved: 42_800_000, due: '2027-06-01', contribs: [{ m: 'm1', v: 25_000_000 }, { m: 'm2', v: 17_800_000 }] }, { id: 'g3', name: 'Dana Darurat', emoji: '🛟', target: 60_000_000, saved: 38_200_000, due: '2026-12-31', contribs: [{ m: 'm1', v: 20_000_000 }, { m: 'm2', v: 18_200_000 }] }, ], debts: [ { id: 'd1', kind: 'hutang', who: 'Mama', amount: 5_000_000, note: 'Pinjaman renov dapur', due: '2026-07-15', status: 'pending' }, { id: 'd2', kind: 'piutang', who: 'Andi (kakak)', amount: 2_500_000, note: 'Talangin tiket pesawat', due: '2026-06-30', status: 'pending' }, { id: 'd3', kind: 'piutang', who: 'Rina', amount: 750_000, note: 'Patungan kado mama', due: '2026-06-10', status: 'overdue' }, ], // Most recent first transactions: [ { id: 't1', kind: 'expense', cat: 'makan', by: 'm2', amount: 142_000, note: 'Brunch di Common Grounds', date: '2026-05-26T11:20:00' }, { id: 't2', kind: 'expense', cat: 'transport', by: 'm1', amount: 58_000, note: 'Gojek ke kantor', date: '2026-05-26T08:15:00' }, { id: 't3', kind: 'income', cat: 'gaji', by: 'm1', amount: 12_500_000, note: 'Gaji Mei', date: '2026-05-25T09:00:00' }, { id: 't4', kind: 'expense', cat: 'belanja', by: 'm2', amount: 680_000, note: 'Groceries weekly', date: '2026-05-25T17:40:00' }, { id: 't5', kind: 'expense', cat: 'hiburan', by: 'm1', amount: 220_000, note: 'Netflix + Spotify', date: '2026-05-24T20:00:00' }, { id: 't6', kind: 'expense', cat: 'tagihan', by: 'm1', amount: 1_450_000, note: 'Listrik + internet', date: '2026-05-23T10:30:00' }, { id: 't7', kind: 'expense', cat: 'makan', by: 'm1', amount: 185_000, note: 'Dinner anniversary', date: '2026-05-22T19:45:00' }, { id: 't8', kind: 'income', cat: 'freelance', by: 'm2', amount: 3_800_000, note: 'Proyek logo client', date: '2026-05-21T15:00:00' }, { id: 't9', kind: 'expense', cat: 'kesehatan', by: 'm2', amount: 120_000, note: 'Vitamin & masker', date: '2026-05-20T14:20:00' }, { id: 't10', kind: 'expense', cat: 'transport', by: 'm2', amount: 320_000, note: 'Bensin mobil', date: '2026-05-19T08:00:00' }, ], activity: [ { id: 'a1', m: 'm2', verb: 'tambah pengeluaran', what: 'Brunch · Rp 142.000', ts: '2026-05-26T11:20:00' }, { id: 'a2', m: 'm1', verb: 'catat gaji', what: 'Gaji Mei · Rp 12.500.000', ts: '2026-05-25T09:00:00' }, { id: 'a3', m: 'm2', verb: 'update goal', what: 'Honeymoon Bali +Rp 800.000', ts: '2026-05-24T21:10:00' }, { id: 'a4', m: 'm1', verb: 'bayar tagihan', what: 'Listrik + internet · Rp 1.450.000', ts: '2026-05-23T10:30:00' }, ], }, // ── 2. KELUARGA MUDA — 2 parents + toddler ──────────────────── young: { id: 'young', label: 'Keluarga Muda', family: { name: 'Keluarga Pratama', code: 'PRATAMA-9981' }, members: [ { id: 'm1', name: 'Rizki Pratama', short: 'Rizki', role: 'Suami', color: '#0d9488' }, { id: 'm2', name: 'Dewi Pratama', short: 'Dewi', role: 'Istri', color: '#d946ef' }, { id: 'm3', name: 'Kayla Pratama', short: 'Kayla', role: 'Anak', color: '#f59e0b' }, ], balance: 24_650_000, monthlyIncome: 28_400_000, monthlyExpense: 21_200_000, monthlySavings: 7_200_000, week: [450_000, 820_000, 380_000, 1_240_000, 690_000, 1_580_000, 540_000], weekLabels: ['Sen','Sel','Rab','Kam','Jum','Sab','Min'], budgets: [ { cat: 'makan', limit: 4_500_000, used: 3_280_000 }, { cat: 'anak', limit: 3_000_000, used: 3_350_000 }, // over { cat: 'transport', limit: 2_000_000, used: 1_640_000 }, { cat: 'belanja', limit: 2_500_000, used: 2_100_000 }, { cat: 'tagihan', limit: 3_200_000, used: 3_180_000 }, { cat: 'kesehatan', limit: 1_200_000, used: 480_000 }, { cat: 'hiburan', limit: 800_000, used: 320_000 }, ], goals: [ { id: 'g1', name: 'Dana Pendidikan Kayla', emoji: '🎓', target: 200_000_000, saved: 48_500_000, due: '2031-07-01', contribs: [{ m: 'm1', v: 28_000_000 }, { m: 'm2', v: 20_500_000 }] }, { id: 'g2', name: 'Liburan Jepang', emoji: '🗾', target: 45_000_000, saved: 18_200_000, due: '2026-12-20', contribs: [{ m: 'm1', v: 10_000_000 }, { m: 'm2', v: 8_200_000 }] }, { id: 'g3', name: 'Ganti Mobil', emoji: '🚗', target: 280_000_000, saved: 92_000_000, due: '2027-12-31', contribs: [{ m: 'm1', v: 60_000_000 }, { m: 'm2', v: 32_000_000 }] }, { id: 'g4', name: 'Dana Darurat 6 bulan', emoji: '🛟', target: 120_000_000, saved: 75_400_000, due: '2026-12-31', contribs: [{ m: 'm1', v: 42_000_000 }, { m: 'm2', v: 33_400_000 }] }, ], debts: [ { id: 'd1', kind: 'hutang', who: 'KPR BCA', amount: 18_500_000, note: 'Cicilan KPR Juni', due: '2026-06-05', status: 'pending' }, { id: 'd2', kind: 'hutang', who: 'Papa', amount: 8_000_000, note: 'Pinjaman renov kamar bayi', due: '2026-09-01', status: 'pending' }, { id: 'd3', kind: 'piutang', who: 'Tante Lisa', amount: 1_200_000, note: 'Beli stroller bareng', due: '2026-06-15', status: 'pending' }, { id: 'd4', kind: 'piutang', who: 'Bayu', amount: 500_000, note: 'Tiket konser', due: '2026-05-20', status: 'overdue' }, ], transactions: [ { id: 't1', kind: 'expense', cat: 'anak', by: 'm2', amount: 485_000, note: 'Popok + susu formula', date: '2026-05-26T10:30:00' }, { id: 't2', kind: 'expense', cat: 'makan', by: 'm1', amount: 72_000, note: 'Kopi pagi', date: '2026-05-26T07:45:00' }, { id: 't3', kind: 'income', cat: 'gaji', by: 'm1', amount: 16_500_000, note: 'Gaji Mei', date: '2026-05-25T09:00:00' }, { id: 't4', kind: 'expense', cat: 'belanja', by: 'm2', amount: 920_000, note: 'Groceries + ASIP', date: '2026-05-25T16:00:00' }, { id: 't5', kind: 'expense', cat: 'tagihan', by: 'm1', amount: 3_180_000, note: 'Listrik+air+internet+TV', date: '2026-05-24T08:30:00' }, { id: 't6', kind: 'expense', cat: 'kesehatan', by: 'm2', amount: 340_000, note: 'Imunisasi Kayla', date: '2026-05-23T14:00:00' }, { id: 't7', kind: 'income', cat: 'freelance', by: 'm2', amount: 5_400_000, note: 'Konsultasi desain', date: '2026-05-22T11:00:00' }, { id: 't8', kind: 'expense', cat: 'transport', by: 'm1', amount: 520_000, note: 'Bensin + tol', date: '2026-05-21T18:00:00' }, { id: 't9', kind: 'expense', cat: 'makan', by: 'm1', amount: 248_000, note: 'Dinner keluarga', date: '2026-05-20T19:30:00' }, { id: 't10', kind: 'expense', cat: 'anak', by: 'm2', amount: 1_250_000, note: 'Daycare bulan ini', date: '2026-05-19T09:00:00' }, ], activity: [ { id: 'a1', m: 'm2', verb: 'tambah pengeluaran', what: 'Popok + susu · Rp 485.000', ts: '2026-05-26T10:30:00' }, { id: 'a2', m: 'm1', verb: 'catat gaji', what: 'Gaji Mei · Rp 16.500.000', ts: '2026-05-25T09:00:00' }, { id: 'a3', m: 'm2', verb: 'lewat budget', what: 'Anak Rp 350.000 over', ts: '2026-05-25T16:01:00' }, { id: 'a4', m: 'm2', verb: 'update goal', what: 'Liburan Jepang +Rp 1.500.000', ts: '2026-05-22T20:00:00' }, ], }, // ── 3. KELUARGA DEWASA — 2 parents + 2 teens ────────────────── mature: { id: 'mature', label: 'Keluarga Dewasa', family: { name: 'Keluarga Santosa', code: 'SANTOSA-5512' }, members: [ { id: 'm1', name: 'Hendra Santosa', short: 'Hendra', role: 'Suami', color: '#0d9488' }, { id: 'm2', name: 'Maya Santosa', short: 'Maya', role: 'Istri', color: '#a855f7' }, { id: 'm3', name: 'Aldo Santosa', short: 'Aldo', role: 'Anak', color: '#3b82f6' }, { id: 'm4', name: 'Nadia Santosa', short: 'Nadia', role: 'Anak', color: '#f43f5e' }, ], balance: 41_280_000, monthlyIncome: 48_000_000, monthlyExpense: 36_500_000, monthlySavings: 11_500_000, week: [890_000, 1_240_000, 720_000, 2_140_000, 1_580_000, 2_890_000, 980_000], weekLabels: ['Sen','Sel','Rab','Kam','Jum','Sab','Min'], budgets: [ { cat: 'makan', limit: 6_000_000, used: 4_820_000 }, { cat: 'pendidikan', limit: 8_500_000, used: 8_500_000 }, // 100% { cat: 'transport', limit: 3_500_000, used: 2_940_000 }, { cat: 'belanja', limit: 4_000_000, used: 3_680_000 }, { cat: 'tagihan', limit: 5_200_000, used: 5_080_000 }, { cat: 'kesehatan', limit: 2_000_000, used: 840_000 }, { cat: 'hiburan', limit: 1_800_000, used: 1_240_000 }, { cat: 'rumah', limit: 2_500_000, used: 2_180_000 }, ], goals: [ { id: 'g1', name: 'Kuliah Aldo (UI)', emoji: '🎓', target: 250_000_000, saved: 182_000_000, due: '2027-08-01', contribs: [{ m: 'm1', v: 110_000_000 }, { m: 'm2', v: 72_000_000 }] }, { id: 'g2', name: 'Pernikahan Nadia', emoji: '💍', target: 350_000_000, saved: 68_500_000, due: '2030-06-01', contribs: [{ m: 'm1', v: 40_000_000 }, { m: 'm2', v: 28_500_000 }] }, { id: 'g3', name: 'Pensiun di Bali', emoji: '🌴', target: 2_500_000_000, saved: 845_000_000, due: '2035-01-01', contribs: [{ m: 'm1', v: 520_000_000 }, { m: 'm2', v: 325_000_000 }] }, { id: 'g4', name: 'Umroh Sekeluarga', emoji: '🕌', target: 180_000_000, saved: 92_000_000, due: '2027-03-15', contribs: [{ m: 'm1', v: 52_000_000 }, { m: 'm2', v: 40_000_000 }] }, ], debts: [ { id: 'd1', kind: 'hutang', who: 'KPR Mandiri', amount: 22_400_000, note: 'Cicilan Juni', due: '2026-06-05', status: 'pending' }, { id: 'd2', kind: 'hutang', who: 'Kredit Mobil', amount: 6_800_000, note: 'Cicilan Innova', due: '2026-06-10', status: 'pending' }, { id: 'd3', kind: 'piutang', who: 'Pak Tono', amount: 15_000_000, note: 'Investasi warung kopi', due: '2026-09-01', status: 'pending' }, { id: 'd4', kind: 'piutang', who: 'Bu Rini', amount: 3_200_000, note: 'Pinjaman umroh', due: '2026-05-15', status: 'overdue' }, ], transactions: [ { id: 't1', kind: 'expense', cat: 'pendidikan', by: 'm2', amount: 4_500_000, note: 'SPP Nadia bulan ini', date: '2026-05-26T09:00:00' }, { id: 't2', kind: 'expense', cat: 'makan', by: 'm1', amount: 95_000, note: 'Makan siang kantor', date: '2026-05-26T12:30:00' }, { id: 't3', kind: 'expense', cat: 'transport', by: 'm3', amount: 45_000, note: 'Ojol pulang sekolah', date: '2026-05-26T15:40:00' }, { id: 't4', kind: 'income', cat: 'gaji', by: 'm1', amount: 32_000_000, note: 'Gaji Mei', date: '2026-05-25T09:00:00' }, { id: 't5', kind: 'expense', cat: 'belanja', by: 'm2', amount: 1_240_000, note: 'Groceries weekly', date: '2026-05-25T17:30:00' }, { id: 't6', kind: 'expense', cat: 'tagihan', by: 'm1', amount: 5_080_000, note: 'Listrik+air+internet+TV+pulsa', date: '2026-05-24T08:00:00' }, { id: 't7', kind: 'expense', cat: 'pendidikan', by: 'm2', amount: 4_000_000, note: 'Les Aldo (UTBK)', date: '2026-05-23T16:00:00' }, { id: 't8', kind: 'expense', cat: 'hiburan', by: 'm4', amount: 320_000, note: 'Konser sama temen', date: '2026-05-22T20:00:00' }, { id: 't9', kind: 'income', cat: 'investasi', by: 'm1', amount: 2_800_000, note: 'Dividen reksadana', date: '2026-05-21T10:00:00' }, { id: 't10', kind: 'expense', cat: 'rumah', by: 'm2', amount: 1_450_000, note: 'Service AC + tukang', date: '2026-05-20T11:00:00' }, ], activity: [ { id: 'a1', m: 'm2', verb: 'bayar SPP', what: 'SPP Nadia · Rp 4.500.000', ts: '2026-05-26T09:00:00' }, { id: 'a2', m: 'm3', verb: 'tambah pengeluaran', what: 'Ojol · Rp 45.000', ts: '2026-05-26T15:40:00' }, { id: 'a3', m: 'm1', verb: 'catat gaji', what: 'Gaji Mei · Rp 32.000.000', ts: '2026-05-25T09:00:00' }, { id: 'a4', m: 'm1', verb: 'budget tercapai', what: 'Pendidikan 100% terpakai', ts: '2026-05-23T16:01:00' }, ], }, }; // Member lookup helper — used everywhere transactions render function getMember(scenario, id) { return scenario.members.find((m) => m.id === id); } Object.assign(window, { CATEGORIES, SCENARIOS, memberInitials, getMember, });