TorbatYar/frontend/modules/beauty/design-system/BeautyPrimitives.tsx
Mortezakoohjani 6f4a484051 Migrate Beauty, Healthcare, and Accounting frontend to modular src/modules architecture.
Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 22:28:27 +03:30

98 lines
2.8 KiB
TypeScript

"use client";
import { cn } from "@/lib/utils";
export function Section({
children,
className,
title,
description,
}: {
children: React.ReactNode;
className?: string;
title?: string;
description?: string;
}) {
return (
<section className={cn("space-y-4", className)}>
{title ? (
<div>
<h2 className="font-semibold text-secondary">{title}</h2>
{description ? <p className="mt-1 text-sm text-[var(--muted)]">{description}</p> : null}
</div>
) : null}
{children}
</section>
);
}
export function Hero({
badge,
title,
description,
actions,
}: {
badge?: string;
title: string;
description: string;
actions?: React.ReactNode;
}) {
return (
<section className="relative overflow-hidden border-b border-[var(--border)] bg-gradient-to-b from-[var(--beauty-accent-soft)] to-[var(--canvas)] px-4 py-20 sm:px-6">
<div className="mx-auto max-w-4xl text-center">
{badge ? (
<span className="mb-4 inline-block rounded-full bg-[var(--beauty-accent-soft)] px-4 py-1 text-sm font-medium text-[var(--beauty-accent)]">
{badge}
</span>
) : null}
<h1 className="text-4xl font-bold tracking-tight text-secondary sm:text-5xl">{title}</h1>
<p className="mx-auto mt-4 max-w-2xl text-lg text-[var(--muted)]">{description}</p>
{actions ? <div className="mt-8 flex flex-wrap items-center justify-center gap-3">{actions}</div> : null}
</div>
</section>
);
}
export function StatWidget({
label,
value,
hint,
icon: Icon,
}: {
label: string;
value: string | number;
hint?: string;
icon?: React.ComponentType<{ className?: string }>;
}) {
return (
<div className="rounded-2xl border border-[var(--border)] bg-[var(--surface)] p-5 shadow-[var(--shadow-sm)] transition-shadow hover:shadow-[var(--shadow-md)]">
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-sm text-[var(--muted)]">{label}</p>
<p className="mt-2 text-3xl font-bold tracking-tight text-secondary">{value}</p>
{hint ? <p className="mt-1 text-xs text-[var(--muted)]">{hint}</p> : null}
</div>
{Icon ? (
<div className="rounded-xl bg-[var(--beauty-accent-soft)] p-2.5 text-[var(--beauty-accent)]">
<Icon className="h-5 w-5" />
</div>
) : null}
</div>
</div>
);
}
export function PageSection({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
<div className={cn("mx-auto max-w-6xl px-4 py-8 sm:px-6 lg:py-10", className)}>{children}</div>
);
}
export { SearchResultRow, TimelineItem } from "./BeautyCards";