"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}
) : 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}
) : (
<>
{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}
);
}