Files
butcem/src/features/shopping/components/list-dialog.tsx
T
suphicakir fa70168622 feat(ui): alışveriş listeleri, akıllı öneri paneli ve alışveriş modu
- /alisveris, /alisveris/:id ve /alisveris/:id/mod sayfaları; odak ve 30 sn yenileme
- stok önerileri paneli, kalem ekle/düzenle/taşı, mağazaya gruplu kontrol listesi
- dashboard Alışveriş kartı, kenar menü, ürün tipi formunda hacimli işareti

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 23:28:54 +03:00

87 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "sonner";
import { ResponsiveDialog } from "@/components/responsive-dialog";
import { Button } from "@/components/ui/button";
import { Field, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { tr } from "@/i18n/tr";
import { saveShoppingListAction } from "../actions";
const t = tr.shopping;
/** Yeni liste / listeyi düzenle. Yeni liste açılınca detayına gider. */
export function ShoppingListDialog({
list,
onClose,
}: {
list: { id: string; name: string; note: string } | null;
onClose: () => void;
}) {
const router = useRouter();
const [v, setV] = useState({ name: list?.name ?? "", note: list?.note ?? "" });
const [errors, setErrors] = useState<Record<string, string | undefined>>({});
const [busy, setBusy] = useState(false);
async function submit(e: React.FormEvent) {
e.preventDefault();
setBusy(true);
const r = await saveShoppingListAction(list?.id ?? null, v);
setBusy(false);
if (!r.ok) {
setErrors({ ...r.fieldErrors, root: r.fieldErrors ? undefined : r.error });
return;
}
toast.success(t.toast.saved);
onClose();
if (!list && r.data && typeof r.data === "object" && "id" in r.data)
router.push(`/alisveris/${r.data.id}`);
}
return (
<ResponsiveDialog
open
onOpenChange={(o) => !o && onClose()}
title={list ? t.editTitle : t.createTitle}
footer={
<>
<Button variant="outline" type="button" onClick={onClose}>
{tr.common.cancel}
</Button>
<Button type="submit" form="shopping-list-form" disabled={busy}>
{tr.common.save}
</Button>
</>
}
>
<form id="shopping-list-form" onSubmit={submit} noValidate>
<FieldGroup>
<Field data-invalid={Boolean(errors.name)}>
<FieldLabel htmlFor="sl-name">{t.fields.name}</FieldLabel>
<Input
id="sl-name"
value={v.name}
placeholder={t.fields.namePlaceholder}
onChange={(e) => setV((s) => ({ ...s, name: e.target.value }))}
aria-invalid={Boolean(errors.name)}
autoFocus
/>
{errors.name ? <FieldError>{errors.name}</FieldError> : null}
</Field>
<Field>
<FieldLabel htmlFor="sl-note">{t.fields.note}</FieldLabel>
<Input
id="sl-note"
value={v.note}
onChange={(e) => setV((s) => ({ ...s, note: e.target.value }))}
/>
</Field>
{errors.root ? <FieldError>{errors.root}</FieldError> : null}
</FieldGroup>
</form>
</ResponsiveDialog>
);
}