From d304733eca93f681f9cd71ebe225a23792e1111f Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Fri, 23 Jan 2026 07:46:36 +0000 Subject: [PATCH] Generated by Spark: Update remaining views (Payroll, Compliance, Expenses) to use PageHeader, Grid, Stack, and MetricCard components --- src/components/views/ComplianceView.tsx | 221 ++++++++-------- src/components/views/ExpensesView.tsx | 290 +++++++++++--------- src/components/views/PayrollView.tsx | 338 +++++++++++------------- 3 files changed, 436 insertions(+), 413 deletions(-) diff --git a/src/components/views/ComplianceView.tsx b/src/components/views/ComplianceView.tsx index 443c1c0..b334267 100644 --- a/src/components/views/ComplianceView.tsx +++ b/src/components/views/ComplianceView.tsx @@ -3,16 +3,21 @@ import { UploadSimple, Warning, XCircle, - CheckCircle + CheckCircle, + FileText } from '@phosphor-icons/react' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import { Card, CardContent } from '@/components/ui/card' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' 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 { PageHeader } from '@/components/ui/page-header' +import { Grid } from '@/components/ui/grid' +import { Stack } from '@/components/ui/stack' +import { MetricCard } from '@/components/ui/metric-card' import { toast } from 'sonner' import { ComplianceDetailDialog } from '@/components/ComplianceDetailDialog' import { AdvancedSearch, type FilterField } from '@/components/AdvancedSearch' @@ -44,6 +49,7 @@ export function ComplianceView({ complianceDocs, onUploadDocument }: ComplianceV const expiringDocs = filteredDocs.filter(d => d.status === 'expiring') const expiredDocs = filteredDocs.filter(d => d.status === 'expired') + const validDocs = filteredDocs.filter(d => d.status === 'valid') const [uploadFormData, setUploadFormData] = useState({ workerId: '', @@ -94,77 +100,77 @@ export function ComplianceView({ complianceDocs, onUploadDocument }: ComplianceV } return ( -
-
-
-

Compliance Monitoring

-

Track worker documentation and certifications

-
- - - - - - - Upload Compliance Document - - Add a new document for a worker - - -
-
- - setUploadFormData({ ...uploadFormData, workerName: e.target.value })} - /> -
-
- - -
-
- - setUploadFormData({ ...uploadFormData, expiryDate: e.target.value })} - /> -
-
- -

Click to upload or drag and drop

-

PDF, JPG, PNG up to 10MB

-
-
-
- - -
-
-
-
+ + + + + + + + Upload Compliance Document + + Add a new document for a worker + + + +
+ + setUploadFormData({ ...uploadFormData, workerName: e.target.value })} + /> +
+
+ + +
+
+ + setUploadFormData({ ...uploadFormData, expiryDate: e.target.value })} + /> +
+
+ +

Click to upload or drag and drop

+

PDF, JPG, PNG up to 10MB

+
+
+ + + + +
+ + } + /> -
- - - - - Expiring Soon - - - -
{expiringDocs.length}
-

Documents expiring within 30 days

-
-
- - - - - - Expired - - - -
{expiredDocs.length}
-

Workers blocked from engagement

-
-
-
+ + } + /> + } + /> + } + /> + @@ -256,7 +255,7 @@ export function ComplianceView({ complianceDocs, onUploadDocument }: ComplianceV if (!open) setViewingDocument(null) }} /> -
+ ) } @@ -278,19 +277,19 @@ function ComplianceCard({ document, onViewDetails }: ComplianceCardProps) { onViewDetails?.(document)}>
-
-
+ +
-
+

{document.workerName}

{document.status} -
-
+ +

Document Type

{document.documentType}

@@ -309,14 +308,14 @@ function ComplianceCard({ document, onViewDetails }: ComplianceCardProps) { {document.daysUntilExpiry < 0 ? 'Expired' : `${document.daysUntilExpiry} days`}

-
+
-
-
-
e.stopPropagation()}> + + + e.stopPropagation()}> -
+
diff --git a/src/components/views/ExpensesView.tsx b/src/components/views/ExpensesView.tsx index 37180ea..f8b5181 100644 --- a/src/components/views/ExpensesView.tsx +++ b/src/components/views/ExpensesView.tsx @@ -6,7 +6,8 @@ import { CheckCircle, ClockCounterClockwise, XCircle, - Camera + Camera, + CurrencyDollar } from '@phosphor-icons/react' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' @@ -17,6 +18,10 @@ import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Textarea } from '@/components/ui/textarea' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { PageHeader } from '@/components/ui/page-header' +import { Grid } from '@/components/ui/grid' +import { Stack } from '@/components/ui/stack' +import { MetricCard } from '@/components/ui/metric-card' import { toast } from 'sonner' import { ExpenseDetailDialog } from '@/components/ExpenseDetailDialog' import { AdvancedSearch, type FilterField } from '@/components/AdvancedSearch' @@ -68,6 +73,26 @@ export function ExpensesView({ setFilteredExpenses(results) }, []) + const pendingExpenses = useMemo(() => + expenses.filter(e => e.status === 'pending'), + [expenses] + ) + + const approvedExpenses = useMemo(() => + expenses.filter(e => e.status === 'approved'), + [expenses] + ) + + const totalPendingAmount = useMemo(() => + pendingExpenses.reduce((sum, e) => sum + e.amount, 0), + [pendingExpenses] + ) + + const totalApprovedAmount = useMemo(() => + approvedExpenses.reduce((sum, e) => sum + e.amount, 0), + [approvedExpenses] + ) + const [formData, setFormData] = useState({ workerName: '', clientName: '', @@ -132,113 +157,113 @@ export function ExpensesView({ } return ( -
-
-
-

Expense Management

-

Manage worker expenses and reimbursements

-
- - - - - - - Create New Expense - - Enter expense details for worker reimbursement or client billing - - -
-
- - setFormData({ ...formData, workerName: e.target.value })} - /> -
-
- - setFormData({ ...formData, clientName: e.target.value })} - /> -
-
- - setFormData({ ...formData, date: e.target.value })} - /> -
-
- - -
-
- -