dress/resources/js/pages/admin/manage/order/partials/columns.tsx

195 lines
7.3 KiB
TypeScript

import { DataTableColumnHeader } from '@/components/data-table-column-header';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { usePermission } from '@/hooks/use-permission';
import * as orderRoutes from '@/routes/order';
import type { Order } from '@/types/order';
import { Link } from '@inertiajs/react';
import type { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { id } from 'date-fns/locale';
import { Pencil, Printer, Trash2 } from 'lucide-react';
interface ColumnProps {
onDelete: (order: Order) => void;
onPrint: (order: Order) => void;
}
export const getColumns = ({
onDelete,
onPrint,
}: ColumnProps): ColumnDef<Order>[] => [
{
accessorKey: 'order_number',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="No. Order" />
),
cell: ({ row }) => (
<div className="flex flex-col">
<span className="font-medium">{row.original.order_number}</span>
<span className="text-xs text-muted-foreground">
{format(
new Date(row.original.created_at),
'dd MMM yyyy HH:mm',
{ locale: id },
)}
</span>
</div>
),
meta: { title: 'No. Order' },
},
{
accessorKey: 'customer_name',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Pelanggan" />
),
cell: ({ row }) => (
<div className="flex flex-col">
<span>{row.original.customer_name}</span>
<Badge
variant="outline"
className="h-4 w-fit px-1 py-0 text-[10px]"
>
{row.original.order_channel}
</Badge>
</div>
),
meta: { title: 'Pelanggan' },
},
{
accessorKey: 'items',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Item" />
),
cell: ({ row }) => {
const items = row.original.items;
if (!items || !Array.isArray(items) || items.length === 0) {
return (
<span className="text-xs text-muted-foreground italic">
-
</span>
);
}
return (
<div className="flex flex-col gap-1">
{items.slice(0, 2).map((item, i) => (
<div key={i} className="text-xs">
<span className="text-muted-foreground">
{item.product?.name}:
</span>{' '}
<span className="font-medium text-primary">
{item.qty} x {item.price_formatted}
</span>
</div>
))}
{items.length > 2 && (
<span className="text-[10px] text-muted-foreground italic">
+{items.length - 2} item lainnya...
</span>
)}
</div>
);
},
meta: { title: 'Item' },
},
{
accessorKey: 'total',
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Total" />
),
cell: ({ row }) => (
<div className="flex flex-col items-end gap-1">
<span className="font-bold text-primary">
{row.original.total_formatted}
</span>
<Badge
className="h-4 py-0 text-[10px]"
variant={
row.original.order_status === 'delivered'
? 'default'
: row.original.order_status === 'pending'
? 'secondary'
: row.original.order_status === 'cancelled'
? 'destructive'
: 'outline'
}
>
{row.original.order_status}
</Badge>
</div>
),
meta: { title: 'Total' },
},
{
id: 'actions',
header: 'Aksi',
cell: ({ row }) => {
const order = row.original;
const { hasPermission } = usePermission();
return (
<div className="flex items-center gap-2">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="text-blue-600 hover:bg-blue-50 hover:text-blue-700 dark:hover:bg-blue-950/20"
onClick={() => onPrint(order)}
>
<Printer className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Cetak Struk</p>
</TooltipContent>
</Tooltip>
{hasPermission('Edit:Order') && (
<Tooltip>
<TooltipTrigger asChild>
<Link href={orderRoutes.edit(order.id).url}>
<Button
variant="ghost"
size="icon"
className="text-yellow-600 hover:bg-yellow-50 hover:text-yellow-700 dark:hover:bg-yellow-950/20"
>
<Pencil className="size-4" />
</Button>
</Link>
</TooltipTrigger>
<TooltipContent>
<p>Ubah</p>
</TooltipContent>
</Tooltip>
)}
{hasPermission('Delete:Order') && (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="icon"
className="text-red-600 hover:bg-red-50 hover:text-red-700 dark:hover:bg-red-950/20"
onClick={() => onDelete(order)}
>
<Trash2 className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Hapus</p>
</TooltipContent>
</Tooltip>
)}
</div>
);
},
meta: { title: 'Aksi' },
},
];