feat(ui): add theme-aware stats and finance carousel
This commit is contained in:
@@ -22,6 +22,10 @@ assert.ok(
|
||||
globalsCss.includes('@import "poyraz-ui/preset.css";'),
|
||||
"Poyraz UI preset must be imported by app/globals.css",
|
||||
);
|
||||
assert.ok(
|
||||
globalsCss.includes("@custom-variant dark (&:where(.dark, .dark *));"),
|
||||
"Tailwind dark utilities must follow Neta's explicit root color mode",
|
||||
);
|
||||
|
||||
for (const component of [
|
||||
"SidebarProvider",
|
||||
@@ -62,7 +66,11 @@ assert.doesNotMatch(
|
||||
assert.match(settingsPage, /\bRadioGroup\b/, "Settings must use the Poyraz RadioGroup for theme selection");
|
||||
for (const workspaceControl of [
|
||||
'name="workspaceName"',
|
||||
'name="logo"',
|
||||
'name="metaTitle"',
|
||||
'name="shortName"',
|
||||
'name="lightLogo"',
|
||||
'name="darkLogo"',
|
||||
'name="favicon"',
|
||||
'name="primaryColor"',
|
||||
]) {
|
||||
assert.ok(
|
||||
@@ -70,6 +78,12 @@ for (const workspaceControl of [
|
||||
`Settings must expose workspace branding control ${workspaceControl}`,
|
||||
);
|
||||
}
|
||||
assert.ok(settingsPage.includes('useState("Genel")'), "Workspace and appearance settings must share the General tab");
|
||||
assert.doesNotMatch(
|
||||
settingsPage,
|
||||
/\{\s*name:\s*"Görünüm"/,
|
||||
"Appearance must not remain as a separate settings tab",
|
||||
);
|
||||
for (const colorMode of ["light", "dark", "system"]) {
|
||||
assert.ok(
|
||||
settingsPage.includes(`value: "${colorMode}"`),
|
||||
@@ -88,17 +102,77 @@ assert.ok(
|
||||
fs.existsSync(path.join(repoRoot, "server/settings/preferences.ts")),
|
||||
"Missing database-backed user preferences service",
|
||||
);
|
||||
assert.match(
|
||||
settingsPage,
|
||||
/md:sticky md:top-8/,
|
||||
"The desktop settings navigation must remain sticky while its content scrolls",
|
||||
);
|
||||
assert.equal(
|
||||
fs.existsSync(path.join(repoRoot, "app/favicon.ico")),
|
||||
false,
|
||||
"Static App Router favicon must not override database-backed branding metadata",
|
||||
);
|
||||
|
||||
const requiredSystemCompositions = [
|
||||
"components/system/page-header.tsx",
|
||||
"components/system/feedback-state.tsx",
|
||||
"components/system/status-badge.tsx",
|
||||
"components/system/destructive-confirmation.tsx",
|
||||
"components/system/stat-card.tsx",
|
||||
];
|
||||
for (const file of requiredSystemCompositions) {
|
||||
assert.ok(fs.existsSync(path.join(repoRoot, file)), `Missing Neta system composition: ${file}`);
|
||||
}
|
||||
|
||||
const statCard = fs.readFileSync(
|
||||
path.join(repoRoot, "components/system/stat-card.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
for (const semanticTone of [
|
||||
"bg-success text-success-icon",
|
||||
"bg-info text-info-icon",
|
||||
"bg-warning text-warning-icon",
|
||||
"bg-destructive-muted text-destructive-muted-foreground",
|
||||
]) {
|
||||
assert.ok(
|
||||
statCard.includes(semanticTone),
|
||||
`Stat cards must use Poyraz's theme-aware ${semanticTone} tokens`,
|
||||
);
|
||||
}
|
||||
|
||||
for (const statPage of [
|
||||
"app/(dashboard)/dashboard-client.tsx",
|
||||
"app/(dashboard)/clients/clients-client.tsx",
|
||||
"app/(dashboard)/projects/projects-client.tsx",
|
||||
"app/(dashboard)/journal/journal-client.tsx",
|
||||
"app/(dashboard)/finance/finance-client.tsx",
|
||||
]) {
|
||||
const content = fs.readFileSync(path.join(repoRoot, statPage), "utf8");
|
||||
assert.ok(
|
||||
content.includes('from "@/components/system/stat-card"'),
|
||||
`${statPage} must use the shared theme-aware stat card`,
|
||||
);
|
||||
}
|
||||
|
||||
const financePage = fs.readFileSync(
|
||||
path.join(repoRoot, "app/(dashboard)/finance/finance-client.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
for (const sliderBehavior of [
|
||||
"financeSummaryCardConfig",
|
||||
"featured: true",
|
||||
"snap-mandatory",
|
||||
"overflow-x-auto",
|
||||
"scrollBy",
|
||||
'event.key === "ArrowLeft"',
|
||||
'event.key === "ArrowRight"',
|
||||
]) {
|
||||
assert.ok(
|
||||
financePage.includes(sliderBehavior),
|
||||
`Finance summary slider is missing ${sliderBehavior}`,
|
||||
);
|
||||
}
|
||||
|
||||
const allowedLocalUiFiles = new Set([
|
||||
"pending-link.tsx",
|
||||
"pending-submit-button.tsx",
|
||||
|
||||
Reference in New Issue
Block a user