website refactor
This commit is contained in:
@@ -42,18 +42,52 @@ Authoritative contract: [`WEBSITE_CONTRACT.md`](docs/architecture/website/WEBSIT
|
||||
|
||||
- JSON-serializable only.
|
||||
- Contains only values ready to render (mostly strings/numbers).
|
||||
- Built from Page DTO (initial render) and from ViewModel (post-hydration).
|
||||
- Built from API DTO directly in RSC.
|
||||
|
||||
The mapping between Page DTO, ViewModel, and ViewData is performed by Presenters.
|
||||
See [`PRESENTERS.md`](docs/architecture/website/PRESENTERS.md:1).
|
||||
The mapping between API DTO and ViewData is performed by ViewData Builders.
|
||||
See [`BUILDERS.md`](docs/architecture/website/BUILDERS.md:1).
|
||||
|
||||
## 3) Required per-route structure
|
||||
|
||||
Every route MUST follow:
|
||||
### Server Components (RSC)
|
||||
Every RSC route MUST follow:
|
||||
|
||||
1) `page.tsx` (server): calls a PageQuery and passes Page DTO
|
||||
2) `*PageClient.tsx` (client): builds ViewData and renders Template
|
||||
3) `*Template.tsx` (pure UI): renders ViewData only
|
||||
1) `page.tsx`: calls a PageQuery
|
||||
2) `page.tsx`: builds ViewData using ViewDataBuilder
|
||||
3) `page.tsx`: renders Template with ViewData
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
export default async function AdminDashboardPage() {
|
||||
const apiDto = await AdminDashboardPageQuery.execute();
|
||||
const viewData = AdminDashboardViewDataBuilder.build(apiDto);
|
||||
return <AdminDashboardTemplate viewData={viewData} />;
|
||||
}
|
||||
```
|
||||
|
||||
### Client Components
|
||||
Client components that need API data MUST follow:
|
||||
|
||||
1) `*Client.tsx`: fetches API DTO
|
||||
2) `*Client.tsx`: builds ViewModel using ViewModelBuilder
|
||||
3) `*Client.tsx`: renders Template with ViewModel
|
||||
|
||||
Example:
|
||||
```typescript
|
||||
'use client';
|
||||
|
||||
export function AdminDashboardClient() {
|
||||
const [viewModel, setViewModel] = useState<AdminDashboardViewModel | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const apiDto = await adminApiClient.getDashboard();
|
||||
const vm = AdminDashboardViewModelBuilder.build(apiDto);
|
||||
setViewModel(vm);
|
||||
}, []);
|
||||
|
||||
return viewModel ? <AdminDashboardTemplate viewModel={viewModel} /> : null;
|
||||
}
|
||||
```
|
||||
|
||||
All writes enter through Server Actions.
|
||||
See [`FORM_SUBMISSION.md`](docs/architecture/website/FORM_SUBMISSION.md:1).
|
||||
|
||||
Reference in New Issue
Block a user