init
This commit is contained in:
649
LAYOUT.md
Normal file
649
LAYOUT.md
Normal file
@@ -0,0 +1,649 @@
|
||||
# ALLA OS CRM — Page Layout Templates
|
||||
|
||||
> **Rule**: No design tokens are embedded in this document.
|
||||
> All colors, text content, icons, and brand-specific values are represented by **semantic placeholders** (`{placeholder}`).
|
||||
> Use these templates as structural skeletons — inject your own design system, copy, and iconography.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Shared Vocabulary](#1-shared-vocabulary)
|
||||
2. [Template A — Entity Detail Page](#2-template-a--entity-detail-page)
|
||||
3. [Template B — Entity List Page](#3-template-b--entity-list-page)
|
||||
4. [Component Blueprints](#4-component-blueprints)
|
||||
5. [Slot Reference](#5-slot-reference)
|
||||
|
||||
---
|
||||
|
||||
## 1. Shared Vocabulary
|
||||
|
||||
### Semantic Placeholders
|
||||
|
||||
| Category | Placeholder | Represents |
|
||||
|---|---|---|
|
||||
| Color | `{color.status-positive}` | approved / success / active |
|
||||
| Color | `{color.status-negative}` | rejected / error / lost |
|
||||
| Color | `{color.status-warning}` | pending / caution / awaiting |
|
||||
| Color | `{color.status-neutral}` | draft / default / info |
|
||||
| Color | `{color.accent}` | hot / highlight / urgent |
|
||||
| Color | `{color.muted}` | secondary text / disabled |
|
||||
| Color | `{color.surface}` | card background / subtle fill |
|
||||
| Text | `{entity.code}` | business code (e.g. QT2606-001) |
|
||||
| Text | `{entity.title}` | primary display name / project name |
|
||||
| Text | `{label.fieldName}` | field label (locale-aware) |
|
||||
| Text | `{action.verb}` | button label (locale-aware) |
|
||||
| Text | `{value.field}` | field display value |
|
||||
| Icon | `{icon.back}` | back / navigate-left icon |
|
||||
| Icon | `{icon.status}` | contextual status icon |
|
||||
| Icon | `{icon.field}` | field-specific icon |
|
||||
| Link | `{route.list}` | parent list route |
|
||||
| Link | `{route.detail}` | detail page route |
|
||||
| Component | `<StatusBadge />` | status display component |
|
||||
| Component | `<PreviewPanel />` | collapsible preview component |
|
||||
| Data | `{data.summary}` | summary/computed values |
|
||||
| Data | `{data.items}` | line items collection |
|
||||
| Data | `{data.steps}` | approval/workflow steps |
|
||||
| Data | `{data.related}` | related entities collection |
|
||||
|
||||
### Spacing Convention
|
||||
|
||||
| Token | Tailwind | Usage |
|
||||
|---|---|---|
|
||||
| `{gap-page}` | `gap-6` | between top-level sections |
|
||||
| `{gap-card}` | `space-y-6` | between cards in a column |
|
||||
| `{gap-inner}` | `gap-4` | between fields in a grid |
|
||||
| `{gap-compact}` | `gap-2` / `gap-3` | between badges, inline items |
|
||||
| `{pad-page}` | `p-4 md:p-6` | page outer padding |
|
||||
| `{pad-card}` | default CardContent | card inner padding |
|
||||
|
||||
---
|
||||
|
||||
## 2. Template A — Entity Detail Page
|
||||
|
||||
**Used by**: Enquiry Detail, Quotation Detail, Approval Detail
|
||||
|
||||
### 2.1 Page Skeleton
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ [←] {entity.code} <StatusBadge> <Badge?> <Badge?> │ ← Header Bar
|
||||
│ {entity.title} │
|
||||
│ [Btn] [Btn] [Btn] │ ← Header Actions
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ [Btn] [Btn] [Btn] │ ← Action Row (conditional)
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ <CollapsiblePanel /> │ ← Optional Preview
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ <ProgressBarCard /> │ ← Optional Progress
|
||||
├──────────────────────────┬──────────────────────────────┤
|
||||
│ │ │
|
||||
│ Main Column (2/3) │ Side Column (1/3) │
|
||||
│ │ │
|
||||
│ ┌──────────────────┐ │ ┌────────────────────┐ │
|
||||
│ │ Summary Card │ │ │ Key Metric Card │ │
|
||||
│ └──────────────────┘ │ └────────────────────┘ │
|
||||
│ ┌──────────────────┐ │ ┌────────────────────┐ │
|
||||
│ │ Secondary Card │ │ │ Current State Card │ │
|
||||
│ └──────────────────┘ │ └────────────────────┘ │
|
||||
│ ┌──────────────────┐ │ ┌────────────────────┐ │
|
||||
│ │ Table Card │ │ │ Progress Card │ │
|
||||
│ └──────────────────┘ │ └────────────────────┘ │
|
||||
│ ┌──────────────────┐ │ ┌────────────────────┐ │
|
||||
│ │ Tabs Card │ │ │ Quick Links Card │ │
|
||||
│ │ ┌─┬─┬─┬─┐ │ │ └────────────────────┘ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ └─┴─┴─┴─┘ │ │ │
|
||||
│ │ Tab Content │ │ │
|
||||
│ └──────────────────┘ │ │
|
||||
│ │ │
|
||||
└──────────────────────────┴──────────────────────────────┘
|
||||
|
||||
<Dialog /> (action confirmation)
|
||||
```
|
||||
|
||||
### 2.2 Section Specifications
|
||||
|
||||
#### A. Header Bar
|
||||
|
||||
```
|
||||
Container: flex items-center gap-{gap-inner}
|
||||
─────────────────────────────────────────────
|
||||
[BackButton] {entity.code} <StatusBadge> <Badge*>
|
||||
{entity.title}
|
||||
─────────────────────────────────────
|
||||
flex-1 flex items-center gap-{gap-compact}
|
||||
```
|
||||
|
||||
| Element | Structure | Notes |
|
||||
|---|---|---|
|
||||
| Back Button | `Button variant="ghost" size="icon"` → `Link` to `{route.list}` | Always present |
|
||||
| Code | `h1` with `{font-size.heading}` | Monospace for business codes |
|
||||
| Status Badge | `<StatusBadge status={status} />` | Maps status → `{color.status-*}` |
|
||||
| Extra Badges | `Badge variant="outline"` or custom | Revision, Hot, Type — conditionally shown |
|
||||
| Subtitle | `p text-muted-foreground` | `{entity.title}` or description |
|
||||
| Header Actions | `Button variant="outline"` or `Button` | Preview, PDF, Navigate — aligned right |
|
||||
|
||||
#### B. Action Row (Conditional)
|
||||
|
||||
```
|
||||
Container: flex flex-wrap items-center gap-{gap-compact}
|
||||
─────────────────────────────────────────────────────
|
||||
[Btn1] [Btn2] [Btn3] ...
|
||||
```
|
||||
|
||||
- Only rendered when at least one action is available
|
||||
- Actions are **status-driven**: show/hide based on `entity.status`
|
||||
- Use consistent `size="sm"` for all action buttons
|
||||
- Primary action uses default variant, destructive uses `variant="destructive"`, secondary uses `variant="outline"`
|
||||
- Each button follows pattern: `<Icon className="h-4 w-4 mr-1" /> {action.verb}`
|
||||
|
||||
#### C. Collapsible Panel (Optional)
|
||||
|
||||
```
|
||||
Container: Card → CardContent p-4 overflow-auto max-h-[{max-preview-height}]
|
||||
──────────────────────────────────────────────────────────────────────────
|
||||
<PreviewPanel />
|
||||
```
|
||||
|
||||
- Toggled via state (`showPreview`)
|
||||
- Rendered between Action Row and Grid
|
||||
- Only present when entity supports preview (e.g. PDF preview for Quotation)
|
||||
|
||||
#### D. Progress Bar Card (Optional)
|
||||
|
||||
```
|
||||
Container: Card → CardContent p-4
|
||||
───────────────────────────────────
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ Progress Title ({completed}/{total}) Current │ ← flex justify-between
|
||||
│ ▓▓▓▓▓▓▓▓░░░░░░░░░░░ │ ← step bars
|
||||
│ ✓ Step1 ○ Step2 ○ Step3 │ ← step labels
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- Step bars: `flex items-center gap-1`, each step is `flex-1 h-2 rounded-full`
|
||||
- Filled steps use `{color.status-positive}`, pending use `{color.muted}`
|
||||
- Step labels: icon + role name per step
|
||||
|
||||
#### E. 3-Column Grid
|
||||
|
||||
```
|
||||
Container: grid grid-cols-1 lg:grid-cols-3 gap-{gap-page}
|
||||
─────────────────────────────────────────────────────────────
|
||||
├── Main Column: lg:col-span-2 space-y-{gap-card}
|
||||
└── Side Column: space-y-{gap-card}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Main Column — Card Types
|
||||
|
||||
#### Card Type 1: Summary Card (Always First)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ {label.summaryTitle} │ ← CardHeader pb-3, CardTitle text-base
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ┌────────┬────────┬────────┬────────┐ │
|
||||
│ │ Field1 │ Field2 │ Field3 │ Field4 │ │ ← grid 2cols md:4cols gap-{gap-inner}
|
||||
│ │ label │ label │ label │ label │ │ ← text-xs text-muted-foreground
|
||||
│ │ value │ value │ value │ value │ │ ← text-sm (or Badge for enum)
|
||||
│ └────────┴────────┴────────┴────────┘ │
|
||||
│ │
|
||||
│ [Optional: description block] │ ← mt-3 / mt-4 if present
|
||||
│ [Optional: location with icon] │ ← flex items-center gap-2
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Field cell pattern:**
|
||||
```jsx
|
||||
<div>
|
||||
<p className="text-xs text-muted-foreground">{label.fieldName}</p>
|
||||
<p className="text-sm">{value.field}</p> // plain value
|
||||
// OR
|
||||
<Badge variant="secondary">{value.field}</Badge> // enum value
|
||||
// OR
|
||||
<Link className="text-sm text-primary hover:underline">{value.field}</Link> // link value
|
||||
</div>
|
||||
```
|
||||
|
||||
#### Card Type 2: Entity List Card (e.g. Customer Roles)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ {label.cardTitle} │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ┌─────────────────┬─────────────────┐ │
|
||||
│ │ [Icon] Name │ [Icon] Name │ │ ← grid 1col sm:2cols gap-3
|
||||
│ │ Subtitle │ Subtitle │ │ ← each row: flex items-center gap-3 p-3 rounded-lg border
|
||||
│ │ <Badge>│ <Badge>│ │
|
||||
│ └─────────────────┴─────────────────┘ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Row pattern:**
|
||||
```
|
||||
[IconBox] [Content flex-1] [Badge]
|
||||
p-2 Name (medium) variant="outline"
|
||||
bg-muted Subtitle (xs)
|
||||
rounded text-muted
|
||||
```
|
||||
|
||||
#### Card Type 3: Table Card (e.g. Line Items)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ {label.tableTitle} │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ┌───┬──────────┬────┬────┬────────┬──────┐│
|
||||
│ │ # │ Description│ Qty│Unit│ Price │Total ││ ← thead: border-b bg-muted/50
|
||||
│ ├───┼──────────┼────┼────┼────────┼──────┤│
|
||||
│ │ 1 │ Item A │ 2 │ ea │ 1,000 │2,000 ││ ← tbody: border-b last:border-0
|
||||
│ │ │ spec... │ │ │ │ ││ ← specification: text-xs text-muted
|
||||
│ └───┴──────────┴────┴────┴────────┴──────┘│
|
||||
│ │
|
||||
│ ┌─────────────────┐│
|
||||
│ │ Subtotal val ││ ← Totals section: flex justify-end
|
||||
│ │ Discount val ││ w-72 space-y-1 text-sm
|
||||
│ │ Tax val ││
|
||||
│ │ ────────────── ││ Separator
|
||||
│ │ Grand val ││ font-bold text-base
|
||||
│ └─────────────────┘│
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Card Type 4: Topics Card (Optional — Key-Value List Groups)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ {label.topicsTitle} │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ {icon.topicType} {topic.title} │ ← text-sm font-semibold
|
||||
│ • Item 1 │ ← list-disc list-inside text-sm text-muted
|
||||
│ • Item 2 │ ml-2 space-y-0.5
|
||||
│ │
|
||||
│ {icon.topicType} {topic.title} │ ← space-y-4 between topics
|
||||
│ • Item 1 │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Card Type 5: Tabs Card (Always Last in Main Column)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ [Tab1 (n)] [Tab2 (n)] [Tab3] [Tab4] │ ← TabsList
|
||||
├─────────────────────────────────────────────┤
|
||||
│ <TabContent> │
|
||||
│ ...varies per tab type (see below)... │
|
||||
│ </TabContent> │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Tab content variants:**
|
||||
|
||||
| Variant | Structure | Empty State |
|
||||
|---|---|---|
|
||||
| Step Timeline | Vertical: icon + step label + badge + meta + comment bubble | Centered text + create CTA |
|
||||
| Related Items | Card list: each item is a linked card with code/status/amount | Icon + text + create CTA |
|
||||
| Follow-ups | Icon-box + title + description + metadata | Centered text |
|
||||
| Attachments | Upload area with drag-drop zone | Icon + text + upload button |
|
||||
| Audit Log | Dot + action badge + description + timestamp | Centered text |
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Side Column — Card Types
|
||||
|
||||
#### Side Card Type 1: Key Metric Summary
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ {label.metricTitle} │ ← CardHeader pb-3, CardTitle text-base
|
||||
├─────────────────────────────┤
|
||||
│ Sub-amount {value} │ ← flex justify-between text-sm
|
||||
│ Deduction {value} │ ← conditional, uses {color.status-negative}
|
||||
│ Tax {value} │
|
||||
│ ───────────────────────── │ ← Separator
|
||||
│ Grand Total {value} │ ← flex justify-between font-bold
|
||||
│ {label.currencyNote} │ ← text-xs text-muted-foreground
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Side Card Type 2: Current State / Status Highlight
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ {icon.state} {label.stateTitle} │ ← CardHeader with icon
|
||||
├─────────────────────────────────────┤
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ [Icon] Step M/N │ │ ← Highlighted box: p-3 rounded-lg
|
||||
│ │ {label.waitingFor} │ │ border uses {color.status-warning}
|
||||
│ └─────────────────────────────┘ │ bg uses {color.status-warning} light
|
||||
│ │
|
||||
│ [Btn1] [Btn2] │ ← Inline action buttons (conditional)
|
||||
│ OR │
|
||||
│ ┌─────────────────────────────┐ │
|
||||
│ │ [Icon] {label.completed} │ │ ← Completed state box
|
||||
│ │ {label.subtext} │ │ uses {color.status-positive} or {color.status-negative}
|
||||
│ └─────────────────────────────┘ │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Side Card Type 3: Progress Indicator
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ {label.progressTitle} │ ← CardHeader pb-3
|
||||
├─────────────────────────────┤
|
||||
│ ████████░░░░░░ 70% │ ← flex items-center gap-3
|
||||
│ │ bar: w-full bg-muted rounded-full h-3
|
||||
│ │ fill: rounded-full h-3, width={percent}%
|
||||
│ │ fill color: threshold-based from {color.status-*}
|
||||
│ │ label: text-lg font-bold
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
#### Side Card Type 4: Quick Links / Metadata
|
||||
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ {label.infoTitle} │ ← CardHeader pb-3
|
||||
├─────────────────────────────┤
|
||||
│ {label.key1} {value1} │ ← flex justify-between text-sm
|
||||
│ {label.key2} {value2} │ value can be: text | Link | Badge
|
||||
│ {label.key3} <Badge> │
|
||||
│ {label.key4} {value4} │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.5 Dialog Pattern (Action Confirmation)
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────┐
|
||||
│ {action.confirmTitle} │ ← DialogTitle
|
||||
│ {entity.code} - {entity.title} │ ← DialogDescription
|
||||
│ {label.metric}: {value} │
|
||||
│ │
|
||||
│ [Warning Box] (reject mode only) │ ← flex items-start gap-2 p-3 rounded-lg
|
||||
│ {label.rejectWarning} │ uses {color.status-negative} light
|
||||
│ │
|
||||
│ {label.commentField} │ ← label text-sm font-medium
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ {placeholder.comment} │ │ ← Textarea
|
||||
│ └─────────────────────────────────┘ │
|
||||
│ │
|
||||
│ [Cancel] [Confirm] │ ← DialogFooter
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Template B — Entity List Page
|
||||
|
||||
**Used by**: Approvals List (adaptable for any entity collection)
|
||||
|
||||
### 3.1 Page Skeleton
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Page Title │ ← Page Header
|
||||
│ {label.subtitle} ({count}) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ ← Summary Row
|
||||
│ │ Stat 1 │ │ Stat 2 │ │ Stat 3 │ │ grid 1col sm:3cols
|
||||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────────────────────────────────────────┐│
|
||||
│ │ Item Card 1 ││ ← Item Cards
|
||||
│ │ Info | Metric | Progress + Actions ││ space-y-4
|
||||
│ │ ───────────────────────────────── ││
|
||||
│ │ Inline Timeline ││
|
||||
│ └─────────────────────────────────────────────────────┘│
|
||||
│ ┌─────────────────────────────────────────────────────┐│
|
||||
│ │ Item Card 2 ││
|
||||
│ │ ... ││
|
||||
│ └─────────────────────────────────────────────────────┘│
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ <Dialog /> │ ← Action Dialog
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 3.2 Section Specifications
|
||||
|
||||
#### A. Page Header
|
||||
|
||||
```
|
||||
Container: (no wrapper needed)
|
||||
──────────────────────────────
|
||||
<h1>{label.pageTitle}</h1> ← text-2xl font-bold tracking-tight
|
||||
<p className="text-muted-foreground">
|
||||
{label.subtitle} ({count})
|
||||
</p>
|
||||
```
|
||||
|
||||
#### B. Summary Row
|
||||
|
||||
```
|
||||
Container: grid grid-cols-1 sm:grid-cols-3 gap-4
|
||||
──────────────────────────────────────────────────
|
||||
┌─────────────────────┐
|
||||
│ [IconBox] {value} │ ← flex items-center gap-3
|
||||
│ {label} │ ← value: text-2xl font-bold
|
||||
└─────────────────────┘ label: text-xs text-muted-foreground
|
||||
```
|
||||
|
||||
**Stat card pattern:**
|
||||
```jsx
|
||||
<Card>
|
||||
<CardContent className="p-4 flex items-center gap-3">
|
||||
<div className="p-2 rounded-lg {color.surface}">
|
||||
<{icon.stat} className="h-5 w-5 {color.icon}" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-2xl font-bold">{value}</p>
|
||||
<p className="text-xs text-muted-foreground">{label}</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
```
|
||||
|
||||
#### C. Item Card
|
||||
|
||||
```
|
||||
Container: Card hover:shadow-md transition-shadow
|
||||
──────────────────────────────────────────────────
|
||||
┌───────────────────────────────────────────────────────────────────┐
|
||||
│ CardContent p-5 │
|
||||
│ ┌─────────────────┬────────────┬───────────────────────────┐ │
|
||||
│ │ Info (flex-1) │ Metric │ Progress + Actions │ │
|
||||
│ │ │ (min-w-*) │ (min-w-*) flex-col items-end│ │
|
||||
│ │ [Code] [Badge*] │ │ [Step Dots] │ │
|
||||
│ │ Title │ {amount} │ {label.currentStep} │ │
|
||||
│ │ [Meta items] │ {currency} │ [Btn] [Btn] [Btn] │ │
|
||||
│ └─────────────────┴────────────┴───────────────────────────┘ │
|
||||
│ │
|
||||
│ ─── border-t ─── │
|
||||
│ {label.timelineTitle} │
|
||||
│ [Step1 icon + label] [Step2 icon + label] ... │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Responsive behavior:**
|
||||
- Mobile: `flex-col items-start` — all sections stack vertically
|
||||
- Desktop (`lg:`): `flex-row items-center` — sections align horizontally
|
||||
|
||||
**Info section pattern:**
|
||||
```
|
||||
Code link + Status Badge + Type Badge + Branch Badge ← flex items-center gap-2 mb-2
|
||||
code: Link text-primary hover:underline font-mono
|
||||
Title ← text-sm font-medium mb-1
|
||||
Meta items: [Icon] value • [Icon] value • [Icon] value ← flex flex-wrap gap-3 text-xs text-muted
|
||||
```
|
||||
|
||||
**Step dots pattern:**
|
||||
```
|
||||
Container: flex items-center gap-1
|
||||
───────────────────────────────
|
||||
[●]─[●]─[○]─[○]
|
||||
1 2 3 4
|
||||
|
||||
Each dot: h-6 w-6 rounded-full flex items-center justify-center text-xs font-medium
|
||||
approved → {color.status-positive}
|
||||
rejected → {color.status-negative}
|
||||
pending → {color.status-warning}
|
||||
content: ✓ | ✗ | {stepNumber}
|
||||
|
||||
Connector: w-6 h-0.5 between dots
|
||||
after approved → {color.status-positive}
|
||||
otherwise → {color.muted}
|
||||
```
|
||||
|
||||
**Inline timeline (collapsed):**
|
||||
```
|
||||
Container: mt-4 pt-4 border-t
|
||||
───────────────────────────────
|
||||
{label.timelineTitle}
|
||||
flex items-start gap-3
|
||||
[Icon] RoleName: ApproverName ← each step
|
||||
timestamp
|
||||
comment (italic)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Component Blueprints
|
||||
|
||||
### 4.1 Field Grid Cell
|
||||
|
||||
Reusable unit for Summary Card field grids.
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ {label} │ ← text-xs text-muted-foreground
|
||||
│ {value} │ ← text-sm (default) | text-sm font-medium (emphasized) | Badge (enum)
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
Grid: `grid grid-cols-2 md:grid-cols-4 gap-4`
|
||||
|
||||
### 4.2 Icon + Text Row (Metadata)
|
||||
|
||||
Used in side cards, info sections, and meta lines.
|
||||
|
||||
```
|
||||
[{icon}] {text} ← flex items-center gap-2 text-sm
|
||||
[{icon}] {label}: {value} ← icon: h-3.5 w-3.5 text-muted-foreground
|
||||
```
|
||||
|
||||
### 4.3 Linked Entity Row
|
||||
|
||||
Used in tabs for related entities (Quotation in Enquiry, etc.).
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Code [Badge] │ ← font-mono text-sm + Badge outline
|
||||
│ Title Amount | Date │ ← text-sm + text-right values
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Wrapped in `Link` → `Card hover:shadow-md transition-shadow cursor-pointer mb-3`
|
||||
|
||||
### 4.4 Follow-up Row
|
||||
|
||||
```
|
||||
[IconBox] Title ← icon: p-2 rounded-lg bg-muted
|
||||
Description (optional) ← text-xs text-muted
|
||||
{label.by} {person} • {label.due} {date} ← text-xs text-muted
|
||||
```
|
||||
|
||||
### 4.5 Audit Timeline Entry
|
||||
|
||||
```
|
||||
● [ActionBadge] Description ← dot: w-2 h-2 rounded-full bg-primary
|
||||
{person} • {timestamp} ← text-xs text-muted
|
||||
```
|
||||
|
||||
### 4.6 Approval Step Timeline (Vertical — Detail Page)
|
||||
|
||||
```
|
||||
┌───┐
|
||||
│ ✓ │ ← h-8 w-8 rounded-full, status-colored
|
||||
└─┬─┘
|
||||
│ ← w-0.5 flex-1 min-h-[24px], approved: {color.status-positive} light, else: {color.muted}
|
||||
┌───┐
|
||||
│ ○ │
|
||||
└───┘
|
||||
|
||||
Step {n}: {role} [Status Badge] ← text-sm font-medium
|
||||
{label.by} {approver} ← text-xs text-muted
|
||||
{timestamp} ← text-xs text-muted
|
||||
┌─────────────────────────────┐
|
||||
│ {comment} │ ← text-sm mt-2 p-2.5 rounded-lg bg-muted
|
||||
└─────────────────────────────┘
|
||||
[Btn] [Btn] ← inline actions (if step is pending)
|
||||
```
|
||||
|
||||
### 4.7 Empty State
|
||||
|
||||
```
|
||||
[{icon}] ← h-8 w-8 mx-auto mb-2 opacity-50
|
||||
{label.emptyMessage} ← text-sm text-muted-foreground text-center
|
||||
[Btn] ← variant="outline" size="sm" mt-3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Slot Reference
|
||||
|
||||
Quick reference for what goes where when composing a new page from these templates.
|
||||
|
||||
### Detail Page Slots
|
||||
|
||||
| Slot | Location | Required | Content |
|
||||
|---|---|---|---|
|
||||
| `header.backLink` | Header left | ✅ | Link to list page |
|
||||
| `header.code` | Header center-left | ✅ | Entity business code |
|
||||
| `header.badges` | Header center-left | — | StatusBadge + 0..N extra badges |
|
||||
| `header.subtitle` | Header center-left | ✅ | Entity display name / description |
|
||||
| `header.actions` | Header right | — | 0..N outline/primary buttons |
|
||||
| `actionRow` | Below header | — | Status-driven action buttons |
|
||||
| `previewPanel` | Below actionRow | — | Collapsible preview (PDF, etc.) |
|
||||
| `progressBar` | Below previewPanel | — | Step progress indicator |
|
||||
| `main.summary` | Main col, 1st card | ✅ | Field grid with entity core data |
|
||||
| `main.secondary*` | Main col, 2nd..Nth | — | Customer roles, table, topics |
|
||||
| `main.tabs` | Main col, last | ✅ | Tabbed content area |
|
||||
| `side.metric` | Side col, 1st card | — | Amount/quantity summary |
|
||||
| `side.currentState` | Side col, 2nd card | — | Current workflow step + inline actions |
|
||||
| `side.progress` | Side col, 3rd card | — | Progress bar (chance %, completion) |
|
||||
| `side.quickInfo` | Side col, last card | — | Key-value pairs with optional links/badges |
|
||||
| `dialog` | Overlay | — | Confirmation dialog for actions |
|
||||
|
||||
### List Page Slots
|
||||
|
||||
| Slot | Location | Required | Content |
|
||||
|---|---|---|---|
|
||||
| `pageHeader.title` | Top | ✅ | Page heading + subtitle |
|
||||
| `summaryRow` | Below header | — | 3 stat cards |
|
||||
| `itemCard.info` | Card left | ✅ | Code link, badges, title, metadata |
|
||||
| `itemCard.metric` | Card center | — | Primary numeric value |
|
||||
| `itemCard.progress` | Card right | — | Step dots + current step label |
|
||||
| `itemCard.actions` | Card right | — | Action buttons (detail, approve, reject) |
|
||||
| `itemCard.timeline` | Card bottom | — | Collapsed inline timeline |
|
||||
| `dialog` | Overlay | — | Action confirmation dialog |
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Page → Template Mapping
|
||||
|
||||
| Page | Template | Custom Slots Used |
|
||||
|---|---|---|
|
||||
| Enquiry Detail | A | summary, tabs (quotations, followups, timeline), side (customer, project, chance) |
|
||||
| Quotation Detail | A | summary, customers, items table, topics, tabs (approval, followups, attachments, audit), side (amount, chance, quickInfo) + previewPanel + actionRow |
|
||||
| Approval Detail | A | summary, linked-quotation, tabs (steps, followups, audit), side (amount, currentState, chance, quickInfo) + progressBar + actionRow + dialog |
|
||||
| Approvals List | B | summaryRow, itemCards with stepDots + timeline, dialog |
|
||||
|
||||
---
|
||||
|
||||
*End of Layout Templates*
|
||||
Reference in New Issue
Block a user