vue0
n

nikhilakki

n

convert this to vue 3 import React, { useState, useEffect } from 'react' 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 { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Badge } from "@/components/ui/badge" import { Textarea } from "@/components/ui/textarea" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog" import { Check, Truck, Building, DollarSign, FileText, Search, Filter, Undo, Trash2, Printer, Download } from 'lucide-react' // Mock data and functions (unchanged) const mockOrderConfirmation = { orderId: 'ORD-12345', customerName: 'Acme Corp', pickups: [ { address: "123 Pickup St, City1", details: "2 pallets" }, { address: "456 Pickup Ave, City2", details: "1 container" } ], deliveries: [ { address: "789 Delivery Rd, City3", details: "All items" } ], specialInstructions: "Handle with care", totalAmount: 1000, freightDeclaredValue: 5000 } const mockFleetTrucks = [ { id: 'truck1', name: 'Truck 1' }, { id: 'truck2', name: 'Truck 2' }, { id: 'truck3', name: 'Truck 3' }, ] const mockThirdPartyCarriers = [ { id: 'carrier1', name: 'Carrier A' }, { id: 'carrier2', name: 'Carrier B' }, { id: 'carrier3', name: 'Carrier C' }, ] const mockDrivers = [ { id: 'driver1', name: 'John Doe' }, { id: 'driver2', name: 'Jane Smith' }, { id: 'driver3', name: 'Mike Johnson' }, ] interface OrderSegment { id: string pickupAddress: string deliveryAddress: string assignedVehicle: string isThirdParty: boolean driver: string amount: number state: 'Pending' | 'In Progress' | 'Delivered' } interface Order { orderId: string customerName: string segments: OrderSegment[] specialInstructions: string totalAmount: number freightDeclaredValue: number commission: number } export default function SplitOrderHandling() { const [currentStep, setCurrentStep] = useState(1) const [order, setOrder] = useState<Order | null>(null) const [isFinalized, setIsFinalized] = useState(false) const [dispatchHistory, setDispatchHistory] = useState<OrderSegment[][]>([]) const [finalizeHistory, setFinalizeHistory] = useState<boolean[]>([]) const [invoiceGenerated, setInvoiceGenerated] = useState(false) const [reportGenerated, setReportGenerated] = useState(false) useEffect(() => { // Simulate order confirmation upload const initialOrder = { orderId: mockOrderConfirmation.orderId, customerName: mockOrderConfirmation.customerName, segments: [ { id: 'segment1', pickupAddress: mockOrderConfirmation.pickups[0].address, deliveryAddress: mockOrderConfirmation.deliveries[0].address, assignedVehicle: '', isThirdParty: false, driver: '', amount: mockOrderConfirmation.totalAmount * 0.9, // 90% of total amount, leaving 10% for commission state: 'Pending' } ], specialInstructions: mockOrderConfirmation.specialInstructions, totalAmount: mockOrderConfirmation.totalAmount, freightDeclaredValue: mockOrderConfirmation.freightDeclaredValue, commission: mockOrderConfirmation.totalAmount * 0.1 // 10% of total amount } setOrder(initialOrder) setDispatchHistory([initialOrder.segments]) setFinalizeHistory([false]) }, []) const handleNextStep = () => { setCurrentStep(prev => Math.min(prev + 1, 7)) } const handlePrevStep = () => { setCurrentStep(prev => Math.max(prev - 1, 1)) } const handleSplitDispatch = () => { if (order) { const newSegments = [ ...order.segments, { id: `segment${order.segments.length + 1}`, pickupAddress: mockOrderConfirmation.pickups[1].address, deliveryAddress: mockOrderConfirmation.deliveries[0].address, assignedVehicle: '', isThirdParty: false, driver: '', amount: 0, state: 'Pending' } ] setOrder({ ...order, segments: newSegments }) setDispatchHistory([...dispatchHistory, newSegments]) } } const handleUndoDispatch = () => { if (dispatchHistory.length > 1) { const previousSegments = dispatchHistory[dispatchHistory.length - 2] setOrder(prevOrder => ({ ...prevOrder!, segments: previousSegments })) setDispatchHistory(prevHistory => prevHistory.slice(0, -1)) } } const handleDeleteDispatch = (segmentId: string) => { if (order && order.segments.length > 1) { const newSegments = order.segments.filter(segment => segment.id !== segmentId) setOrder({ ...order, segments: newSegments }) setDispatchHistory([...dispatchHistory, newSegments]) } } const handleVehicleAssignment = (segmentId: string, vehicleId: string, isThirdParty: boolean) => { if (order) { setOrder({ ...order, segments: order.segments.map(segment => segment.id === segmentId ? { ...segment, assignedVehicle: vehicleId, isThirdParty, driver: isThirdParty ? '' : segment.driver } : segment ) }) } } const handleDriverAssignment = (segmentId: string, driverId: string) => { if (order) { setOrder({ ...order, segments: order.segments.map(segment => segment.id === segmentId ? { ...segment, driver: driverId } : segment ) }) } } const handleAmountChange = (segmentId: string, amount: number) => { if (order) { const otherSegmentsTotal = order.segments .filter(s => s.id !== segmentId) .reduce((sum, s) => sum + (isNaN(s.amount) ? 0 : s.amount), 0) const maxAllowedAmount = order.totalAmount - otherSegmentsTotal - order.commission const newAmount = isNaN(amount) ? 0 : Math.min(amount, maxAllowedAmount) setOrder({ ...order, segments: order.segments.map(segment => segment.id === segmentId ? { ...segment, amount: newAmount } : segment ) }) } } const handleCommissionChange = (commission: number) => { if (order) { const segmentsTotal = order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0) const maxAllowedCommission = order.totalAmount - segmentsTotal const newCommission = isNaN(commission) ? 0 : Math.min(commission, maxAllowedCommission) setOrder({ ...order, commission: newCommission }) } } const handleMoveRemainingToCommission = () => { if (order) { const segmentsTotal = order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0) const remainingAmount = order.totalAmount - segmentsTotal - order.commission setOrder({ ...order, commission: order.commission + remainingAmount }) } } const handleStateChange = (segmentId: string, newState: 'Pending' | 'In Progress' | 'Delivered') => { if (order) { setOrder({ ...order, segments: order.segments.map(segment => segment.id === segmentId ? { ...segment, state: newState } : segment ) }) } } const handleFinalize = () => { setIsFinalized(true) setFinalizeHistory([...finalizeHistory, true]) } const handleUndoFinalize = () => { if (finalizeHistory.length > 1) { setIsFinalized(finalizeHistory[finalizeHistory.length - 2]) setFinalizeHistory(prevHistory => prevHistory.slice(0, -1)) } } const handleGenerateInvoice = () => { setInvoiceGenerated(true) } const handleGenerateReport = () => { setReportGenerated(true) } const renderStep = () => { switch (currentStep) { case 1: return ( <Card> <CardHeader> <CardTitle>1. Order Confirmation</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="grid grid-cols-2 gap-4 mb-4"> <div> <Label>Order ID</Label> <Input value={order.orderId} readOnly /> </div> <div> <Label>Customer Name</Label> <Input value={order.customerName} readOnly /> </div> <div> <Label>Total Amount</Label> <Input value={`$${order.totalAmount.toFixed(2)}`} readOnly /> </div> <div> <Label>Freight Declared Value</Label> <Input value={`$${order.freightDeclaredValue.toFixed(2)}`} readOnly /> </div> </div> <div className="mb-4"> <Label>Special Instructions</Label> <Textarea value={order.specialInstructions} readOnly /> </div> <div> <Label>Segments</Label> <Table> <TableHeader> <TableRow> <TableHead>Pickup</TableHead> <TableHead>Delivery</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{segment.pickupAddress}</TableCell> <TableCell>{segment.deliveryAddress}</TableCell> </TableRow> ))} </TableBody> </Table> </div> </> )} </CardContent> </Card> ) case 2: return ( <Card> <CardHeader> <CardTitle>2. Dispatch Creation</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="flex justify-end mb-4 space-x-2"> <Button variant="outline" size="sm" onClick={handleSplitDispatch}> Split Dispatch </Button> <Button variant="outline" size="sm" onClick={handleUndoDispatch} disabled={dispatchHistory.length <= 1}> <Undo className="w-4 h-4 mr-2" /> Undo </Button> </div> <Table> <TableHeader> <TableRow> <TableHead>Pickup</TableHead> <TableHead>Delivery</TableHead> <TableHead>Actions</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{segment.pickupAddress}</TableCell> <TableCell>{segment.deliveryAddress}</TableCell> <TableCell> <Button variant="ghost" size="sm" onClick={() => handleDeleteDispatch(segment.id)} disabled={order.segments.length <= 1} > <Trash2 className="w-4 h-4" /> </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </> )} </CardContent> </Card> ) case 3: return ( <Card> <CardHeader> <CardTitle>3. Dispatch List</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="mb-4"> <Label>Total Amount: ${order.totalAmount.toFixed(2)}</Label> </div> <Table> <TableHeader> <TableRow> <TableHead>Pickup</TableHead> <TableHead>Delivery</TableHead> <TableHead>Vehicle</TableHead> <TableHead>Driver</TableHead> <TableHead>Amount</TableHead> <TableHead>State</TableHead> <TableHead>Actions</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{segment.pickupAddress}</TableCell> <TableCell>{segment.deliveryAddress}</TableCell> <TableCell>{segment.assignedVehicle || 'Not assigned'}</TableCell> <TableCell>{segment.driver || 'Not assigned'}</TableCell> <TableCell> <Input type="number" value={isNaN(segment.amount) ? '' : segment.amount} onChange={(e) => handleAmountChange(segment.id, parseFloat(e.target.value))} className="w-24" /> </TableCell> <TableCell> <Badge className={ segment.state === 'Pending' ? 'bg-yellow-500' : segment.state === 'In Progress' ? 'bg-blue-500' : 'bg-green-500' }> {segment.state} </Badge> </TableCell> <TableCell> <Select onValueChange={(value) => handleStateChange(segment.id, value as any)} value={segment.state}> <SelectTrigger className="w-[180px]"> <SelectValue placeholder="Change state" /> </SelectTrigger> <SelectContent> <SelectItem value="Pending">Pending</SelectItem> <SelectItem value="In Progress">In Progress</SelectItem> <SelectItem value="Delivered">Delivered</SelectItem> </SelectContent> </Select> </TableCell> </TableRow> ))} </TableBody> </Table> <div className="mt-4 grid grid-cols-2 gap-4"> <div> <Label>Total Split Amount: ${order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0).toFixed(2)}</Label> </div> <div> <Label>$ Commission</Label> <Input type="number" value={isNaN(order.commission) ? '' : order.commission} onChange={(e) => handleCommissionChange(parseFloat(e.target.value))} className="w-24" /> </div> </div> <div className="mt-2 flex justify-between items-center"> <Label>Remaining Amount: ${(order.totalAmount - order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0) - (isNaN(order.commission) ? 0 : order.commission)).toFixed(2)}</Label> <Button onClick={handleMoveRemainingToCommission}> Move Remaining to Commission </Button> </div> </> )} </CardContent> </Card> ) case 4: return ( <Card> <CardHeader> <CardTitle>4. Split Dispatch Assignment</CardTitle> </CardHeader> <CardContent> {order && order.segments.map((segment, index) => ( <Card key={index} className="mb-4"> <CardHeader> <CardTitle>Segment {index + 1}</CardTitle> </CardHeader> <CardContent> <div className="grid grid-cols-2 gap-4 mb-4"> <div> <Label>Pickup Address</Label> <Input value={segment.pickupAddress} readOnly /> </div> <div> <Label>Delivery Address</Label> <Input value={segment.deliveryAddress} readOnly /> </div> </div> <Tabs defaultValue="fleet" className="w-full mb-4"> <TabsList className="grid w-full grid-cols-2"> <TabsTrigger value="fleet">Fleet Truck</TabsTrigger> <TabsTrigger value="thirdparty">Third-Party Carrier</TabsTrigger> </TabsList> <TabsContent value="fleet"> <Select onValueChange={(value) => handleVehicleAssignment(segment.id, value, false)} value={!segment.isThirdParty ? segment.assignedVehicle : undefined} > <SelectTrigger> <SelectValue placeholder="Select a truck" /> </SelectTrigger> <SelectContent> {mockFleetTrucks.map((truck) => ( <SelectItem key={truck.id} value={truck.id}>{truck.name}</SelectItem> ))} </SelectContent> </Select> <div className="mt-4"> <Label>Driver</Label> <Select onValueChange={(value) => handleDriverAssignment(segment.id, value)} value={segment.driver} > <SelectTrigger> <SelectValue placeholder="Select a driver" /> </SelectTrigger> <SelectContent> {mockDrivers.map((driver) => ( <SelectItem key={driver.id} value={driver.id}>{driver.name}</SelectItem> ))} </SelectContent> </Select> </div> </TabsContent> <TabsContent value="thirdparty"> <Select onValueChange={(value) => handleVehicleAssignment(segment.id, value, true)} value={segment.isThirdParty ? segment.assignedVehicle : undefined} > <SelectTrigger> <SelectValue placeholder="Select a carrier" /> </SelectTrigger> <SelectContent> {mockThirdPartyCarriers.map((carrier) => ( <SelectItem key={carrier.id} value={carrier.id}>{carrier.name}</SelectItem> ))} </SelectContent> </Select> </TabsContent> </Tabs> <div className="mb-4"> <Label>Amount</Label> <Input type="number" value={isNaN(segment.amount) ? '' : segment.amount} readOnly /> </div> </CardContent> </Card> ))} </CardContent> </Card> ) case 5: return ( <Card> <CardHeader> <CardTitle>5. Final Review and Completion</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="grid grid-cols-2 gap-4 mb-4"> <div> <strong>Order ID:</strong> {order.orderId} </div> <div> <strong>Customer:</strong> {order.customerName} </div> <div> <strong>Total Amount:</strong> ${order.totalAmount.toFixed(2)} </div> <div> <strong>Total Split Amount:</strong> ${order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0).toFixed(2)} </div> <div> <strong>Commission:</strong> ${isNaN(order.commission) ? '0.00' : order.commission.toFixed(2)} </div> <div> <strong>Status:</strong> {isFinalized ? <Badge className="bg-green-500">Finalized</Badge> : <Badge className="bg-yellow-500">Pending</Badge> } </div> </div> <Accordion type="single" collapsible className="w-full mb-4"> <AccordionItem value="segments"> <AccordionTrigger>View Segments</AccordionTrigger> <AccordionContent> <Table> <TableHeader> <TableRow> <TableHead>Pickup</TableHead> <TableHead>Delivery</TableHead> <TableHead>Vehicle</TableHead> <TableHead>Driver</TableHead> <TableHead>Amount</TableHead> <TableHead>State</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{segment.pickupAddress}</TableCell> <TableCell>{segment.deliveryAddress}</TableCell> <TableCell>{segment.assignedVehicle}</TableCell> <TableCell>{segment.isThirdParty ? 'N/A' : segment.driver}</TableCell> <TableCell>${isNaN(segment.amount) ? '0.00' : segment.amount.toFixed(2)}</TableCell> <TableCell>{segment.state}</TableCell> </TableRow> ))} </TableBody> </Table> </AccordionContent> </AccordionItem> </Accordion> <div className="flex gap-4"> <AlertDialog> <AlertDialogTrigger asChild> <Button disabled={isFinalized}> <Check className="mr-2 h-4 w-4" /> Finalize Order </Button> </AlertDialogTrigger> <AlertDialogContent> <AlertDialogHeader> <AlertDialogTitle>Are you sure you want to finalize this order?</AlertDialogTitle> <AlertDialogDescription> This action cannot be undone. Please make sure all details are correct before finalizing. </AlertDialogDescription> </AlertDialogHeader> <AlertDialogFooter> <AlertDialogCancel>Cancel</AlertDialogCancel> <AlertDialogAction onClick={handleFinalize}>Finalize</AlertDialogAction> </AlertDialogFooter> </AlertDialogContent> </AlertDialog> <Button onClick={handleUndoFinalize} disabled={!isFinalized || finalizeHistory.length <= 1}> <Undo className="mr-2 h-4 w-4" /> Undo Finalize </Button> <Button onClick={() => setCurrentStep(6)} disabled={!isFinalized}> <DollarSign className="mr-2 h-4 w-4" /> Generate Invoice </Button> <Button onClick={() => setCurrentStep(7)} disabled={!isFinalized}> <FileText className="mr-2 h-4 w-4" /> Generate Report </Button> </div> </> )} </CardContent> </Card> ) case 6: return ( <Card> <CardHeader> <CardTitle>6. Generate Invoice</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="grid grid-cols-2 gap-4 mb-4"> <div> <Label>Invoice Number</Label> <Input value={`INV-${order.orderId}`} readOnly /> </div> <div> <Label>Invoice Date</Label> <Input value={new Date().toISOString().split('T')[0]} readOnly /> </div> <div> <Label>Customer Name</Label> <Input value={order.customerName} readOnly /> </div> <div> <Label>Total Amount</Label> <Input value={`$${order.totalAmount.toFixed(2)}`} readOnly /> </div> </div> <Table> <TableHeader> <TableRow> <TableHead>Description</TableHead> <TableHead>Quantity</TableHead> <TableHead>Unit Price</TableHead> <TableHead>Total</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{`Delivery from ${segment.pickupAddress} to ${segment.deliveryAddress}`}</TableCell> <TableCell>1</TableCell> <TableCell>${isNaN(segment.amount) ? '0.00' : segment.amount.toFixed(2)}</TableCell> <TableCell>${isNaN(segment.amount) ? '0.00' : segment.amount.toFixed(2)}</TableCell> </TableRow> ))} <TableRow> <TableCell>Commission</TableCell> <TableCell>1</TableCell> <TableCell>${isNaN(order.commission) ? '0.00' : order.commission.toFixed(2)}</TableCell> <TableCell>${isNaN(order.commission) ? '0.00' : order.commission.toFixed(2)}</TableCell> </TableRow> </TableBody> </Table> <div className="flex justify-end mt-4"> <Button onClick={handleGenerateInvoice} disabled={invoiceGenerated}> <Printer className="mr-2 h-4 w-4" /> {invoiceGenerated ? 'Invoice Generated' : 'Generate Invoice'} </Button> </div> </> )} </CardContent> </Card> ) case 7: return ( <Card> <CardHeader> <CardTitle>7. Generate Report</CardTitle> </CardHeader> <CardContent> {order && ( <> <div className="grid grid-cols-2 gap-4 mb-4"> <div> <Label>Report Number</Label> <Input value={`REP-${order.orderId}`} readOnly /> </div> <div> <Label>Report Date</Label> <Input value={new Date().toISOString().split('T')[0]} readOnly /> </div> <div> <Label>Customer Name</Label> <Input value={order.customerName} readOnly /> </div> <div> <Label>Total Segments</Label> <Input value={order.segments.length.toString()} readOnly /> </div> </div> <Table> <TableHeader> <TableRow> <TableHead>Segment</TableHead> <TableHead>Pickup</TableHead> <TableHead>Delivery</TableHead> <TableHead>Vehicle</TableHead> <TableHead>Driver</TableHead> <TableHead>Amount</TableHead> <TableHead>State</TableHead> </TableRow> </TableHeader> <TableBody> {order.segments.map((segment, index) => ( <TableRow key={index}> <TableCell>{index + 1}</TableCell> <TableCell>{segment.pickupAddress}</TableCell> <TableCell>{segment.deliveryAddress}</TableCell> <TableCell>{segment.assignedVehicle}</TableCell> <TableCell>{segment.isThirdParty ? 'N/A' : segment.driver}</TableCell> <TableCell>${isNaN(segment.amount) ? '0.00' : segment.amount.toFixed(2)}</TableCell> <TableCell>{segment.state}</TableCell> </TableRow> ))} </TableBody> </Table> <div className="mt-4"> <Label>Commission: ${isNaN(order.commission) ? '0.00' : order.commission.toFixed(2)}</Label> </div> <div className="flex justify-end mt-4"> <Button onClick={handleGenerateReport} disabled={reportGenerated}> <Download className="mr-2 h-4 w-4" /> {reportGenerated ? 'Report Generated' : 'Generate Report'} </Button> </div> </> )} </CardContent> </Card> ) default: return null } } return ( <div className="container mx-auto p-4"> <h1 className="text-2xl font-bold mb-4">Split Order Handling</h1> {renderStep()} <div className="flex justify-between mt-4"> <Button onClick={handlePrevStep} disabled={currentStep === 1}>Previous</Button> <Button onClick={handleNextStep} disabled={currentStep === 7 || (currentStep === 3 && order && (order.totalAmount - order.segments.reduce((sum, segment) => sum + (isNaN(segment.amount) ? 0 : segment.amount), 0) - (isNaN(order.commission) ? 0 : order.commission)) !== 0)}>Next</Button> </div> </div> ) }