1.8 KiB
1.8 KiB
Building in this project
This app ships a component kit at @project/components (source in
packages/components/src). Compose these instead of hand-rolling UI — it is faster,
consistent, and already themed. Import from @project/components.
Available components
Layout:
PageHeader— page title + optional description + right-alignedactionsslot. Use one per page.Panel— bordered section with an optional titled header (title,description,actions). The workhorse container.StatCard— a single metric tile (label,value, optionalicon,color).StatGrid— responsive row ofStatCards; passstats={[{label, value, icon}]}.
Data (feed these the output of an RPC you implement):
DataTable— generic typed table. Props:columns({key, header, render?, align?}),rows,rowKey, optionalloading/empty/onRowClick. Implement alistXRPC and pass its rows.BarChart— dependency-free horizontal bars fromdata={[{label, value, color?}]}. Good for status/count breakdowns from a stats RPC.
State (already used by the app):
EmptyState,PageLoader,NotFoundState,ServerErrorState,UserCard.
How to build a feature page
- Implement the backend RPCs (
pikku-rpc/pikku-kyselyskills): alistXand any mutations, with zod input/output andauth: true. Scope rows to the signed-in user (where('userId','=',session.userId)). - Fetch with
usePikkuQuery('listX', {})and mutate withusePikkuMutation('createX')(from@project/functions-sdk/pikku/api.gen). - Build the page by composing the kit:
PageHeader+Panel+DataTable/StatGrid/BarChart. Pass i18n strings (m.key()) into the component props.
These are props-only components — they never fetch data themselves. You own the page that wires RPC data into them.