Admin Dashboard Pages Redesign
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Design each admin dashboard page with consistent layout, proper spacing, and professional UI matching the premium gold accent design system.
Architecture: Each page follows a consistent structure with AdminCard wrappers, StatBadge status indicators, and proper spacing using Tailwind.
Tech Stack: Next.js, Tailwind CSS, shadcn/ui components, lucide-react icons
File Inventory
Existing Components (to enhance)
apps/frontend/components/admin/metric-card.tsx- Metric display cardsapps/frontend/components/admin/sidebar.tsx- Left navigation sidebarapps/frontend/components/admin/reservation-filters.tsx- Filter controlsapps/frontend/components/admin/show-table-row.tsx- Table row with status
New Components to Create
apps/frontend/components/admin/admin-card.tsx- Card wrapper with header/contentapps/frontend/components/admin/stat-badge.tsx- Colored status badgeapps/frontend/components/admin/page-header.tsx- Page title + actions header
Task 1: Create AdminCard Component
Files:
-
Create:
apps/frontend/components/admin/admin-card.tsx -
Step 1: Create AdminCard component
// apps/frontend/components/admin/admin-card.tsx
// ipsoc checked: 2026-05-05
// SoC: Pure presentation - card container for dashboard sections
import { cn } from "~/lib/utils";
interface AdminCardProps {
title?: string;
children: React.ReactNode;
className?: string;
action?: React.ReactNode;
}
export function AdminCard({
title,
children,
className,
action,
}: AdminCardProps) {
return (
<div
className={cn(
"bg-[#1a1a1a] border border-[#333333] rounded-lg",
className,
)}
>
{title && (
<div className="flex items-center justify-between px-4 py-3 border-b border-[#333333]">
<h3 className="text-lg font-serif text-[#e6e6e6]">{title}</h3>
{action}
</div>
)}
<div className="p-4">{children}</div>
</div>
);
}Task 2: Create StatBadge Component
Files:
-
Create:
apps/frontend/components/admin/stat-badge.tsx -
Step 1: Create StatBadge component
// apps/frontend/components/admin/stat-badge.tsx
// ipsoc checked: 2026-05-05
// SoC: Pure presentation - colored status badge
import { cn } from "~/lib/utils";
type BadgeVariant = "success" | "warning" | "danger" | "neutral" | "gold";
interface StatBadgeProps {
children: React.ReactNode;
variant?: BadgeVariant;
className?: string;
}
const variantStyles: Record<BadgeVariant, string> = {
success: "bg-green-500/20 text-green-400 border-green-500/30",
warning: "bg-yellow-500/20 text-yellow-400 border-yellow-500/30",
danger: "bg-red-500/20 text-red-400 border-red-500/30",
neutral: "bg-[#2E2E2E] text-[#808080] border-[#333333]",
gold: "bg-[#C5A059]/20 text-[#C5A059] border-[#C5A059]/30",
};
export function StatBadge({
children,
variant = "neutral",
className,
}: StatBadgeProps) {
return (
<span
className={cn(
"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border",
variantStyles[variant],
className,
)}
>
{children}
</span>
);
}Task 3: Create PageHeader Component
Files:
-
Create:
apps/frontend/components/admin/page-header.tsx -
Step 1: Create PageHeader component
// apps/frontend/components/admin/page-header.tsx
// ipsoc checked: 2026-05-05
// SoC: Pure presentation - consistent page header
import { cn } from "~/lib/utils";
interface PageHeaderProps {
title: string;
subtitle?: string;
actions?: React.ReactNode;
className?: string;
}
export function PageHeader({
title,
subtitle,
actions,
className,
}: PageHeaderProps) {
return (
<div className={cn("flex items-center justify-between", className)}>
<div>
<h1 className="text-2xl font-serif text-[#C5A059]">{title}</h1>
{subtitle && <p className="text-sm text-[#808080] mt-1">{subtitle}</p>}
</div>
{actions && <div className="flex items-center gap-2">{actions}</div>}
</div>
);
}Task 4: Update Dashboard Overview Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/admin/page.tsx -
Step 1: Read current admin dashboard page
cat apps/frontend/app/[locale]/dashboard/admin/page.tsx- Step 2: Update imports to use new components
Add imports for AdminCard, StatBadge, PageHeader.
- Step 3: Wrap AtRiskList in AdminCard
<AdminCard title={t("atRiskOccurrences")}>
<AtRiskList occurrences={atRiskOccurrences ?? []} />
</AdminCard>- Step 4: Wrap RecentReservations in AdminCard
<AdminCard title={t("recentReservations")}>
<RecentReservations reservations={recentReservations ?? []} />
</AdminCard>Task 5: Update Shows Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/admin/shows/page.tsx -
Step 1: Read current shows page
cat apps/frontend/app/[locale]/dashboard/admin/shows/page.tsx- Step 2: Add PageHeader with Add button
import { PageHeader } from "~/components/admin/page-header";
<PageHeader
title={t("title")}
actions={
<Button variant="outlineGold" size="sm" onClick={handleAddNew}>
<Plus className="w-4 h-4 mr-2" />
{t("addNew")}
</Button>
}
/>;- Step 3: Wrap table in AdminCard
<AdminCard>
<Table>...</Table>
</AdminCard>Task 6: Update Analytics Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/admin/analytics/page.tsx -
Step 1: Read current analytics page
cat apps/frontend/app/[locale]/dashboard/admin/analytics/page.tsx- Step 2: Add PageHeader
import { PageHeader } from "~/components/admin/page-header";
<PageHeader title={t("title")} />;- Step 3: Wrap revenue section in AdminCard
<AdminCard title={t("revenueByShow")}>
<div className="space-y-2">
{topShows?.map((show: TopShowRevenue, idx: number) => (
<div
key={show.showTitle}
className="flex justify-between items-center p-3 bg-[#2E2E2E] rounded"
>
<span className="text-[#e6e6e6]">
{idx + 1}. {show.showTitle}
</span>
<span className="text-[#C5A059] font-serif">
{show.revenue.toLocaleString()} VND
</span>
</div>
))}
</div>
</AdminCard>Task 7: Update Occurrences Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/admin/occurrences/page.tsx -
Step 1: Read current occurrences page
cat apps/frontend/app/[locale]/dashboard/admin/occurrences/page.tsx- Step 2: Add PageHeader with batch create button
import { PageHeader } from "~/components/admin/page-header";
<PageHeader
title={t("title")}
actions={
<LocaleLink href="/dashboard/admin/occurrences/batch">
<Button variant="outlineGold" size="sm">
<Plus className="w-4 h-4 mr-2" />
{t("batchCreate")}
</Button>
</LocaleLink>
}
/>;Task 8: Update Checkin Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/admin/checkin/page.tsx -
Step 1: Read current checkin page
cat apps/frontend/app/[locale]/dashboard/admin/checkin/page.tsx- Step 2: Wrap scanner section in AdminCard
<AdminCard title="Scanner">{/* Scanner content */}</AdminCard>- Step 3: Wrap ticket detail in AdminCard
<AdminCard title="Ticket Details">{/* Ticket detail content */}</AdminCard>Task 9: Update POS Reception Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/pos/reception/page.tsx -
Step 1: Read current reception page
cat apps/frontend/app/[locale]/dashboard/pos/reception/page.tsx- Step 2: Add PageHeader
<PageHeader title={t("pos.reception.title")} />- Step 3: Wrap floor plan in AdminCard
<AdminCard>
<Suspense fallback={<ReceptionLoading />}>
<FloorPlan />
</Suspense>
</AdminCard>Task 10: Update POS Kitchen Page
Files:
-
Modify:
apps/frontend/app/[locale]/dashboard/pos/kitchen/page.tsx -
Step 1: Read current kitchen page
cat apps/frontend/app/[locale]/dashboard/pos/kitchen/page.tsx- Step 2: Add PageHeader with station tabs
<PageHeader
title={t("pos.kitchen.title")}
actions={
<div className="flex gap-2">
{STATIONS.map((station) => (
<a key={station.key} href={`?station=${station.key}`}>
<Button
variant={currentStation === station.key ? "default" : "outlineGold"}
size="sm"
>
{t(station.labelKey)}
</Button>
</a>
))}
</div>
}
/>Verification
After all tasks, verify each page:
/dashboard- Metric cards + AtRiskList + RecentReservations with AdminCard wrappers/dashboard/admin/shows- Table in AdminCard with PageHeader/dashboard/admin/occurrences- Calendar with PageHeader/dashboard/admin/reservations- Filters + Table in AdminCard/dashboard/admin/checkin- Scanner + Ticket detail in AdminCards/dashboard/admin/addons- Addon cards in AdminCard/dashboard/admin/analytics- Revenue list in AdminCard with PageHeader/dashboard/pos/reception- Floor plan in AdminCard with PageHeader/dashboard/pos/kitchen- Kitchen board with PageHeader + station tabs/dashboard/pos/staff- Table selection grid + ordering view