# 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
; }; export default MyComponent; // ❌ SALAH — Jangan gunakan class component class MyComponent extends React.Component { } ``` --- ## 2. Styling ```jsx // ✅ BENAR — CSS variables dari design system
// ✅ BENAR — className dengan class yang didefinisikan di CSS
// ❌ SALAH — Hardcode warna
// ❌ SALAH — TailwindCSS
``` --- ## 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 ``` --- ## 4. Animasi ```jsx // ✅ BENAR — Selalu gunakan Framer Motion import { motion } from 'framer-motion'; // ❌ 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'; // ❌ SALAH — Emoji sebagai icon UI 📍 // ❌ SALAH — SVG inline tanpa abstraksi ``` --- ## 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 `