fix(ui): align portal stats and auth feedback
This commit is contained in:
+2
-27
@@ -1,8 +1,9 @@
|
||||
import { Card, CardContent, Badge } from "poyraz-ui/atoms";
|
||||
import { FolderKanban, CheckCircle2, Clock, BarChart, type LucideIcon } from "lucide-react";
|
||||
import { FolderKanban, CheckCircle2, Clock, BarChart } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { format } from "date-fns";
|
||||
import { tr } from "date-fns/locale";
|
||||
import { StatCard } from "@/components/system/stat-card";
|
||||
import { requirePortalBackend } from "@/server/web/portal";
|
||||
|
||||
export default async function PortalDashboardPage() {
|
||||
@@ -76,29 +77,3 @@ export default async function PortalDashboardPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function StatCard({ label, value, icon: Icon, tone }: {
|
||||
label: string;
|
||||
value: string;
|
||||
icon: LucideIcon;
|
||||
tone: "green" | "blue" | "amber";
|
||||
}) {
|
||||
const toneClass = {
|
||||
green: "bg-emerald-50 text-emerald-700",
|
||||
blue: "bg-blue-50 text-blue-700",
|
||||
amber: "bg-amber-50 text-amber-700",
|
||||
}[tone];
|
||||
return (
|
||||
<Card>
|
||||
<CardContent className="flex items-center justify-between gap-3 p-4">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">{label}</p>
|
||||
<p className="mt-1 text-2xl font-semibold text-foreground">{value}</p>
|
||||
</div>
|
||||
<div className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-sm ${toneClass}`}>
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { toast } from "poyraz-ui/molecules";
|
||||
export function ErrorToaster({ message }: { message: string }) {
|
||||
useEffect(() => {
|
||||
if (message) {
|
||||
toast.error(message);
|
||||
toast.error(message, { id: `route-error:${message}` });
|
||||
}
|
||||
}, [message])
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@ const repoRoot = process.cwd();
|
||||
const packageJson = JSON.parse(fs.readFileSync(path.join(repoRoot, "package.json"), "utf8"));
|
||||
const globalsCss = fs.readFileSync(path.join(repoRoot, "app/globals.css"), "utf8");
|
||||
const appShell = fs.readFileSync(path.join(repoRoot, "components/layout/app-shell.tsx"), "utf8");
|
||||
const errorToaster = fs.readFileSync(
|
||||
path.join(repoRoot, "components/error-toaster.tsx"),
|
||||
"utf8",
|
||||
);
|
||||
const loginActions = fs.readFileSync(path.join(repoRoot, "app/login/actions.ts"), "utf8");
|
||||
const rootLayout = fs.readFileSync(path.join(repoRoot, "app/layout.tsx"), "utf8");
|
||||
const brandingService = fs.readFileSync(
|
||||
@@ -68,6 +72,11 @@ assert.doesNotMatch(
|
||||
/<DropdownMenuItem[^>]*\binteractiveMotion=/s,
|
||||
"Poyraz UI 3.0.2 leaks DropdownMenuItem interactiveMotion to the DOM",
|
||||
);
|
||||
assert.match(
|
||||
errorToaster,
|
||||
/toast\.error\(message,\s*\{\s*id:/,
|
||||
"Route error toasts must use a stable id so React development effects cannot duplicate them",
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
appShell,
|
||||
/<form\s+action=\{signOut\}>/,
|
||||
@@ -183,6 +192,7 @@ for (const statPage of [
|
||||
"app/(dashboard)/projects/projects-client.tsx",
|
||||
"app/(dashboard)/journal/journal-client.tsx",
|
||||
"app/(dashboard)/finance/finance-client.tsx",
|
||||
"app/portal/page.tsx",
|
||||
]) {
|
||||
const content = fs.readFileSync(path.join(repoRoot, statPage), "utf8");
|
||||
assert.ok(
|
||||
|
||||
Reference in New Issue
Block a user