Move Common Commands to docs/COMMANDS.md and add docs/CONVENTIONS.md for frontend patterns (SWR, filters, Mantine, routing, API URLs). CLAUDE.md now only contains runtime rules and pointers.
2.5 KiB
2.5 KiB
Frontend Conventions
Data Fetching
- SWR for read-only data in route components (tables, lists, charts).
- TanStack Query (
useQuery,useMutation) for auth state — seesrc/frontend/hooks/useAuth.ts. - Never mix both in the same component/page.
- Debounce search inputs:
useDebouncedValue(search, 400)+useEffectthat only triggers when length >= 3 or === 0.
API URL Builder
All URLs go through src/frontend/config/api.ts → API_URLS. Add new entries there, never inline URLs in components.
Desa+ endpoints are proxied via /api/proxy/desa-plus → DESA_PLUS_PROXY constant. The actual API source is at:
/Users/wibu04/Documents/Projects/sistem-desa-mandiri/src/app/api/monitoring/[[...slug]]/route.ts
Filters & Pagination Pattern
Server-side filtering — always pass filter params to the API, never filter client-side on paginated data.
State pattern for a filtered table page:
const [page, setPage] = useState(1)
const [search, setSearch] = useState('') // raw input
const [searchQuery, setSearchQuery] = useState('') // debounced, sent to API
const [debouncedSearch] = useDebouncedValue(search, 400)
useEffect(() => {
if (debouncedSearch.length >= 3 || debouncedSearch.length === 0) {
setSearchQuery(debouncedSearch)
setPage(1)
}
}, [debouncedSearch])
useEffect(() => { setPage(1) }, [filterA, filterB]) // reset page on filter change
Mantine Components
- Dark theme forced (
#242424). Never add light-mode conditionals. radius="md"on inputs,radius="2xl"on containerPaper.className="glass"onPapercards for the frosted glass effect.size="sm"on table inputs and selects.- Icons from
react-icons/tbonly — no other icon libraries. DatePickerInputfrom@mantine/dateswithtype="range"returns[string | null, string | null], not Date objects.
Route Files
File-based routing via TanStack Router Vite plugin. Files in src/frontend/routes/:
| Pattern | Route |
|---|---|
apps.$appId.tsx |
Layout wrapper for per-app pages |
apps.$appId.index.tsx |
Overview/dashboard for an app |
apps.$appId.users.index.tsx |
User management |
apps.$appId.logs.tsx |
Activity logs |
apps.$appId.villages.tsx |
Villages layout |
apps.$appId.villages.index.tsx |
Village list |
apps.$appId.villages.$villageId.tsx |
Village detail |
routeTree.gen.ts is auto-generated — never edit it manually.
App Registration
App configs (ID, menu items) live in src/frontend/config/appMenus.ts. Add new apps there to register them.
Currently active app: desa-plus.