TASKS-1823 WebManager module
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Web Manager — Admin (Web Studio)
|
||||
|
||||
Admin side of [Web Manager](./Readme.md). Source: `apps/admin/src/core/WebStudio/`.
|
||||
|
||||
## Routes
|
||||
|
||||
```txt
|
||||
/web-studio/pages/listing list, search, filters, row actions
|
||||
/web-studio/pages/-/create new draft
|
||||
/web-studio/pages/-/:id editor (page or draft clone)
|
||||
/web-studio/settings/:section header | footer | legal
|
||||
```
|
||||
|
||||
The list shows title with full path, locale, slug, group key, page type, status, draft marker and
|
||||
updated time; search is debounced and filters, pagination and locale live in the query string
|
||||
(`useWebStudioQueryParams`), so links and the back arrow keep the editor's context. Row actions are
|
||||
Edit, Preview, Open in web app, Publish, Unpublish, Discard and Delete — Edit opens the draft clone
|
||||
when `draftId` is present, so an editor always lands on the working copy.
|
||||
|
||||
## Editor
|
||||
|
||||
The editor is a flat two-column layout: a sticky ~320px Page details column, and Hero / Blocks / SEO
|
||||
as line tabs beside it. One React Hook Form instance (`PAGE_EDITOR_FORM_ID`) owns everything;
|
||||
the header's Save button submits it by form id, and submitting disables the whole fieldset.
|
||||
Actions sit in a split button: Save draft, then Preview / Publish / Unpublish / Discard / Delete in
|
||||
the dropdown, each behind its own control component in `view/controls/` and its own permission.
|
||||
Publish is offered whenever the page is not already live, so it doubles as republish.
|
||||
|
||||
Blocks are added from a sheet filtered to the page type's `allowedBlockTypes`, reordered by drag
|
||||
(`view/components/SortableList.tsx`), and duplicated or removed from their own header. Nested
|
||||
collections — content columns, CTAs, FAQ items, navigation links — behave the same way one level
|
||||
down.
|
||||
|
||||
## Key Files
|
||||
|
||||
| Concern | File |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| Module registration | `config/module.ts`, `config/routing.tsx`, `config/menu.ts` |
|
||||
| Languages | `config/languages.ts` — code, labels, direction, public prefix |
|
||||
| Page types | `config/pages.ts` — allowed blocks and default path per type |
|
||||
| Block catalogue | `config/blocks.ts` — label, description, preview image, factory |
|
||||
| Settings shape | `config/siteSettings.ts` |
|
||||
| HTTP + multipart | `data/api/WebStudioAPI.ts`, `data/api/PagePayloadSerializer.ts` |
|
||||
| Domain types | `entities/` — `PageType`, `PageStatus`, `BlockType`, `HeroType`, block and field shapes |
|
||||
| Form ↔ DTO | `pages/PageEditPage/helpers/toEditorValues.ts`, `view/forms/PageEditorForm/helpers/toCreatePayload.ts` |
|
||||
|
||||
Page types decide what an editor can build:
|
||||
|
||||
| Type | Layout | Blocks offered | Default path |
|
||||
| ----------- | ---------- | --------------------------------------------------- | ------------ |
|
||||
| `landing` | Standard | all six | `/` |
|
||||
| `blog` | Blog index | none — the listing is rendered from published posts | `/blog` |
|
||||
| `blog-item` | Editorial | all except `articles` | `/` |
|
||||
|
||||
## UI Conventions
|
||||
|
||||
The module is a content tool, not a dashboard of cards. Flat surfaces, few separators, one primary
|
||||
action per screen.
|
||||
|
||||
| Element | Treatment |
|
||||
| ------------------- | -------------------------------------------------------- |
|
||||
| Screen heading | `text-mono text-xl font-semibold` |
|
||||
| Supporting copy | `text-muted-foreground text-sm` |
|
||||
| Editor settings | `bg-muted/40 space-y-5 p-5` |
|
||||
| Top-level block | `bg-muted/35`, compact header, one `border-b` while open |
|
||||
| Nested field group | `border-l-2 pl-4` (`view/components/FieldCard.tsx`) |
|
||||
| Inline actions | small ghost icon buttons |
|
||||
| Destructive trigger | ghost button, destructive text, confirmation dialog |
|
||||
| Empty collection | `bg-muted/35`, generous padding, short copy |
|
||||
|
||||
`view/components/BlockCard.tsx` is named for compatibility but is a flat section, not a card — no
|
||||
shadow, no hover lift, no bordered container nested inside every block. The block picker stays a
|
||||
sheet with a divided list, because picking is a temporary task. Shared visual principles live in the
|
||||
[Admin UI Style Guide](../../../apps/admin/ui-style-guide.md); style Web Studio from Web Studio and do
|
||||
not edit `apps/admin/src/shared` for a module-only visual change.
|
||||
|
||||
A visual change must not alter routes, `locale` / `group_key` query behavior, list filtering or DTO
|
||||
mapping, draft-clone semantics, form values or validation, block factory output, settings payload
|
||||
shape, or the toast / error / loading states. Anything that does is a feature change.
|
||||
Reference in New Issue
Block a user