auto winn

This commit is contained in:
Faizulhaq F.N
2026-08-27 19:45:15 +07:00
commit f5a633227f
66 changed files with 11576 additions and 0 deletions
+186
View File
@@ -0,0 +1,186 @@
# Coding Standards — Tour Planner App
Aturan ini berlaku untuk semua kode yang ditulis dalam proyek ini.
AI agent wajib mengikuti seluruh aturan di bawah ini.
---
## 1. Struktur Komponen
```jsx
// ✅ BENAR — Functional component dengan arrow function
const MyComponent = ({ prop1, prop2 }) => {
// hooks di atas
// logic di tengah
// return di bawah
return <div />;
};
export default MyComponent;
// ❌ SALAH — Jangan gunakan class component
class MyComponent extends React.Component { }
```
---
## 2. Styling
```jsx
// ✅ BENAR — CSS variables dari design system
<div style={{ color: 'var(--color-text-primary)', padding: 'var(--space-4)' }}>
// ✅ BENAR — className dengan class yang didefinisikan di CSS
<div className="glass section-title">
// ❌ SALAH — Hardcode warna
<div style={{ color: '#ffffff', backgroundColor: '#1a1a2e' }}>
// ❌ SALAH — TailwindCSS
<div className="text-white bg-gray-900 p-4">
```
---
## 3. State Management
```javascript
// ✅ BENAR — Gunakan Zustand store untuk state yang di-share
const { schedule, addActivity } = useTourStore();
// ✅ BENAR — useState untuk state lokal (form, toggle)
const [isOpen, setIsOpen] = useState(false);
// ❌ SALAH — Prop drilling lebih dari 2 level
<A> <B prop={x}> <C prop={x}> <D prop={x} />
```
---
## 4. Animasi
```jsx
// ✅ BENAR — Selalu gunakan Framer Motion
import { motion } from 'framer-motion';
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
// ❌ SALAH — Animasi manual
setTimeout(() => setVisible(true), 100);
element.style.transition = 'opacity 0.3s';
```
---
## 5. Icons
```jsx
// ✅ BENAR — Lucide React
import { MapPin, Calendar, Plane } from 'lucide-react';
<MapPin size={20} />
// ❌ SALAH — Emoji sebagai icon UI
<span>📍</span>
// ❌ SALAH — SVG inline tanpa abstraksi
<svg xmlns="..." viewBox="..."><path d="..." /></svg>
```
---
## 6. Data & Constants
```javascript
// ✅ BENAR — Data di src/data/
import { destinations } from '../data/destinations';
import { CATEGORY_COLORS } from '../data/constants';
// ❌ SALAH — Data hardcode di dalam komponen
const destinations = [{ name: 'Bali', ... }]; // dalam file .jsx
```
---
## 7. File Naming
| Tipe | Convention | Contoh |
|------|------------|--------|
| Component | PascalCase | `TripCard.jsx` |
| Hook | camelCase dengan "use" prefix | `useBudget.js` |
| Utility | camelCase | `formatCurrency.js` |
| Data file | camelCase | `destinations.js` |
| CSS | kebab-case | `trip-card.css` |
---
## 8. Import Order
```javascript
// 1. React & hooks
import { useState, useEffect } from 'react';
// 2. Third-party libraries
import { motion, AnimatePresence } from 'framer-motion';
import { MapPin } from 'lucide-react';
// 3. Internal store & hooks
import { useTourStore } from '../store/tourStore';
import { useBudget } from '../hooks/useBudget';
// 4. Components
import Button from '../components/ui/Button';
import TripCard from '../components/trip/TripCard';
// 5. Data & utils
import { destinations } from '../data/destinations';
import { formatIDR } from '../utils/formatCurrency';
// 6. Styles (jika ada)
import './ComponentName.css';
```
---
## 9. Performance
- Gunakan `useMemo` untuk kalkulasi berat (total budget, statistik packing)
- Gunakan `useCallback` untuk handler yang di-pass sebagai prop
- Gunakan `React.memo` untuk komponen list item yang berat
- Jangan lakukan side effect tanpa `useEffect`
---
## 10. Batasan Fitur (TIDAK BOLEH DILANGGAR)
| Larangan | Alasan |
|----------|--------|
| ❌ Login / Logout | Aplikasi ini sepenuhnya static & lokal |
| ❌ API call ke backend | Tidak ada server, semua data lokal |
| ❌ Menyimpan password atau data sensitif | Tidak ada autentikasi |
| ❌ TailwindCSS | Gunakan vanilla CSS + CSS variables |
| ❌ jQuery atau manipulasi DOM manual | Gunakan React state |
| ❌ `console.log` di production code | Hapus sebelum commit |
---
## 11. Aksesibilitas (Minimum Requirements)
- Semua tombol punya `aria-label` jika tidak ada teks
- Semua form field punya `<label>` yang terhubung
- Warna kontras minimum 4.5:1 untuk teks
- Keyboard navigable untuk modal (focus trap)
---
## 12. Error Handling
```javascript
// Selalu handle edge case
const totalDays = trip?.totalDays ?? 0;
const activities = schedule[dayIndex]?.activities ?? [];
// Jangan biarkan crash karena undefined
// ❌
const name = trip.name.toUpperCase(); // crash jika trip.name null
// ✅
const name = trip?.name?.toUpperCase() ?? 'Unnamed Trip';
```
+353
View File
@@ -0,0 +1,353 @@
# Phase Workflow Rules — Tour Planner App
> Aturan ini mengatur bagaimana setiap fitur harus dikerjakan secara berurutan.
> AI agent WAJIB mengikuti fase ini dan TIDAK BOLEH melompat fase tanpa alasan yang jelas.
---
## ⚠️ Prinsip Utama
1. **Satu fase harus selesai sebelum masuk ke fase berikutnya.**
2. **Setiap akhir fase, update `task.md`** untuk mencatat progress.
3. **Jangan mulai phase baru jika phase sebelumnya masih ada item `[ ]`.**
4. **Validasi output setiap phase sebelum lanjut.**
---
## 🗂️ Phase 0 — Project Setup (WAJIB DIKERJAKAN PERTAMA)
> Fondasi project. Tidak ada komponen atau page yang boleh dibuat sebelum phase ini selesai.
### Checklist Phase 0
- [ ] **0.1** — Inisialisasi Vite + React
```bash
npm create vite@latest . -- --template react
npm install
```
- [ ] **0.2** — Install semua dependencies sekaligus
```bash
npm install react-router-dom zustand framer-motion lucide-react recharts @dnd-kit/core @dnd-kit/sortable date-fns
```
- [ ] **0.3** — Buat `src/index.css` dengan SEMUA CSS variables (lihat skill `ui-design`)
- [ ] **0.4** — Buat `src/store/tourStore.js` dengan full Zustand store + persist middleware
- [ ] **0.5** — Setup React Router di `src/App.jsx` dengan semua 4 routes
- [ ] **0.6** — Buat file data dummy:
- `src/data/destinations.js` (min. 10 destinasi)
- `src/data/activities.js` (template aktivitas)
- `src/data/packingTemplates.js` (template per tipe trip)
- [ ] **0.7** — Buat utility functions:
- `src/utils/formatCurrency.js`
- `src/utils/dateHelpers.js`
- `src/utils/helpers.js` (generateId, dll.)
### Validasi Phase 0
- `npm run dev` harus berjalan tanpa error
- Route `/`, `/schedule`, `/packing`, `/budget` harus bisa diakses
- Zustand store harus bisa di-import dari semua page
- CSS variables harus aktif (cek di browser DevTools)
---
## 🧱 Phase 1 — Layout & UI Components
> Membangun blok bangunan dasar yang akan dipakai semua page.
> Jangan buat page dulu sebelum komponen UI dasar selesai.
### Checklist Phase 1
#### 1A — Layout Components
- [ ] **1A.1** — `src/components/layout/Navbar.jsx`
- Logo + nama app
- Link navigasi ke 4 halaman
- Indikator halaman aktif
- Responsif (hamburger menu di mobile)
- [ ] **1A.2** — `src/components/layout/PageWrapper.jsx`
- Wrapper umum untuk semua page
- Padding, max-width, fade-in animation
#### 1B — UI Components Dasar
- [ ] **1B.1** — `src/components/ui/Button.jsx`
- Props: `variant` (primary/secondary/ghost/danger), `size` (sm/md/lg), `icon`, `loading`, `disabled`
- [ ] **1B.2** — `src/components/ui/Card.jsx`
- Props: `glassmorphism`, `hoverable`, `onClick`
- [ ] **1B.3** — `src/components/ui/Modal.jsx`
- Props: `isOpen`, `onClose`, `title`
- Focus trap, backdrop click close, escape key
- Framer Motion animation (scalePop)
- [ ] **1B.4** — `src/components/ui/Badge.jsx`
- Props: `variant` (primary/success/warning/danger)
- [ ] **1B.5** — `src/components/ui/ProgressBar.jsx`
- Props: `value` (0-100), `label`, `showPercent`, `color`
- Animated fill dengan Framer Motion
- [ ] **1B.6** — `src/components/ui/EmptyState.jsx`
- Tampil saat list kosong, dengan ilustrasi dan CTA
### Validasi Phase 1
- Semua komponen bisa di-render tanpa crash
- Tidak ada hardcode warna (semua pakai CSS variables)
- Modal bisa dibuka dan ditutup dengan keyboard (Escape)
- Navbar menampilkan halaman aktif dengan benar
---
## 🏠 Phase 2 — Home Page (Trip Selection)
> Feature pertama. Harus selesai sebelum page lain karena trip yang dipilih
> menentukan data yang dipakai di semua page lainnya.
### Checklist Phase 2
#### 2A — Hero Section
- [ ] **2A.1** — Hero dengan background gradient + animated particles atau subtle pattern
- [ ] **2A.2** — Headline besar dengan `Playfair Display` font
- [ ] **2A.3** — Subtitle dan CTA button "Mulai Rencanakan"
- [ ] **2A.4** — Search bar dengan placeholder animasi
#### 2B — Filter & Grid Destinasi
- [ ] **2B.1** — `FilterBar.jsx` — filter pills: Semua / Pantai / Gunung / Kota / Budaya
- [ ] **2B.2** — `TripCard.jsx` — card dengan:
- Gambar destinasi (16:9 ratio)
- Nama, negara, rating
- Estimasi budget range
- Durasi populer
- Tags/badge kategori
- Hover effect (scale + overlay)
- [ ] **2B.3** — Grid responsif 4→3→2→1 kolom
- [ ] **2B.4** — Animasi stagger pada grid item
#### 2C — Trip Configuration Modal
- [ ] **2C.1** — Modal terbuka saat klik TripCard
- [ ] **2C.2** — Form: Nama Trip, Tanggal Mulai, Tanggal Selesai
- [ ] **2C.3** — Auto-hitung total hari dari range tanggal
- [ ] **2C.4** — Tombol "Buat Trip Kustom" (tanpa pilih destinasi preset)
- [ ] **2C.5** — Konfirmasi → update Zustand store → redirect ke `/schedule`
### Validasi Phase 2
- Semua destinasi tampil di grid
- Filter berfungsi (klik kategori → grid berubah)
- Search berfungsi (filter by name)
- Modal terbuka dengan animasi
- Setelah konfirmasi, `useTourStore().trip` terisi dengan benar
- Data trip tersimpan di localStorage
---
## 📅 Phase 3 — Schedule Builder Page
> Fitur drag & drop. Ini yang paling complex — kerjakan dengan hati-hati.
### Checklist Phase 3
#### 3A — Day Navigation
- [ ] **3A.1** — `DayTabs.jsx` — tabs untuk setiap hari
- Day 1, Day 2, ..., Day N (sesuai `trip.totalDays`)
- Tampilkan tanggal di bawah label hari
- Active state yang jelas
- Scrollable jika banyak hari
- [ ] **3A.2** — Guard: Jika trip belum dikonfigurasi, tampilkan prompt ke Home
#### 3B — Timeline View
- [ ] **3B.1** — `ScheduleTimeline.jsx` — timeline vertikal
- Jam dari 06:00 - 23:00 di sisi kiri
- Aktivitas diposisikan sesuai waktu
- [ ] **3B.2** — `ActivityItem.jsx` — satu item:
- Warna berdasarkan kategori
- Waktu, nama, lokasi, durasi
- Drag handle (ikon GripVertical)
- Tombol edit & hapus
- [ ] **3B.3** — Placeholder "Belum ada aktivitas" dengan CTA tambah
#### 3C — Add/Edit Activity
- [ ] **3C.1** — `AddActivityModal.jsx` — form:
- Time picker (HH:MM)
- Nama aktivitas
- Lokasi
- Durasi (menit)
- Kategori (dropdown/pills)
- Catatan (textarea)
- [ ] **3C.2** — Template aktivitas cepat (chip/button, klik → auto-isi form)
- [ ] **3C.3** — Edit mode: modal ter-preisi dengan data yang ada
#### 3D — Drag & Drop
- [ ] **3D.1** — Sortable dalam satu hari (reorder aktivitas)
- [ ] **3D.2** — Update state setelah drag selesai
- [ ] **3D.3** — Visual feedback saat dragging (opacity, scale)
### Validasi Phase 3
- Tabs menampilkan jumlah hari yang benar sesuai trip
- Tambah aktivitas → muncul di timeline
- Hapus aktivitas → hilang dari timeline
- Drag & drop mengubah urutan dan tersimpan
- Data persist setelah refresh browser
---
## 🎒 Phase 4 — Packing List Page
> Fitur yang relatif straightforward. Fokus pada UX checklist yang satisfying.
### Checklist Phase 4
#### 4A — Overview & Progress
- [ ] **4A.1** — `PackingOverview.jsx`:
- Total item / item yang sudah dipak
- ProgressBar keseluruhan (animated)
- Badge status: "Belum dimulai" / "Sedang dikemas" / "Siap Berangkat!"
- [ ] **4A.2** — Tombol "Load Template" berdasarkan tipe trip
#### 4B — Kategori & Item
- [ ] **4B.1** — `PackingCategory.jsx`:
- Header kategori dengan icon dan jumlah item
- Collapsible (klik header → expand/collapse)
- Progress mini per kategori
- [ ] **4B.2** — `PackingItem.jsx`:
- Checkbox dengan animasi checkmark (Framer Motion)
- Nama item (strikethrough jika checked)
- Quantity counter (- / angka / +)
- Tombol hapus
- [ ] **4B.3** — Inline add item per kategori (input + tombol "+")
#### 4C — Interaksi & UX
- [ ] **4C.1** — "Check All" / "Uncheck All" per kategori
- [ ] **4C.2** — Sort: unchecked items tampil di atas
- [ ] **4C.3** — Animasi item saat di-check (smooth height collapse jika sorted)
- [ ] **4C.4** — Konfetti/celebrasi kecil saat 100% selesai
### Validasi Phase 4
- Load template mengisi item sesuai tipe trip
- Checkbox berfungsi dan tersimpan di localStorage
- Progress bar update real-time saat item di-check
- Tambah item baru muncul di kategori yang tepat
- Quantity counter mengubah nilai dengan benar
---
## 💰 Phase 5 — Budget Calculator Page
> Fitur terakhir. Fokus pada visual chart dan feedback yang jelas.
### Checklist Phase 5
#### 5A — Budget Overview Header
- [ ] **5A.1** — Input total budget (editable, format IDR)
- [ ] **5A.2** — 3 stat card: Total Budget / Total Terpakai / Sisa
- Warna Sisa: hijau (cukup), kuning (hampir habis), merah (over)
- [ ] **5A.3** — Progress bar: % budget terpakai
- [ ] **5A.4** — Warning banner jika over budget
#### 5B — Chart Visualisasi
- [ ] **5B.1** — `PieChart` — distribusi per kategori (Recharts)
- Custom tooltip dengan format IDR
- Legend dengan warna kategori
- [ ] **5B.2** — `BarChart` — pengeluaran per hari (Recharts)
- X axis: hari ke-N
- Y axis: jumlah IDR
#### 5C — Expense Management
- [ ] **5C.1** — List semua pengeluaran (grouped by kategori)
- [ ] **5C.2** — `AddExpenseModal.jsx`:
- Nama pengeluaran
- Jumlah (IDR)
- Kategori
- Hari (dropdown: Hari 1, Hari 2, ... atau "Umum")
- Catatan
- [ ] **5C.3** — Edit & hapus pengeluaran
- [ ] **5C.4** — Currency toggle (IDR / USD / EUR) dengan konversi sederhana
### Validasi Phase 5
- Tambah expense → stat card dan chart update real-time
- Over budget → warning tampil dengan warna merah
- Pie chart menampilkan semua kategori dengan warna yang benar
- Bar chart menampilkan per-hari dengan benar
- Data tersimpan setelah refresh
---
## ✨ Phase 6 — Polish & Optimization (FASE TERAKHIR)
> Hanya dikerjakan setelah Phase 2-5 semuanya selesai dan tervalidasi.
### Checklist Phase 6
#### 6A — Animasi & Transisi
- [ ] **6A.1** — Page transition (fade antar route)
- [ ] **6A.2** — Scroll-triggered animations (IntersectionObserver via Framer Motion)
- [ ] **6A.3** — Loading states yang smooth
- [ ] **6A.4** — Hover dan tap feedback di semua elemen interaktif
#### 6B — Responsive Design Audit
- [ ] **6B.1** — Test di 320px (iPhone SE)
- [ ] **6B.2** — Test di 768px (tablet)
- [ ] **6B.3** — Test di 1280px (desktop)
- [ ] **6B.4** — Navbar collapse ke hamburger di mobile
#### 6C — UX Improvement
- [ ] **6C.1** — Toast notification (sukses tambah item, hapus, dll.)
- [ ] **6C.2** — Konfirmasi sebelum hapus item penting
- [ ] **6C.3** — Empty states yang informatif di semua halaman
- [ ] **6C.4** — Tombol "Reset Trip" dengan konfirmasi
#### 6D — Code Quality
- [ ] **6D.1** — Hapus semua `console.log`
- [ ] **6D.2** — Pastikan tidak ada prop drilling lebih dari 2 level
- [ ] **6D.3** — Cek semua edge case (trip belum dibuat, schedule kosong, dll.)
### Validasi Phase 6
- Aplikasi berjalan mulus di semua ukuran layar
- Tidak ada error di console browser
- localStorage berfungsi: data tetap ada setelah refresh
- Semua animasi smooth (tidak ada jank/lag)
---
## 📋 Template Update task.md per Phase
Saat memulai pengerjaan, buat file `task.md` dengan format ini:
```markdown
# Task Progress — Tour Planner App
## Phase 0 — Setup [DONE/IN PROGRESS/TODO]
- [x] 0.1 Init Vite
- [x] 0.2 Install dependencies
...
## Phase 1 — Layout & UI [TODO]
- [ ] 1A.1 Navbar
...
## Phase 2 — Home Page [TODO]
...
```
**Update status item:**
- `[ ]` → belum dikerjakan
- `[/]` → sedang dikerjakan
- `[x]` → selesai dan tervalidasi
---
## 🚦 Decision Tree untuk Agent Baru
```
Masuk ke project
Baca AGENTS.md + task.md
Phase 0 selesai? ──NO──→ Kerjakan Phase 0 dulu
YES
Phase 1 selesai? ──NO──→ Kerjakan Phase 1 dulu
YES
Phase mana yang belum selesai? → Kerjakan sesuai urutan (2→3→4→5→6)
Semua done? → Lakukan validasi akhir & update walkthrough.md
```