34 KiB
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
- Shared Vocabulary
- Template A — Entity Detail Page
- Template B — Entity List Page
- Component Blueprints
- 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 usesvariant="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 isflex-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:
<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:
<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