- Introduction
- Pitch
- Hogwarts
- Live Demo
- MVP
- Roadmap
- Launch Sprint
- PRD
- Get Started
- Localhost
- Architecture
- Structure
- Pattern
- Page
- Layout
- Content
- Types
- Config
- Actions
- Queries
- Authorization
- Validation
- Form
- Table
- Detail
- Card
- Util
- Hooks
- List Params
- Views
- README.md
- ISSUE.md
- Technology Stack
- Database
- File
- CDN Assets
- Entry Points
- Dashboard
- Authentication
- Credentials
- OAuth
- Flow Diagrams
- Multi-Tenancy
- Offline
- Onboarding
- Onboarding Videos
- Add Values
- Admission
- Application
- Attendance
- Compliance
- Profile
- Exams
- Exam Wizard
- Timetable
- Classrooms
- Notifications
- Conference
- LMS (Lumos)
Finance
- Finance
- Fee Management
- Invoice
- Wallet
- Salary
- Payroll
- Timesheet
- Expenses
- Budget
- Receipt
- Accounts
- Banking
- Reports
- Dashboard
- Permissions
- Messages
- Integration Flow
- Provision
- AI Document Processing
- Document Intelligence
- Internationalization
- Translation
- Translation Guide
- Icons
- Docs Factory
- Inspiration
- Listings
- Teachers
- Students
- Catalog
- Library
- Contributing
- Code of conduct
- GitHub Workflow
- Database Seeds
- Database Safety
- Test Accounts
- Playwright
- Prettier
- Block Rebound
Sales & GTM
card.tsx renders display cards composed from shadcn Card primitives — KPIs, entity summaries, onboarding tiles. Pure presentation, no data fetching, no mutations.
Categories
| Category | Shape | Reference |
|---|---|---|
| Entity display | Full / compact / health / stats variants for one entity | saas-dashboard/billing/card.tsx |
| KPI / stats | Single metric with label, trend, icon | school-dashboard/dashboard/card.tsx |
| Onboarding step | Visual card for a wizard option | onboarding/branding/card.tsx |
| Atom lab | Showcase cards in atom/lab/ | atom/lab/*-card.tsx |
Rules
| # | Rule |
|---|---|
| 1 | Compose from shadcn Card primitives — never reinvent |
| 2 | Typed entity props from types.ts — no any |
| 3 | Formatters from util.ts — no inline Intl.NumberFormat |
| 4 | Multiple variants per file — EntityCard, CompactCard from one card.tsx |
| 5 | showActions prop for conditional footers |
Canonical example
import { Badge } from "@/components/ui/badge"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import type { TenantDto } from "./types"
import { formatDate } from "./util"
interface TenantCardProps {
tenant: TenantDto
showActions?: boolean
}
export function TenantCard({ tenant, showActions = true }: TenantCardProps) {
return (
<Card>
<CardHeader>
<CardTitle>{tenant.name}</CardTitle>
<CardDescription>{tenant.domain}</CardDescription>
</CardHeader>
<CardContent>
<Badge variant={tenant.isActive ? "default" : "secondary"}>
{tenant.isActive ? "Active" : "Suspended"}
</Badge>
<p className="text-muted-foreground text-sm">
Created {formatDate(tenant.createdAt)}
</p>
</CardContent>
{showActions && <CardFooter>{/* edit, archive, etc. */}</CardFooter>}
</Card>
)
}
export function TenantCompactCard({ tenant }: { tenant: TenantDto }) {
return (
<Card className="bg-muted/30">
<CardHeader>
<CardTitle className="text-base">{tenant.name}</CardTitle>
</CardHeader>
</Card>
)
}Variant suffixes
| Variant | Suffix | Example |
|---|---|---|
| Full / default | none | TenantCard |
| Compact | Compact | TenantCompactCard |
| Health / status | Health | TenantHealthCard |
| Metric / KPI | Stats | TenantStatsCard |
| Detail-only | Detail | TenantDetailCard |
Anti-patterns
- Form logic inside cards — 12 onboarding files do this. Lift state to
client.tsxor the form. - Reinventing primitives — use
Card, not<div className="rounded-lg border p-6">. - Inline formatters —
Intl.NumberFormatbelongs inutil.ts. - Untyped props — import from
types.ts. - Hardcoded labels — use the dictionary slice for translatable text.
Sibling roles
- Rendered by
content.tsx,client.tsx, ordetail.tsx. - Imports from
types.ts,util.ts,config.ts. - Does not import from
actions.ts,queries.ts,form.tsx. - Does not call server actions — handlers live one level up.
Naming
- File:
card.tsx. - Function:
<Feature>Cardfor default, suffix-coded variants per the table above.