"use client"; import { AlertTriangle, ChartColumn, ChevronRight, ClipboardCheck, Clock, FolderTree, Plus, Search, Tags, } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useMemo, useState, useTransition } from "react"; import { toast } from "sonner"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { tr } from "@/i18n/tr"; import { cn } from "@/lib/utils"; import { formatDate } from "@/shared/format"; import { foldTr } from "@/shared/search"; import { formatStock, stepLabel, type ExpiringLot } from "@/shared/stock"; import { quickConsumeAction } from "../actions"; import type { ProductTypeView, StockOption, StockView as Data } from "../service"; import { ProductTypeFormDialog } from "./stock-dialogs"; const t = tr.stock; export const ymdLabel = (ymd: string) => formatDate(`${ymd}T12:00:00+03:00`); /** Mevcut/hedef çubuğu; eşik çizgiyle işaretli. */ export function StockBar({ item }: { item: ProductTypeView }) { const pct = Math.min(100, item.level.pct ?? 0); return (
{item.thresholdPct > 0 && item.thresholdPct < 100 ? ( ) : null}
); } export function LevelBadge({ item }: { item: ProductTypeView }) { if (item.current <= 0 && item.targetQuantity > 0) return {t.list.outBadge}; if (item.level.low) return ( {t.list.lowBadge} ); return null; } export function ExpiryBadge({ lot }: { lot: Pick }) { return ( {t.expiring.on(ymdLabel(lot.expiryDate))} ); } /** "1 azalt" düğmesi. */ export function QuickConsumeButton({ item }: { item: ProductTypeView }) { const [pending, start] = useTransition(); return ( ); } /** Önerilen miktarın gerekçesi: fire indirimi, tüketim hızı yuvarlaması, kaç gün yeter. */ export function suggestionReasons(item: ProductTypeView): string[] { const s = item.suggestion; if (s.quantity === 0) return []; const out: string[] = []; if (s.waste) out.push(t.suggestions.wasteReduced(s.waste.purchases, s.waste.pct)); if (s.roundedByUsage) out.push(t.suggestions.roundedByUsage(formatStock(s.roundTo, item.unit))); if (s.coverDays !== null) out.push(t.suggestions.covers(s.coverDays)); return out; } function Stat({ label, value, tone }: { label: string; value: number; tone?: string }) { return (

{label}

0 && tone)}>{value}

); } /** /stok: özet, öneriler, SKT uyarıları ve kategoriye göre ürün listesi. */ export function StockView({ data, options }: { data: Data; options: StockOption[] }) { const router = useRouter(); const [creating, setCreating] = useState(false); const [query, setQuery] = useState(""); const [onlyLow, setOnlyLow] = useState(false); const expired = data.expiring.filter((e) => e.lot.status === "expired").length; const groups = useMemo(() => { const q = foldTr(query.trim()); const match = (i: ProductTypeView) => (!onlyLow || i.level.low) && (!q || foldTr(i.name).includes(q) || foldTr(i.location).includes(q)); return data.categories .map((c) => ({ category: c, items: data.items.filter((i) => i.categoryId === c.id && match(i)), })) .filter((g) => g.items.length > 0); }, [data, query, onlyLow]); return (
{data.canWrite ? ( ) : null}
{t.suggestions.title} {t.suggestions.description} {data.suggestions.length ? ( {t.suggestions.toShopping} ) : null} {data.suggestions.length === 0 ? (

{t.suggestions.empty}

) : (
    {data.suggestions.map((i) => { const reasons = suggestionReasons(i); return (
  • {i.name} {t.list.of( formatStock(Math.max(0, i.current), i.unit), formatStock(i.targetQuantity, i.unit), )} {t.suggestions.suggested(formatStock(i.suggestedQuantity, i.unit))}
    {reasons.length ? (

    {reasons.join(" ")}

    ) : null}
  • ); })}
)}
{data.countDue.length ? ( {t.countDue.title} {t.countDue.description}
    {data.countDue.map((g) => (
  • {g.path} {t.countDue.products(g.products)} ·{" "} {t.countDue.overdue(g.overdueDays)}
    {data.canWrite ? ( ) : null}
  • ))}
) : null} {data.expiring.length ? ( {t.expiring.title} {t.expiring.description}
    {data.expiring.map(({ item, lot }) => (
  • {item.name} {formatStock(lot.remaining, item.unit)}
  • ))}
) : null}
{data.items.length === 0 ? (

{t.list.empty}

) : ( <>
setQuery(e.target.value)} placeholder={t.list.search} aria-label={t.list.search} className="pl-8" />
{groups.length === 0 ? (

{t.list.noMatch}

) : null} {groups.map(({ category, items }) => (

{category.path}

    {items.map((item) => ( ))}
))} )} {creating ? ( setCreating(false)} onCreated={(id) => router.push(`/stok/${id}`)} /> ) : null}
); } function StockRow({ item, canWrite }: { item: ProductTypeView; canWrite: boolean }) { const lot = item.expiring[0]; return (
  • {item.name} {lot ? : null}

    {formatStock(Math.max(0, item.current), item.unit)} {" "} / {formatStock(item.targetQuantity, item.unit)}
    {item.location ? (

    {item.location}

    ) : null}
    {canWrite ? : null}
  • ); }