Files
GSB-Construction/Modules/ApprovalWorkflow/resources/js/Components/ApprovableBreakdown.tsx

84 lines
3.9 KiB
TypeScript

import { Card, CardContent, CardHeader, CardTitle } from '@/Components/ui/card';
import { Button } from '@/Components/ui/button';
import { ExternalLink, FileText, ShoppingCart } from 'lucide-react';
interface Props {
chain: any;
breakdownData?: any;
}
export default function ApprovableBreakdown({ chain, breakdownData }: Props) {
const approvable = chain.approvable;
if (!approvable || !breakdownData) return null;
let title = 'Document Breakdown';
let icon = <FileText className="h-5 w-5 mr-2" />;
let details: { label: string; value: React.ReactNode }[] = [];
let linkUrl = '#';
switch (chain.approvable_type) {
case 'Modules\\MaterialLogistics\\Models\\MaterialRequisition':
title = 'Material Requisition Details';
icon = <ShoppingCart className="h-5 w-5 mr-2" />;
linkUrl = route('requisitions.show', approvable.ulid || approvable.id);
details = [
{ label: 'Document Number', value: breakdownData.document_number || `REQ-${approvable.id}` },
{ label: 'Total Cost', value: breakdownData.total_cost != null ? `${parseFloat(breakdownData.total_cost).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : 'N/A' },
{ label: 'Notes', value: breakdownData.notes || 'None' },
];
break;
case 'Modules\\MaterialLogistics\\Models\\PurchaseOrder':
title = 'Purchase Order Details';
icon = <ShoppingCart className="h-5 w-5 mr-2" />;
linkUrl = route('purchase-orders.show', approvable.ulid || approvable.id);
details = [
{ label: 'PO Number', value: breakdownData.document_number || `PO-${approvable.id}` },
{ label: 'Total Amount', value: breakdownData.total_cost != null ? `${parseFloat(breakdownData.total_cost).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : 'N/A' },
{ label: 'Notes', value: breakdownData.notes || 'None' },
];
break;
default:
title = 'Generic Document';
break;
}
return (
<Card className="mb-6 border-primary bg-primary/5 shadow-sm">
<CardHeader className="flex flex-row justify-between items-center pb-2">
<CardTitle className="text-lg flex items-center text-primary">
{icon} {title}
</CardTitle>
<a href={linkUrl} target="_blank" rel="noopener noreferrer">
<Button variant="default" size="sm" className="hidden sm:flex">
<ExternalLink className="h-4 w-4 mr-2" />
View Source Document
</Button>
</a>
</CardHeader>
<CardContent>
{details.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-2">
{details.map((detail, idx) => (
<div key={idx}>
<p className="text-xs text-muted-foreground">{detail.label}</p>
<p className="font-medium text-sm">{detail.value}</p>
</div>
))}
</div>
) : (
<p className="text-sm text-gray-500">Details not found or unsupported document type.</p>
)}
<div className="mt-4 sm:hidden">
<a href={linkUrl} target="_blank" rel="noopener noreferrer">
<Button variant="default" size="sm" className="w-full">
<ExternalLink className="h-4 w-4 mr-2" />
View Source Document
</Button>
</a>
</div>
</CardContent>
</Card>
);
}