Add missing materials export button

Implemented a button to export only missing materials based on BOM and expenditures, using `useMaterialsCalculations` to determine missing quantities. Updated `MaterialsActions` and `MaterialsImportExport` components.
This commit is contained in:
gpt-engineer-app[bot]
2025-07-09 19:21:01 +00:00
committed by PhatPhuckDave
parent 5af53723cc
commit fb130799a9

View File

@@ -1,9 +1,10 @@
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Download, Upload, Check } from 'lucide-react'; import { Download, Upload, Check, AlertTriangle } from 'lucide-react';
import { IndJob } from '@/lib/types'; import { IndJob } from '@/lib/types';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { useClipboard } from '@/hooks/useClipboard'; import { useClipboard } from '@/hooks/useClipboard';
import { useMaterialsCalculations } from '@/hooks/useMaterialsCalculations';
interface BOMActionsProps { interface BOMActionsProps {
job: IndJob; job: IndJob;
@@ -13,6 +14,7 @@ interface BOMActionsProps {
const BOMActions: React.FC<BOMActionsProps> = ({ job, onImportBOM }) => { const BOMActions: React.FC<BOMActionsProps> = ({ job, onImportBOM }) => {
const { toast } = useToast(); const { toast } = useToast();
const { copying, copyToClipboard } = useClipboard(); const { copying, copyToClipboard } = useClipboard();
const { calculateMissingMaterials } = useMaterialsCalculations(job, job.billOfMaterials || []);
const importBillOfMaterials = async () => { const importBillOfMaterials = async () => {
if (!onImportBOM) { if (!onImportBOM) {
@@ -85,6 +87,27 @@ const BOMActions: React.FC<BOMActionsProps> = ({ job, onImportBOM }) => {
await copyToClipboard(text, 'bom', 'Bill of materials copied to clipboard'); await copyToClipboard(text, 'bom', 'Bill of materials copied to clipboard');
}; };
const exportMissingMaterials = async () => {
const missingMaterials = calculateMissingMaterials();
if (missingMaterials.length === 0) {
toast({
title: "Nothing Missing",
description: "All materials are satisfied for this job",
duration: 2000,
});
return;
}
const text = missingMaterials
.map(item => `${item.name}\t${item.quantity.toLocaleString()}`)
.join('\n');
await copyToClipboard(text, 'missing', 'Missing materials copied to clipboard');
};
const missingMaterials = calculateMissingMaterials();
return ( return (
<div className="flex gap-1"> <div className="flex gap-1">
<Button <Button
@@ -112,6 +135,21 @@ const BOMActions: React.FC<BOMActionsProps> = ({ job, onImportBOM }) => {
<Upload className="w-4 h-4 text-blue-400" /> <Upload className="w-4 h-4 text-blue-400" />
)} )}
</Button> </Button>
<Button
variant="ghost"
size="sm"
className="p-1 h-6 w-6"
onClick={exportMissingMaterials}
disabled={missingMaterials.length === 0}
title="Export missing materials to clipboard"
data-no-navigate
>
{copying === 'missing' ? (
<Check className="w-4 h-4 text-green-400" />
) : (
<AlertTriangle className="w-4 h-4 text-red-400" />
)}
</Button>
</div> </div>
); );
}; };