MiHCM

Templates

Full-page layouts assembled from patterns and primitives. Each preview below is a live render using @mihcm/ui components. Copy the structure, replace the content, adjust to your domain.

Templates are grouped by purpose. Marketing templates are for public website and campaign surfaces; application templates are for authenticated product workflows.

Marketing templates

These pages use MiHCM primitives and semantic tokens for campaign and website work. They should stay separate from the core application layouts.

Product landing page

A compact marketing page with hero, product proof, module snapshot, and outcome CTAs. Use it for product pages, campaign pages, and partner-facing explainers.

Production previewMiHCM + Tailwind
MiHCM workforce suiteA cleaner operating layer for payroll, HR, and employee service.A website template for product pages that need a clear value proposition, product proof, and direct demo conversion without custom CSS.
Workforce operationsLive readiness dashboard
Ready
Payroll
98% configured
Core HR
91% complete
Leave
88% approved
Analytics
76% connected
15+
Countries
1M+
Records
99.9%
Uptime
import { Badge } from '@mihcm/ui/Badge';
import { Button } from '@mihcm/ui/Button';
import { Card } from '@mihcm/ui/Card';
import { StatCard } from '@mihcm/ui/StatCard';
import { Text } from '@mihcm/ui/Text';

export default function ProductLandingPage() {
  return (
    <main className="bg-background text-foreground">
      <section className="grid gap-6 rounded-lg border border-border bg-card p-6 lg:grid-cols-2 lg:p-8">
        <div>
          <Badge variant="outline">MiHCM for growing teams</Badge>
          <Text size="3xl" weight="bold" className="mt-4 block leading-tight">
            Modern HR operations without fragmented tools.
          </Text>
          <Text size="body" tone="muted" className="mt-3 block">
            Say the business outcome clearly and keep the CTA focused.
          </Text>
          <div className="mt-6 flex flex-wrap gap-3">
            <Button>Book a demo</Button>
            <Button variant="outline">See platform tour</Button>
          </div>
        </div>
        <Card className="bg-muted p-4">
          <Text size="body-sm" weight="semibold">Platform overview</Text>
          <div className="mt-4 space-y-3">
            {modules.map((module) => (
              <div key={module.name} className="rounded-md border border-border bg-card p-3">
                <Text size="body-sm" weight="medium">{module.name}</Text>
              </div>
            ))}
          </div>
        </Card>
      </section>

      <section className="grid gap-3 border-x border-b border-border bg-muted p-4 sm:grid-cols-3">
        <StatCard tone="primary" value="15+" label="Countries" />
        <StatCard tone="accent" value="1M+" label="Records" />
        <StatCard tone="success" value="99.9%" label="Uptime" />
      </section>
    </main>
  );
}
What to swap:
  • Replace headline and supporting copy with one product outcome.
  • Replace proof metrics with verified business claims.
  • Keep all visual styling on semantic token classes.

Pricing and plan page

A marketing template for plan comparison. It provides a recommended plan, short feature list, and comparison table without requiring a custom visual system.

Production previewMiHCM + Tailwind
Plan architectureChoose the operating model that fits your HR teamA pricing page template with a plan signal, short plan descriptions, and comparison evidence for buyer confidence.
CoreFor HR recordkeeping
Start
GrowthFor payroll and workflows
Popular
EnterpriseFor multi-country operations
Scale
Feature
Core
Growth
Enterprise
Employee records
Included
Included
Advanced
Approval workflows
Included
Included
Advanced
Payroll controls
Included
Included
Advanced
import { Badge } from '@mihcm/ui/Badge';
import { Button } from '@mihcm/ui/Button';
import { Card } from '@mihcm/ui/Card';
import { Text } from '@mihcm/ui/Text';

export default function PricingPage() {
  return (
    <main className="space-y-5 bg-background text-foreground">
      <div className="max-w-2xl">
        <Text size="2xl" weight="bold" className="block">
          Choose the operating model that fits your HR team
        </Text>
        <Text size="body-sm" tone="muted" className="mt-2 block">
          Make plan differences easy to compare before a buyer contacts sales.
        </Text>
      </div>

      <div className="grid gap-4 lg:grid-cols-3">
        {plans.map((plan) => (
          <Card key={plan.name} className={plan.highlight ? 'border-primary shadow-mi-card' : undefined}>
            <div className="p-5">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <Text size="lg" weight="bold" className="block">{plan.name}</Text>
                  <Text size="body-sm" tone="muted" className="mt-1 block">{plan.description}</Text>
                </div>
                <Badge variant={plan.highlight ? 'default' : 'outline'}>{plan.label}</Badge>
              </div>
              <Button className="mt-5 w-full" variant={plan.highlight ? 'default' : 'outline'}>
                Request pricing
              </Button>
            </div>
          </Card>
        ))}
      </div>
    </main>
  );
}
What to swap:
  • Use one highlighted plan only.
  • Keep comparison rows short and factual.
  • Avoid raw colour classes when emphasizing the recommended plan.

Application templates

These templates are for authenticated product experiences. They prioritize work density, role-specific actions, and predictable navigation.

Admin dashboard

The primary MiHCM admin surface. A page shell with stat cards, a scoped search bar, and a master-detail role editor.

Production previewMiHCM + Tailwind
Security command centerMonitor access health, high-risk role changes, and reviewer ownership.
6
Active Roles
18
Open Reviews
92%
Policy Match
AdministratorFull system access with all sensitive permissions enabled.
Quarterly review
User ManagementFull Access
Payroll ControlApproval only
ReportsView + export
System ConfigOwner required
import { PageShell } from '@mihcm/ui/PageShell';
import { TopBar, TopBarLogo, TopBarBackLink, TopBarNotification, TopBarProfile, TopBarDivider, TopBarAction } from '@mihcm/ui/TopBar';
import { MainSidebar } from '@mihcm/ui/MainSidebar';
import { TitleBar } from '@mihcm/ui/TitleBar';
import { StatCard } from '@mihcm/ui/StatCard';
import { SearchField } from '@mihcm/ui/SearchField';
import { Card } from '@mihcm/ui/Card';
import { Avatar, AvatarFallback, AvatarImage } from '@mihcm/ui/Avatar';

export default function AdminDashboard() {
  const [active, setActive] = useState('security');
  return (
    <PageShell
      topBar={
        <TopBar
          start={<><TopBarLogo /><TopBarBackLink>Back to main</TopBarBackLink><TopBarNotification icon={<BellIcon />} count={5} /></>}
          end={<><TopBarProfile name="Good Morning Yashi" avatar={<Avatar><AvatarImage src="/people/alex-kim.svg" alt="Yashi" /><AvatarFallback>YA</AvatarFallback></Avatar>} /><TopBarDivider /><TopBarAction>Logout</TopBarAction></>}
        />
      }
      sidebar={<MainSidebar items={NAV} activeKey={active} onItemSelect={setActive} />}
      titleBar={<TitleBar supertitle="User Administration" title="Security & Permissions" />}
    >
      {/* Search bar */}
      <Card className="p-4 mb-4 flex items-center gap-4">
        <SearchField placeholder="Search by name or email..." className="flex-1" />
      </Card>

      {/* Quick stats */}
      <div className="grid grid-cols-1 gap-3 sm:grid-cols-3 mb-4">
        <StatCard tone="primary" value="6" label="Active Roles" />
        <StatCard tone="accent" value="13,283" label="Total Users" />
        <StatCard tone="success" value="16" label="Modules" />
      </div>

      {/* Master-detail card */}
      <Card className="flex-1 flex flex-col md:flex-row min-h-0 overflow-hidden">
        <aside className="w-full overflow-y-auto border-b border-secondary md:basis-72 md:border-b-0 md:border-r">
          <RoleList />
        </aside>
        <main className="flex-1 bg-muted overflow-y-auto p-4">
          <RoleEditor />
        </main>
      </Card>
    </PageShell>
  );
}
What to swap:
  • Replace NAV items with your module's sidebar entries.
  • Replace StatCard values with your domain metrics.
  • Replace RoleList / RoleEditor with your list and detail components.

Settings page

A single-column settings form with grouped sections. Uses SectionHeader to divide control groups and Switch / Input for toggles and fields.

Production previewMiHCM + Tailwind

General

Manage your account preferences.

Profile
NotificationsChoose how you want to be notified.
import { PageShell } from '@mihcm/ui/PageShell';
import { TitleBar } from '@mihcm/ui/TitleBar';
import { Card, CardHeader, CardTitle, CardDescription } from '@mihcm/ui/Card';
import { SectionHeader } from '@mihcm/ui/SectionHeader';
import { Switch } from '@mihcm/ui/Switch';
import { Input } from '@mihcm/ui/Input';
import { Label } from '@mihcm/ui/Label';
import { Button } from '@mihcm/ui/Button';
import { Avatar, AvatarFallback, AvatarImage } from '@mihcm/ui/Avatar';

export default function SettingsPage() {
  return (
    <PageShell
      topBar={
        <TopBar
          start={<><TopBarLogo /></>}
          end={<><TopBarProfile avatar={<Avatar><AvatarImage src="/people/alex-kim.svg" alt="Yashi" /><AvatarFallback>YA</AvatarFallback></Avatar>} /><TopBarDivider /><TopBarAction>Logout</TopBarAction></>}
        />
      }
      titleBar={<TitleBar supertitle="Account" title="Settings" />}
    >
      <Card className="max-w-2xl">
        <CardHeader>
          <CardTitle>General</CardTitle>
          <CardDescription>Manage your account preferences.</CardDescription>
        </CardHeader>
        <div className="px-6 pb-6 space-y-6">
          <SectionHeader title="Profile" />
          <div className="grid gap-4 sm:grid-cols-2">
            <div>
              <Label>First name</Label>
              <Input placeholder="Yashi" className="mt-1.5" />
            </div>
            <div>
              <Label>Last name</Label>
              <Input placeholder="Alnashri" className="mt-1.5" />
            </div>
          </div>

          <SectionHeader title="Notifications" description="Choose how you want to be notified." />
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <Label>Email digest</Label>
              <Switch checked={emailDigest} onCheckedChange={setEmailDigest} />
            </div>
            <div className="flex items-center justify-between">
              <Label>Push notifications</Label>
              <Switch checked={pushNotifications} onCheckedChange={setPushNotifications} />
            </div>
          </div>

          <div className="flex justify-end gap-3 pt-4 border-t border-secondary">
            <Button variant="outline">Cancel</Button>
            <Button>Save changes</Button>
          </div>
        </div>
      </Card>
    </PageShell>
  );
}
What to swap:
  • Add or remove SectionHeader groups to match your settings structure.
  • Replace Input fields with your form state.
  • Plug in your save handler on the primary Button.

Permission editor

A role configuration view with access-level controls and a permission list. Matches the MiHCM Security prototype's editor panel.

Production previewMiHCM + Tailwind
HR ManagerManages employee records and leave approvals.
Active
Module AccessSet the access level for each module.
3 of 16 enabled
Employee RecordsFull
Leave ManagementEdit
PayrollView
ReportsNone
import { SectionHeader } from '@mihcm/ui/SectionHeader';
import { AccessLevelGroup } from '@mihcm/ui/AccessLevelGroup';
import { CheckboxGrid } from '@mihcm/ui/CheckboxGrid';
import { StatusBadge } from '@mihcm/ui/StatusBadge';
import { Text } from '@mihcm/ui/Text';
import { Button } from '@mihcm/ui/Button';

export default function PermissionEditor({ role }) {
  return (
    <div className="p-4 lg:p-6 space-y-6">
      {/* Role header */}
      <div className="flex items-center justify-between">
        <div>
          <Text size="lg" weight="bold" className="block">{role.name}</Text>
          <Text size="body-sm" tone="muted" className="block mt-1">{role.description}</Text>
        </div>
        <StatusBadge tone={role.active ? 'success' : 'neutral'}>
          {role.active ? 'Active' : 'Inactive'}
        </StatusBadge>
      </div>

      {/* Module access */}
      <SectionHeader
        title="Module Access"
        description="Set the access level for each module."
        action={<Text size="label" tone="muted">3 of 16 enabled</Text>}
      />
      <div className="space-y-3">
        {role.modules.map(mod => (
          <div key={mod.id} className="flex items-center justify-between">
            <Text size="body-sm">{mod.name}</Text>
            <AccessLevelGroup value={mod.level} onValueChange={v => updateModule(mod.id, v)} />
          </div>
        ))}
      </div>

      {/* Fine-grained permissions */}
      <SectionHeader title="Permissions" description="Toggle individual capabilities." />
      <CheckboxGrid items={role.permissions} onChange={setPermissions} />

      {/* Actions */}
      <div className="flex justify-end gap-3 pt-4 border-t border-secondary">
        <Button variant="outline">Discard</Button>
        <Button>Save role</Button>
      </div>
    </div>
  );
}
What to swap:
  • Replace role.modules and role.permissions with your data.
  • Wire updateModule and setPermissions to your state management.
  • Adjust the StatusBadge to reflect your domain's status model.

Product onboarding checklist

A guided setup template for administrators. Use it when a product area requires a sequence of required setup tasks before the user can operate confidently.

Production previewMiHCM + Tailwind
Set up payroll operationsGuide new administrators through the minimum viable setup.
3 of 5 complete
Company profileOwner: Payroll admin
Complete
Pay groupsOwner: Payroll admin
Complete
Approval workflowOwner: Payroll admin
In progress
Bank file exportOwner: Payroll admin
Not started
Final reviewOwner: Payroll admin
Locked
Next best actionFinish the approval workflow so test payroll can run without manual escalation.
60%
import { Button } from '@mihcm/ui/Button';
import { Card } from '@mihcm/ui/Card';
import { SectionHeader } from '@mihcm/ui/SectionHeader';
import { StatusBadge } from '@mihcm/ui/StatusBadge';
import { Text } from '@mihcm/ui/Text';

export default function ProductOnboarding() {
  return (
    <div className="grid gap-4 lg:grid-cols-3">
      <Card className="p-5 lg:col-span-2">
        <SectionHeader
          title="Set up payroll operations"
          description="Guide new administrators through the minimum viable setup."
          action={<StatusBadge tone="info">3 of 5 complete</StatusBadge>}
        />
        <div className="mt-5 space-y-3">
          {tasks.map((task) => (
            <div key={task.name} className="flex items-center justify-between rounded-md border border-border p-3">
              <div>
                <Text size="body-sm" weight="semibold" className="block">{task.name}</Text>
                <Text size="caption" tone="muted" className="mt-1 block">{task.owner}</Text>
              </div>
              <StatusBadge tone={task.tone}>{task.state}</StatusBadge>
            </div>
          ))}
        </div>
      </Card>
      <Card className="p-5">
        <Text size="lg" weight="bold" className="block">Next best action</Text>
        <Text size="body-sm" tone="muted" className="mt-2 block">
          Explain the next task and why it matters.
        </Text>
        <Button className="mt-5 w-full">Continue setup</Button>
      </Card>
    </div>
  );
}
What to swap:
  • Replace tasks with your onboarding checklist.
  • Use StatusBadge tones for state, not raw colours.
  • Keep one next-best action visible beside the checklist.

Analytics workspace

A dashboard template for workforce metrics, priority insights, and export actions. Use it when users need to compare KPIs and investigate changes.

Production previewMiHCM + Tailwind
Workforce analyticsRetention, hiring, and payroll indicators with owners attached.
7.4%
Attrition
18
Open roles
94%
Payroll SLA
Headcount trend
EngineeringUp 8%
OperationsFlat
Customer successUp 3%
Priority insights
Alex KimMaya ChenNoah Smith
Payroll exceptions fell 12%
Hiring velocity is flat
Leave balance risk in 2 teams
import { Button } from '@mihcm/ui/Button';
import { Card } from '@mihcm/ui/Card';
import { StatCard } from '@mihcm/ui/StatCard';
import { StatusBadge } from '@mihcm/ui/StatusBadge';
import { Text } from '@mihcm/ui/Text';

export default function AnalyticsWorkspace() {
  return (
    <div className="space-y-4">
      <Card className="p-4">
        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div>
            <Text size="lg" weight="bold">Workforce analytics</Text>
            <Text size="body-sm" tone="muted" className="mt-1 block">
              Retention, hiring, and payroll indicators.
            </Text>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button variant="outline">This quarter</Button>
            <Button variant="outline">Export</Button>
          </div>
        </div>
      </Card>
      <div className="grid gap-3 sm:grid-cols-3">
        <StatCard tone="primary" value="7.4%" label="Attrition" />
        <StatCard tone="accent" value="18" label="Open roles" />
        <StatCard tone="success" value="94%" label="Payroll SLA" />
      </div>
      <div className="grid gap-4 lg:grid-cols-2">
        <Card className="p-5">
          <Text size="body-sm" weight="semibold" className="block">Headcount trend</Text>
          <div className="mt-4 space-y-3">
            {teams.map((team) => (
              <div key={team.name} className="flex items-center justify-between rounded-md border border-border p-3">
                <Text size="body-sm" weight="medium">{team.name}</Text>
                <StatusBadge tone={team.tone}>{team.trend}</StatusBadge>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </div>
  );
}
What to swap:
  • Use StatCard for comparable headline metrics.
  • Use StatusBadge for trend labels instead of hand-coded colour styles.
  • Keep export and date-range actions in the workspace header.

What's next