Files
temetro/frontend/components/auth/auth-ui.tsx
T
Khalid Abdi a07966ca4d frontend: light-mode logo via CSS invert + prescriptions search
- sidebar + auth logo now invert to black in light mode (dark unchanged),
  same trick the docs site uses — no second asset needed
- prescriptions page: search by patient, file number, medication,
  prescriber or status, with no-match / empty states

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 20:16:22 +03:00

114 lines
2.5 KiB
TypeScript

import Image from "next/image";
import type { ReactNode } from "react";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { cn } from "@/lib/utils";
// temetro logo + wordmark, centered.
export function AuthBrand() {
return (
<div className="flex items-center justify-center gap-3">
{/* White fox mark — inverted to black in light mode. */}
<Image
alt="temetro"
className="size-11 invert dark:invert-0"
height={44}
priority
src="/temetro-logo.png"
width={44}
/>
<span className="text-2xl font-semibold tracking-tight">temetro</span>
</div>
);
}
// Centered page wrapper for every auth screen: brand on top, content below.
export function AuthLayout({ children }: { children: ReactNode }) {
return (
<div className="flex min-h-full w-full items-center justify-center px-4 py-12">
<div className="flex w-full max-w-sm flex-col gap-6">
<AuthBrand />
{children}
</div>
</div>
);
}
// Card-based shell for the non-block auth pages (onboarding, verify, reset,
// forgot-password, accept-invite).
export function AuthShell({
title,
subtitle,
children,
footer,
}: {
title: string;
subtitle?: ReactNode;
children: ReactNode;
footer?: ReactNode;
}) {
return (
<AuthLayout>
<Card>
<CardHeader className="text-center">
<CardTitle className="text-xl">{title}</CardTitle>
{subtitle && <CardDescription>{subtitle}</CardDescription>}
</CardHeader>
<CardContent>{children}</CardContent>
</Card>
{footer && (
<div className="text-center text-sm text-muted-foreground">{footer}</div>
)}
</AuthLayout>
);
}
export function Field({
label,
htmlFor,
hint,
children,
}: {
label: string;
htmlFor: string;
hint?: ReactNode;
children: ReactNode;
}) {
return (
<div className="flex flex-col gap-1.5">
<label className="text-sm font-medium text-foreground" htmlFor={htmlFor}>
{label}
</label>
{children}
{hint && <p className="text-xs text-muted-foreground">{hint}</p>}
</div>
);
}
export function FormAlert({
tone = "error",
children,
}: {
tone?: "error" | "success";
children: ReactNode;
}) {
return (
<p
className={cn(
"rounded-2xl px-3 py-2 text-sm",
tone === "error"
? "bg-destructive/10 text-destructive"
: "bg-primary/10 text-primary"
)}
>
{children}
</p>
);
}