feat(households): hane seçici, ayarlar, admin hane yönetimi ve hane-yok sayfası

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 02:35:01 +03:00
parent de91f2505a
commit 3644e081b1
21 changed files with 1427 additions and 29 deletions
+29 -7
View File
@@ -1,7 +1,8 @@
"use client";
import { House } from "lucide-react";
import { useState } from "react";
import { useTransition } from "react";
import { toast } from "sonner";
import {
Select,
SelectContent,
@@ -9,17 +10,38 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { switchHouseholdAction } from "@/features/households/actions";
import type { HouseholdSummary } from "@/features/households/types";
import { tr } from "@/i18n/tr";
/** Üst bar aktif hane seçici. FAZ 5: seçim sunucuda (cookie) saklanacak. */
export function HouseholdSwitcher({ households }: { households: HouseholdSummary[] }) {
const [value, setValue] = useState(households[0]?.id);
const current = households.find((h) => h.id === value);
/** Üst bar aktif hane seçici. Seçim sunucuda doğrulanır ve cookie'ye yazılır. */
export function HouseholdSwitcher({
households,
activeId,
}: {
households: HouseholdSummary[];
activeId: string | undefined;
}) {
const [pending, startTransition] = useTransition();
const current = households.find((h) => h.id === activeId);
if (households.length === 0) return null;
function onChange(id: string) {
if (id === activeId) return;
startTransition(async () => {
const result = await switchHouseholdAction(id);
if (result.ok) toast.success(tr.household.switched(result.data.name));
else toast.error(result.error);
});
}
return (
<Select value={value} onValueChange={setValue}>
<SelectTrigger aria-label={tr.household.label} className="w-[min(46vw,13rem)]">
<Select value={activeId} onValueChange={onChange} disabled={pending || households.length < 2}>
<SelectTrigger
aria-label={tr.household.label}
className="w-[min(46vw,13rem)]"
aria-busy={pending}
>
<House className="text-muted-foreground" />
{/* Etiket children ile verilir: Radix aksi halde hydration'a kadar boş gösterir. */}
<SelectValue placeholder={tr.household.select}>{current?.name}</SelectValue>