"use client";
import type { CSSProperties, ReactNode } from "react";
import { Icons, type IconName } from "./icons";
// ── Header (sticky top) ─────────────────────────────────
export function Header({
title,
subtitle,
left,
right,
big = false,
sticky = true,
}: {
title: string;
subtitle?: ReactNode;
left?: ReactNode;
right?: ReactNode;
big?: boolean;
sticky?: boolean;
}) {
if (big) {
return (
{title}
{subtitle && (
{subtitle}
)}
{right && (
{right}
)}
);
}
return (
);
}
// ── Icon button (44×44, round) ─────────────────────────
export function IconBtn({
icon,
onClick,
label,
variant = "ghost",
size = 22,
stroke = 1.75,
...rest
}: {
icon: IconName;
onClick?: () => void;
label?: string;
variant?: "ghost" | "muted" | "glass" | "glass-dark";
size?: number;
stroke?: number;
} & React.ButtonHTMLAttributes) {
const I = Icons[icon];
const bg =
variant === "ghost"
? "transparent"
: variant === "glass"
? "rgba(255,255,255,0.85)"
: variant === "glass-dark"
? "rgba(20,16,10,0.55)"
: "var(--muted)";
const fg =
variant === "glass-dark"
? "#fff"
: variant === "glass"
? "#1a1612"
: "var(--foreground)";
const backdrop = variant.startsWith("glass")
? "blur(20px) saturate(180%)"
: undefined;
return (
);
}
// ── Bottom tab bar ──────────────────────────────────────
export function TabBar({
active,
onTab,
onFab,
showFab = true,
}: {
active: string;
onTab: (id: string) => void;
onFab: () => void;
showFab?: boolean;
}) {
const tabs: { id: string; label: string; icon: IconName }[] = [
{ id: "places", label: "Địa điểm", icon: "MapPin" },
{ id: "collections", label: "Bộ sưu tập", icon: "Folder" },
{ id: "profile", label: "Hồ sơ", icon: "User" },
];
return (
{tabs.map((t) => {
const I = Icons[t.icon];
const isActive = active === t.id;
return (
);
})}
{showFab && (
)}
);
}
// ── Offline banner ──────────────────────────────────────
export function OfflineBanner() {
return (
Đang xem bản offline. Một số thao tác bị tạm khóa.
);
}
// ── Empty state ─────────────────────────────────────────
export function EmptyState({
icon = "MapPin",
title,
body,
cta,
}: {
icon?: IconName;
title: string;
body: string;
cta?: ReactNode;
}) {
const I = Icons[icon];
return (
);
}
// ── Checkbox ──────────────────────────────────────────
export function Checkbox({
checked,
onClick,
}: {
checked?: boolean;
onClick?: () => void;
}) {
return (
);
}
// ── Menu item (in sheet) ────────────────────────────────
export function MenuItem({
icon,
label,
onClick,
danger = false,
}: {
icon: IconName;
label: string;
onClick?: () => void;
danger?: boolean;
}) {
const I = Icons[icon];
return (
);
}
// ── Field label (form) ──────────────────────────────────
export function FieldLabel({
children,
required,
}: {
children: ReactNode;
required?: boolean;
}) {
return (
{children}
{required && *}
);
}