dstpabuaran.com/resources/js/pages/admin/manage/restock/restock-sub-row.tsx
Yoga Pangestu cf0e772159 feat: implement restock management functionality
- Add RestockIndex component for displaying and managing restocks.
- Create RestockCardRow component for rendering individual restock items.
- Implement RestockItemSubRow component for displaying detailed item information.
- Define routes for restock management in web.php.
- Create RestockTest to cover various scenarios for restock creation, updating, and deletion.
- Ensure proper handling of permissions for restock actions.
- Add validation for restock data and ensure correct relationships are maintained.
2026-08-02 22:34:10 +07:00

125 lines
4.7 KiB
TypeScript

import { useState } from 'react';
import { ImagePreviewModal } from '@/components/image-preview-modal';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import type { Restock } from './columns';
function formatCurrency(amount: number): string {
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(amount);
}
function formatNumber(num: number): string {
return new Intl.NumberFormat('id-ID', {
maximumFractionDigits: 4,
}).format(num);
}
function VariantPhotoPreview({ url, title }: { url: string; title: string }) {
const [open, setOpen] = useState(false);
return (
<>
<button
type="button"
onClick={() => setOpen(true)}
className="block h-10 w-10 overflow-hidden rounded-md border transition-opacity hover:opacity-80"
>
<img
src={url}
alt={title}
className="h-full w-full object-cover"
/>
</button>
<ImagePreviewModal
open={open}
onOpenChange={setOpen}
src={url}
title={title}
/>
</>
);
}
export function RestockItemSubRow({ restock }: { restock: Restock }) {
const items = restock.restock_items ?? [];
return (
<div className="space-y-4 overflow-x-auto">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[50px] text-center">
No
</TableHead>
<TableHead className="w-[60px]">Foto</TableHead>
<TableHead>Produk</TableHead>
<TableHead>Varian</TableHead>
<TableHead className="text-right">
Harga Modal
</TableHead>
<TableHead className="text-center">Qty</TableHead>
<TableHead className="text-right">Subtotal</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{items.length === 0 ? (
<TableRow>
<TableCell
colSpan={7}
className="text-center text-muted-foreground"
>
Tidak ada item.
</TableCell>
</TableRow>
) : (
items.map((item, index) => (
<TableRow key={item.id}>
<TableCell className="text-center">
{index + 1}
</TableCell>
<TableCell>
{item.product_variant?.photo_url ? (
<VariantPhotoPreview
url={item.product_variant.photo_url}
title={item.product_variant.name}
/>
) : (
<div className="flex h-10 w-10 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">
N/A
</div>
)}
</TableCell>
<TableCell>
{item.product_variant?.product?.name ?? '-'}
</TableCell>
<TableCell>
{item.product_variant?.name ?? '-'}
</TableCell>
<TableCell className="text-right">
{formatCurrency(item.unit_price)}
</TableCell>
<TableCell className="text-center">
{formatNumber(item.quantity)}
</TableCell>
<TableCell className="text-right font-medium">
{formatCurrency(item.subtotal)}
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
);
}