diff --git a/src/components/JobCard.tsx b/src/components/JobCard.tsx index 2fc45b4..06d0bf0 100644 --- a/src/components/JobCard.tsx +++ b/src/components/JobCard.tsx @@ -1,4 +1,3 @@ - import React from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; @@ -160,6 +159,17 @@ const JobCard: React.FC = ({ job, onEdit, onDelete }) => { Expenditure
{formatISK(totalExpenditure)}
+ {job.projectedCost > 0 && ( +
+ vs Projected: {formatISK(job.projectedCost)} + + {((totalExpenditure / job.projectedCost) * 100).toFixed(1)}% + +
+ )}
@@ -167,6 +177,17 @@ const JobCard: React.FC = ({ job, onEdit, onDelete }) => { Income
{formatISK(totalIncome)}
+ {job.projectedRevenue > 0 && ( +
+ vs Projected: {formatISK(job.projectedRevenue)} + = job.projectedRevenue ? 'default' : 'destructive'} + className="ml-1 text-xs" + > + {((totalIncome / job.projectedRevenue) * 100).toFixed(1)}% + +
+ )}
Profit
@@ -176,6 +197,11 @@ const JobCard: React.FC = ({ job, onEdit, onDelete }) => { = 0 ? 'default' : 'destructive'} className="text-xs"> {margin.toFixed(1)}% + {job.projectedRevenue > 0 && job.projectedCost > 0 && ( +
+ vs Projected: {formatISK(job.projectedRevenue - job.projectedCost)} +
+ )}
diff --git a/src/components/JobForm.tsx b/src/components/JobForm.tsx index c62c1c9..6c0ecfd 100644 --- a/src/components/JobForm.tsx +++ b/src/components/JobForm.tsx @@ -1,14 +1,14 @@ - -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; -import { IndBillitemRecordNoId, IndJobStatusOptions, IndJobRecordNoId, IndFacilityRecord, IndBillitemRecord } from '@/lib/pbtypes'; +import { IndJobStatusOptions, IndJobRecordNoId, IndBillitemRecord } from '@/lib/pbtypes'; import MaterialsImportExport from './MaterialsImportExport'; import { IndJob } from '@/lib/types'; +import { parseISKAmount } from '@/utils/priceUtils'; // import { getFacilities } from '@/services/facilityService'; interface JobFormProps { @@ -32,7 +32,9 @@ const JobForm: React.FC = ({ job, onSubmit, onCancel }) => { billOfMaterials: job?.billOfMaterials || [], consumedMaterials: job?.consumedMaterials || [], expenditures: job?.expenditures || [], - income: job?.income || [] + income: job?.income || [], + projectedCost: job?.projectedCost || 0, + projectedRevenue: job?.projectedRevenue || 0 }); // useEffect(() => { @@ -62,7 +64,9 @@ const JobForm: React.FC = ({ job, onSubmit, onCancel }) => { billOfMaterials: formData.billOfMaterials.map(item => item.id), consumedMaterials: formData.consumedMaterials.map(item => item.id), expenditures: formData.expenditures.map(item => item.id), - income: formData.income.map(item => item.id) + income: formData.income.map(item => item.id), + projectedCost: formData.projectedCost, + projectedRevenue: formData.projectedRevenue }); }; @@ -191,6 +195,35 @@ const JobForm: React.FC = ({ job, onSubmit, onCancel }) => { +
+
+ + setFormData({ + ...formData, + projectedCost: parseISKAmount(e.target.value) + })} + className="bg-gray-800 border-gray-600 text-white" + /> +
+
+ + setFormData({ + ...formData, + projectedRevenue: parseISKAmount(e.target.value) + })} + className="bg-gray-800 border-gray-600 text-white" + /> +
+
+