--- name: feature-guide description: Panduan implementasi masing-masing fitur utama Tour Planner App (Trip Selection, Schedule Builder, Packing List, Budget Calculator). Gunakan skill ini saat memulai atau melanjutkan pengerjaan satu halaman/fitur tertentu. --- # Skill: Feature Guide — Tour Planner App ## Fitur 1: Trip Selection (Home Page) **File:** `src/pages/Home.jsx` ### Alur User 1. User membuka aplikasi → landing di halaman Home 2. Bisa search destinasi atau browse dari grid card 3. Filter berdasarkan kategori dan budget 4. Klik card → modal konfirmasi trip (isi tanggal, nama trip) 5. Confirm → redirect ke `/schedule` ### Data yang Diperlukan ```javascript // src/data/destinations.js export const destinations = [ { id: 'bali-001', name: 'Bali', country: 'Indonesia', category: 'pantai', // 'pantai' | 'gunung' | 'kota' | 'budaya' description: 'Surga tropis...', highlights: ['Tanah Lot', 'Ubud', 'Kuta Beach'], estimatedBudget: { min: 2000000, max: 5000000 }, popularDuration: 4, // hari rating: 4.8, reviewCount: 12400, image: '/assets/bali.jpg', // atau URL picsum tags: ['romantis', 'budaya', 'alam'], bestTime: 'April - Oktober', }, // minimal 10 destinasi ]; ``` ### State yang Diupdate ```javascript setTrip({ id: destination.id, name: tripName, // input user destination: destination.name, startDate: startDate, // dari date picker endDate: endDate, totalDays: diffInDays(startDate, endDate) + 1, coverImage: destination.image, type: 'preset', category: destination.category, }); initSchedule(totalDays, startDate); // inisialisasi array schedule ``` ### Komponen yang Dibutuhkan - `TripCard.jsx` — card destinasi dengan image, info, hover effect - `TripSelector.jsx` — modal form input tanggal & nama trip - `SearchBar.jsx` — search dengan debounce - `FilterBar.jsx` — filter kategori (pills/tabs) --- ## Fitur 2: Daily Schedule Builder (Schedule Page) **File:** `src/pages/Schedule.jsx` ### Alur User 1. User masuk ke `/schedule` 2. Melihat tab per hari (Day 1, Day 2, ...) 3. Klik "+ Tambah Aktivitas" → modal form 4. Aktivitas ditampilkan di timeline vertikal 5. Bisa drag & drop untuk reorder ### Komponen yang Dibutuhkan - `DayTabs.jsx` — tab navigasi per hari - `ScheduleTimeline.jsx` — timeline visual - `ActivityItem.jsx` — satu item aktivitas (draggable) - `AddActivityModal.jsx` — form tambah/edit aktivitas ### Implementasi Drag & Drop ```jsx import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { SortableContext, verticalListSortingStrategy, arrayMove } from '@dnd-kit/sortable'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; // Di ActivityItem — tambahkan useSortable const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: activity.id }); const style = { transform: CSS.Transform.toString(transform), transition }; // Di ScheduleTimeline — wrap dengan DndContext {activities.map(a => )} ``` ### Template Aktivitas Cepat ```javascript // src/data/activities.js export const activityTemplates = [ { name: 'Sarapan', category: 'makan', duration: 60, defaultTime: '07:00' }, { name: 'Check-in Hotel', category: 'check-in', duration: 30, defaultTime: '14:00' }, { name: 'Makan Siang', category: 'makan', duration: 60, defaultTime: '12:00' }, { name: 'Makan Malam', category: 'makan', duration: 90, defaultTime: '18:30' }, { name: 'Kunjungan Wisata', category: 'wisata', duration: 120, defaultTime: '10:00' }, { name: 'Belanja Oleh-oleh', category: 'lainnya', duration: 60, defaultTime: '16:00' }, { name: 'Berangkat/Transportasi', category: 'transportasi', duration: 180, defaultTime: '06:00' }, ]; ``` --- ## Fitur 3: Packing List Manager (PackingList Page) **File:** `src/pages/PackingList.jsx` ### Alur User 1. User masuk ke `/packing` 2. Melihat daftar per kategori dengan progress 3. Centang item yang sudah dipak 4. Tambah item baru di kategori tertentu 5. Load template sesuai tipe trip ### Template Packing ```javascript // src/data/packingTemplates.js export const packingTemplates = { pantai: { Pakaian: [ { name: 'Baju pantai', qty: 3 }, { name: 'Celana pendek', qty: 2 }, { name: 'Kacamata hitam', qty: 1 }, ], // ... }, gunung: { /* ... */ }, kota: { /* ... */ }, budaya: { /* ... */ }, }; ``` ### Komponen yang Dibutuhkan - `PackingOverview.jsx` — statistik total item & progress keseluruhan - `PackingCategory.jsx` — section per kategori dengan sub-list - `PackingItem.jsx` — checkbox item + qty counter + delete ### Logic Progress ```javascript const getTotalStats = (packingList) => { let total = 0, checked = 0; Object.values(packingList).forEach(items => { items.forEach(item => { total++; if (item.checked) checked++; }); }); return { total, checked, percent: total > 0 ? Math.round((checked/total)*100) : 0 }; }; ``` --- ## Fitur 4: Budget Calculator (Budget Page) **File:** `src/pages/Budget.jsx` ### Alur User 1. User masuk ke `/budget` 2. Set total budget di bagian atas 3. Tambah pengeluaran satu per satu 4. Melihat ringkasan dan chart 5. Warning merah jika over budget ### Komponen yang Dibutuhkan - `BudgetHeader.jsx` — input total budget + overview card (total, spent, remaining) - `BudgetChart.jsx` — Recharts PieChart + BarChart - `ExpenseList.jsx` — list semua pengeluaran - `AddExpenseModal.jsx` — form tambah pengeluaran ### Recharts Integration ```jsx import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer, BarChart, Bar, XAxis, YAxis } from 'recharts'; // Data untuk pie chart const pieData = Object.entries(byCategory).map(([name, value]) => ({ name, value })); {pieData.map((entry, index) => ( ))} formatIDR(value)} /> ``` ### Format Currency ```javascript // src/utils/formatCurrency.js export const formatIDR = (amount) => new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }).format(amount); export const formatUSD = (amount) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount); ``` --- ## Navigasi Antar Halaman ``` / (Home) → pilih trip /schedule → jadwal harian /packing → packing list /budget → kalkulasi budget ``` Navbar harus selalu tampil dan menampilkan: - Logo / nama app - Link ke semua 4 halaman - Indikator halaman aktif - Badge progress (% packing done, budget status)