hellth-hub/apps/admin/app/(authed)/einstellungen/_components/settings-tabs.tsx

84 lines
2.5 KiB
TypeScript
Raw Normal View History

"use client";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback } from "react";
export type SettingsTabId =
| "profil"
| "ernaehrung"
| "ziele"
| "sicherheit"
| "anwendung";
const tabs: { id: SettingsTabId; label: string; description: string }[] = [
{ id: "profil", label: "Profil", description: "Persönliche Daten und Kontakt" },
{ id: "ernaehrung", label: "Ernährung", description: "Rezept- und Mahlzeiten-Präferenzen" },
{ id: "ziele", label: "Ziele", description: "Kalorien, Makros, Gewicht, Fasten" },
{ id: "sicherheit", label: "Sicherheit", description: "2FA, Passkeys, Passwort" },
{ id: "anwendung", label: "Anwendung", description: "Erscheinungsbild und Erinnerungen" },
];
export function useSettingsTab(): {
active: SettingsTabId;
setActive: (id: SettingsTabId) => void;
} {
const router = useRouter();
const search = useSearchParams();
const tabParam = search.get("tab");
const active: SettingsTabId =
tabs.find((tab) => tab.id === tabParam)?.id ?? "profil";
const setActive = useCallback(
(id: SettingsTabId) => {
const params = new URLSearchParams(search.toString());
params.set("tab", id);
router.replace(`/einstellungen?${params.toString()}`, { scroll: false });
},
[router, search],
);
return { active, setActive };
}
export function SettingsTabs({
active,
onChange,
}: {
active: SettingsTabId;
onChange: (id: SettingsTabId) => void;
}) {
const activeMeta = tabs.find((tab) => tab.id === active);
return (
<div className="space-y-3">
<div
role="tablist"
aria-label="Einstellungs-Kategorien"
className="-mx-1 flex gap-2 overflow-x-auto px-1 pb-1"
>
{tabs.map((tab) => {
const isActive = tab.id === active;
return (
<button
key={tab.id}
type="button"
role="tab"
aria-selected={isActive}
onClick={() => onChange(tab.id)}
className={`shrink-0 rounded-full px-4 py-2 text-sm font-semibold transition-colors ${
isActive
? "bg-[#0F766E] text-white shadow-sm"
: "bg-white text-gray-600 ring-1 ring-gray-200 hover:bg-gray-50"
}`}
>
{tab.label}
</button>
);
})}
</div>
{activeMeta?.description ? (
<p className="px-1 text-sm text-gray-500">{activeMeta.description}</p>
) : null}
</div>
);
}