|
3 | 3 | import { definePage } from '@objectstack/spec/ui'; |
4 | 4 |
|
5 | 5 | /** |
6 | | - * Command Center — a `kind:'html'` page (ADR-0080; formerly `kind:'jsx'`). |
7 | | - * The entire layout is authored as a constrained JSX/HTML + Tailwind *string*; |
8 | | - * at save time |
9 | | - * `@objectstack/sdui-parser` compiles it (parse, never execute) into the SDUI |
10 | | - * tree, which the normal PageRenderer / SchemaRenderer renders. Every tag is a |
11 | | - * real registered component — `flex`, `grid`, `card`, `text`, `badge`, `stack`. |
| 6 | + * Command Center — a `kind:'html'` page (ADR-0080): constrained JSX compiled to |
| 7 | + * the SDUI tree, parsed-never-executed. It composes registered components with |
| 8 | + * structured layout — the html tier's actual purpose. |
12 | 9 | * |
13 | | - * Demonstrates what the fixed page schema cannot: Tailwind-freeform layout that |
14 | | - * still composes the platform's real components. Browser-verified. |
| 10 | + * Styling (ADR-0065): a page's source is runtime metadata the build's Tailwind |
| 11 | + * never scans, so utility `className`s silently no-op. So this page uses NO |
| 12 | + * Tailwind: layout is the components' own structured props (`<flex direction gap>`, |
| 13 | + * `<grid columns>`), and any custom CSS is a JSON `style` object with |
| 14 | + * `hsl(var(--token))` theme colors (quoted keys/values — a JS-style object is |
| 15 | + * parsed as a deferred expression and won't apply). |
15 | 16 | */ |
16 | 17 | export const CommandCenterJsxPage = definePage({ |
17 | 18 | name: 'showcase_command_center_jsx', |
18 | 19 | label: 'Command Center (HTML)', |
19 | 20 | type: 'home', |
20 | 21 | kind: 'html', |
21 | 22 | source: ` |
22 | | -<flex direction="col" className="min-h-screen gap-10 bg-gradient-to-br from-slate-50 via-white to-indigo-50 p-10"> |
| 23 | +<flex direction="col" gap={8} style={{"padding":"40px"}}> |
23 | 24 |
|
24 | | - <flex direction="col" className="gap-3"> |
25 | | - <badge className="w-fit rounded-full bg-indigo-100 px-3 py-1 text-xs font-semibold uppercase tracking-widest text-indigo-700" label="Operations · JSX-source page" /> |
26 | | - <text className="block text-5xl font-bold tracking-tight text-slate-900" content="Command Center" /> |
27 | | - <text className="block max-w-2xl text-base leading-relaxed text-slate-500" content="This whole page is authored as constrained JSX + Tailwind and compiled to the SDUI tree — parsed, never executed. Every card is a real registered component." /> |
| 25 | + <flex direction="col" gap={2}> |
| 26 | + <div style={{"fontSize":"12px","fontWeight":"600","letterSpacing":"0.12em","textTransform":"uppercase","color":"hsl(var(--primary))"}}>Operations · HTML-source page</div> |
| 27 | + <div style={{"fontSize":"36px","fontWeight":"700","letterSpacing":"-0.02em","color":"hsl(var(--foreground))"}}>Command Center</div> |
| 28 | + <div style={{"maxWidth":"640px","fontSize":"15px","lineHeight":"1.6","color":"hsl(var(--muted-foreground))"}}>Authored as constrained JSX and compiled to the SDUI tree — parsed, never executed. Layout is structured component props; color is an inline style object with theme tokens. No Tailwind.</div> |
28 | 29 | </flex> |
29 | 30 |
|
30 | | - <grid columns={4} className="gap-5"> |
31 | | - <card className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"> |
32 | | - <text className="block text-sm font-medium text-slate-500" content="Open Tasks" /> |
33 | | - <text className="mt-3 block text-4xl font-bold text-slate-900" content="128" /> |
34 | | - <text className="mt-2 block text-xs font-semibold text-emerald-600" content="▲ 12% vs last week" /> |
35 | | - </card> |
36 | | - <card className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"> |
37 | | - <text className="block text-sm font-medium text-slate-500" content="In Progress" /> |
38 | | - <text className="mt-3 block text-4xl font-bold text-slate-900" content="47" /> |
39 | | - <text className="mt-2 block text-xs font-semibold text-amber-600" content="● 9 due today" /> |
40 | | - </card> |
41 | | - <card className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"> |
42 | | - <text className="block text-sm font-medium text-slate-500" content="Completed" /> |
43 | | - <text className="mt-3 block text-4xl font-bold text-slate-900" content="1,902" /> |
44 | | - <text className="mt-2 block text-xs font-semibold text-emerald-600" content="▲ 4% this month" /> |
45 | | - </card> |
46 | | - <card className="rounded-2xl border border-indigo-300 bg-gradient-to-br from-indigo-500 to-violet-600 p-6 shadow-md"> |
47 | | - <text className="block text-sm font-medium text-indigo-100" content="Cycle Time" /> |
48 | | - <text className="mt-3 block text-4xl font-bold text-white" content="2.4d" /> |
49 | | - <text className="mt-2 block text-xs font-semibold text-indigo-100" content="▼ 18% faster" /> |
50 | | - </card> |
| 31 | + <grid columns={4} gap={5}> |
| 32 | + <flex direction="col" gap={2} style={{"background":"hsl(var(--card))","border":"1px solid hsl(var(--border))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 33 | + <div style={{"fontSize":"13px","fontWeight":"500","color":"hsl(var(--muted-foreground))"}}>Open Tasks</div> |
| 34 | + <div style={{"fontSize":"34px","fontWeight":"700","color":"hsl(var(--foreground))"}}>128</div> |
| 35 | + <div style={{"fontSize":"12px","fontWeight":"600","color":"hsl(142 70% 45%)"}}>▲ 12% vs last week</div> |
| 36 | + </flex> |
| 37 | + <flex direction="col" gap={2} style={{"background":"hsl(var(--card))","border":"1px solid hsl(var(--border))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 38 | + <div style={{"fontSize":"13px","fontWeight":"500","color":"hsl(var(--muted-foreground))"}}>In Progress</div> |
| 39 | + <div style={{"fontSize":"34px","fontWeight":"700","color":"hsl(var(--foreground))"}}>47</div> |
| 40 | + <div style={{"fontSize":"12px","fontWeight":"600","color":"hsl(38 92% 50%)"}}>● 9 due today</div> |
| 41 | + </flex> |
| 42 | + <flex direction="col" gap={2} style={{"background":"hsl(var(--card))","border":"1px solid hsl(var(--border))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 43 | + <div style={{"fontSize":"13px","fontWeight":"500","color":"hsl(var(--muted-foreground))"}}>Completed</div> |
| 44 | + <div style={{"fontSize":"34px","fontWeight":"700","color":"hsl(var(--foreground))"}}>1,902</div> |
| 45 | + <div style={{"fontSize":"12px","fontWeight":"600","color":"hsl(142 70% 45%)"}}>▲ 4% this month</div> |
| 46 | + </flex> |
| 47 | + <flex direction="col" gap={2} style={{"background":"hsl(var(--primary))","border":"1px solid hsl(var(--primary))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 48 | + <div style={{"fontSize":"13px","fontWeight":"500","color":"hsl(var(--primary-foreground))"}}>Cycle Time</div> |
| 49 | + <div style={{"fontSize":"34px","fontWeight":"700","color":"hsl(var(--primary-foreground))"}}>2.4d</div> |
| 50 | + <div style={{"fontSize":"12px","fontWeight":"600","color":"hsl(var(--primary-foreground))"}}>▼ 18% faster</div> |
| 51 | + </flex> |
51 | 52 | </grid> |
52 | 53 |
|
53 | | - <grid columns={3} className="gap-5"> |
54 | | - <card className="col-span-2 rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"> |
55 | | - <text className="block text-lg font-semibold text-slate-900" content="Weekly Throughput" /> |
56 | | - <flex direction="row" className="mt-8 items-end gap-4"> |
57 | | - <flex className="h-12 w-full rounded-lg bg-indigo-400" /> |
58 | | - <flex className="h-20 w-full rounded-lg bg-indigo-500" /> |
59 | | - <flex className="h-16 w-full rounded-lg bg-indigo-400" /> |
60 | | - <flex className="h-28 w-full rounded-lg bg-violet-500" /> |
61 | | - <flex className="h-14 w-full rounded-lg bg-indigo-400" /> |
62 | | - <flex className="h-24 w-full rounded-lg bg-indigo-500" /> |
63 | | - <flex className="h-10 w-full rounded-lg bg-indigo-300" /> |
64 | | - </flex> |
65 | | - </card> |
66 | | - <card className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"> |
67 | | - <text className="block text-lg font-semibold text-slate-900" content="Recent Activity" /> |
68 | | - <stack className="mt-4 gap-3"> |
69 | | - <flex direction="row" className="items-center gap-3"><flex className="h-2 w-2 rounded-full bg-emerald-500" /><text className="text-sm text-slate-600" content="Onboarding flow shipped" /></flex> |
70 | | - <flex direction="row" className="items-center gap-3"><flex className="h-2 w-2 rounded-full bg-indigo-500" /><text className="text-sm text-slate-600" content="12 tasks moved to Review" /></flex> |
71 | | - <flex direction="row" className="items-center gap-3"><flex className="h-2 w-2 rounded-full bg-amber-500" /><text className="text-sm text-slate-600" content="SLA breach on #4821" /></flex> |
72 | | - <flex direction="row" className="items-center gap-3"><flex className="h-2 w-2 rounded-full bg-slate-300" /><text className="text-sm text-slate-600" content="Sprint 42 planning" /></flex> |
73 | | - </stack> |
74 | | - </card> |
| 54 | + <grid columns={3} gap={5}> |
| 55 | + <flex direction="col" gap={6} style={{"gridColumn":"span 2","background":"hsl(var(--card))","border":"1px solid hsl(var(--border))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 56 | + <div style={{"fontSize":"16px","fontWeight":"600","color":"hsl(var(--foreground))"}}>Weekly Throughput</div> |
| 57 | + <grid columns={7} gap={4} style={{"height":"140px","alignItems":"end"}}> |
| 58 | + <flex style={{"height":"48px","borderRadius":"8px","background":"hsl(var(--primary) / 0.55)"}} /> |
| 59 | + <flex style={{"height":"86px","borderRadius":"8px","background":"hsl(var(--primary) / 0.7)"}} /> |
| 60 | + <flex style={{"height":"64px","borderRadius":"8px","background":"hsl(var(--primary) / 0.55)"}} /> |
| 61 | + <flex style={{"height":"120px","borderRadius":"8px","background":"hsl(var(--primary))"}} /> |
| 62 | + <flex style={{"height":"58px","borderRadius":"8px","background":"hsl(var(--primary) / 0.55)"}} /> |
| 63 | + <flex style={{"height":"100px","borderRadius":"8px","background":"hsl(var(--primary) / 0.7)"}} /> |
| 64 | + <flex style={{"height":"40px","borderRadius":"8px","background":"hsl(var(--primary) / 0.4)"}} /> |
| 65 | + </grid> |
| 66 | + </flex> |
| 67 | + <flex direction="col" gap={4} style={{"background":"hsl(var(--card))","border":"1px solid hsl(var(--border))","borderRadius":"var(--radius)","padding":"24px"}}> |
| 68 | + <div style={{"fontSize":"16px","fontWeight":"600","color":"hsl(var(--foreground))"}}>Recent Activity</div> |
| 69 | + <flex direction="row" gap={3} align="center"><flex style={{"width":"8px","height":"8px","borderRadius":"9999px","background":"hsl(142 70% 45%)"}} /><div style={{"fontSize":"14px","color":"hsl(var(--muted-foreground))"}}>Onboarding flow shipped</div></flex> |
| 70 | + <flex direction="row" gap={3} align="center"><flex style={{"width":"8px","height":"8px","borderRadius":"9999px","background":"hsl(var(--primary))"}} /><div style={{"fontSize":"14px","color":"hsl(var(--muted-foreground))"}}>12 tasks moved to Review</div></flex> |
| 71 | + <flex direction="row" gap={3} align="center"><flex style={{"width":"8px","height":"8px","borderRadius":"9999px","background":"hsl(38 92% 50%)"}} /><div style={{"fontSize":"14px","color":"hsl(var(--muted-foreground))"}}>SLA breach on #4821</div></flex> |
| 72 | + <flex direction="row" gap={3} align="center"><flex style={{"width":"8px","height":"8px","borderRadius":"9999px","background":"hsl(var(--muted-foreground))"}} /><div style={{"fontSize":"14px","color":"hsl(var(--muted-foreground))"}}>Sprint 42 planning</div></flex> |
| 73 | + </flex> |
75 | 74 | </grid> |
76 | 75 | </flex>`, |
77 | 76 | }); |
0 commit comments