diff --git a/src/app/admin/maintenance/[id]/page.tsx b/src/app/admin/maintenance/[id]/page.tsx index 0154d5d..c6d5db2 100644 --- a/src/app/admin/maintenance/[id]/page.tsx +++ b/src/app/admin/maintenance/[id]/page.tsx @@ -6,8 +6,10 @@ import { AlertTriangle, Search, Plus, X, Check, Clock, Bike, User, Phone, MapPin, FileText, Image, DollarSign, Wrench, Battery, Key, CheckCircle, XCircle, ChevronLeft, Save, Printer, Send, QrCode, - Wallet, Building, Edit, MessageSquare, Calendar, ArrowLeft + Wallet, Building, Edit, MessageSquare, Calendar, ArrowLeft, Trash2, + Package, Settings } from 'lucide-react'; +import Link from 'next/link'; type TransactionType = 'deposit' | 'rent_income' | 'investor_funding' | 'investor_withdraw' | 'salary' | 'rent_expense' | 'utility' | 'maintenance' | 'bike_purchase' | 'bike_sale' | 'other_income' | 'other_expense'; @@ -16,6 +18,16 @@ type DamageSeverity = 'critical' | 'major' | 'minor' | 'cosmetic'; type MaintenanceStatus = 'reported' | 'in_progress' | 'parts_ordered' | 'completed' | 'cancelled'; type PaymentStatus = 'pending' | 'approved' | 'paid' | 'rejected'; +interface PartUsed { + id: string; + partId: string; + partName: string; + quantity: number; + unitPrice: number; + totalPrice: number; + addedAt: string; +} + interface MaintenanceRecord { id: string; date: string; @@ -35,7 +47,8 @@ interface MaintenanceRecord { location: string; estimatedCost: number; actualCost?: number; - partsUsed?: string[]; + serviceCost?: number; + partsUsed?: PartUsed[]; images: { id: string; name: string; url: string; uploadedAt: string }[]; assignedTo?: string; notes: string[]; @@ -44,6 +57,30 @@ interface MaintenanceRecord { createdBy: string; } +interface EVPart { + id: string; + name: string; + buyingPrice: number; + sellingPrice: number; + category: string; + inStock: boolean; +} + +const mockParts: EVPart[] = [ + { id: 'PRT-001', name: 'Front fender', buyingPrice: 800, sellingPrice: 1500, category: 'Body Parts', inStock: true }, + { id: 'PRT-002', name: 'Rear fender', buyingPrice: 900, sellingPrice: 1600, category: 'Body Parts', inStock: true }, + { id: 'PRT-003', name: 'Mounting brackets', buyingPrice: 400, sellingPrice: 800, category: 'Hardware', inStock: true }, + { id: 'PRT-004', name: 'Brake pads', buyingPrice: 350, sellingPrice: 600, category: 'Brakes', inStock: true }, + { id: 'PRT-005', name: 'Front wheel', buyingPrice: 2500, sellingPrice: 4000, category: 'Wheels', inStock: true }, + { id: 'PRT-006', name: 'Rear wheel', buyingPrice: 2200, sellingPrice: 3500, category: 'Wheels', inStock: true }, + { id: 'PRT-007', name: 'Motor controller', buyingPrice: 3500, sellingPrice: 5500, category: 'Electrical', inStock: true }, + { id: 'PRT-008', name: 'Display unit', buyingPrice: 1200, sellingPrice: 2000, category: 'Electrical', inStock: true }, + { id: 'PRT-009', name: 'Throttle', buyingPrice: 450, sellingPrice: 750, category: 'Controls', inStock: true }, + { id: 'PRT-010', name: 'Handlebar', buyingPrice: 800, sellingPrice: 1400, category: 'Controls', inStock: true }, + { id: 'PRT-011', name: 'Seat', buyingPrice: 600, sellingPrice: 1000, category: 'Comfort', inStock: true }, + { id: 'PRT-012', name: 'Side stand', buyingPrice: 250, sellingPrice: 450, category: 'Hardware', inStock: true }, +]; + const mockMaintenance: MaintenanceRecord[] = [ { id: 'MNT-001', @@ -64,7 +101,16 @@ const mockMaintenance: MaintenanceRecord[] = [ location: 'Gulshan, Dhaka', estimatedCost: 3500, actualCost: 3200, - partsUsed: ['Front fender', 'Mounting brackets'], + partsUsed: [ + { id: 'PU-001', partId: 'PRT-001', partName: 'Front fender', quantity: 1, unitPrice: 1500, totalPrice: 1500, addedAt: '2024-03-21' }, + { id: 'PU-002', partId: 'PRT-003', partName: 'Mounting brackets', quantity: 2, unitPrice: 800, totalPrice: 1600, addedAt: '2024-03-21' }, + { id: 'PU-003', partId: 'PRT-004', partName: 'Brake pads', quantity: 2, unitPrice: 600, totalPrice: 1200, addedAt: '2024-03-21' }, + { id: 'PU-004', partId: 'PRT-005', partName: 'Front wheel', quantity: 1, unitPrice: 4000, totalPrice: 4000, addedAt: '2024-03-21' }, + { id: 'PU-005', partId: 'PRT-009', partName: 'Throttle', quantity: 1, unitPrice: 750, totalPrice: 750, addedAt: '2024-03-21' }, + { id: 'PU-006', partId: 'PRT-011', partName: 'Seat', quantity: 1, unitPrice: 1000, totalPrice: 1000, addedAt: '2024-03-21' }, + { id: 'PU-007', partId: 'PRT-010', partName: 'Handlebar', quantity: 1, unitPrice: 1250, totalPrice: 1250, addedAt: '2024-03-21' }, + ], + serviceCost: 3200, images: [ { id: 'img1', name: 'Damage Front', url: '', uploadedAt: '2024-03-21' }, { id: 'img2', name: 'Damage Side', url: '', uploadedAt: '2024-03-21' }, @@ -237,9 +283,17 @@ export default function MaintenanceDetailPage() { const [showPaymentModal, setShowPaymentModal] = useState(false); const [showInvoiceModal, setShowInvoiceModal] = useState(false); const [showAddNoteModal, setShowAddNoteModal] = useState(false); + const [showAddPartModal, setShowAddPartModal] = useState(false); + const [showAddServiceCostModal, setShowAddServiceCostModal] = useState(false); + const [partSearch, setPartSearch] = useState(''); + const [invoiceData, setInvoiceData] = useState({ tips: 0, discount: 0 }); + const [showPaymentSuccess, setShowPaymentSuccess] = useState(false); const [editForm, setEditForm] = useState>({}); const [newNoteText, setNewNoteText] = useState(''); const [actualCost, setActualCost] = useState(''); + const [selectedPart, setSelectedPart] = useState(null); + const [partQuantity, setPartQuantity] = useState(1); + const [serviceCostInput, setServiceCostInput] = useState(''); useEffect(() => { const found = mockMaintenance.find(r => r.id === id); @@ -286,11 +340,11 @@ export default function MaintenanceDetailPage() { const handlePayment = (source: 'bank' | 'cash' | 'biker') => { if (!record) return; - const cost = record.actualCost || record.estimatedCost; + const cost = ((record.partsUsed?.reduce((s, p) => s + p.totalPrice, 0) || 0) + (record.serviceCost || 0)) + invoiceData.tips - invoiceData.discount; - setRecord(prev => prev ? { ...prev, paymentStatus: 'paid' } : null); + setRecord(prev => prev ? { ...prev, paymentStatus: 'paid', actualCost: cost, status: 'completed', resolvedAt: new Date().toISOString().split('T')[0] } : null); setShowPaymentModal(false); - setShowInvoiceModal(true); + setShowPaymentSuccess(true); }; const handleGenerateInvoice = () => { @@ -375,6 +429,8 @@ export default function MaintenanceDetailPage() { setShowAddNoteModal(false); }; + const invoiceTotal = record ? ((record.partsUsed?.reduce((s, p) => s + p.totalPrice, 0) || 0) + (record.serviceCost || 0)) + invoiceData.tips - invoiceData.discount : 0; + return (
- - -
-
-

- Description -

- {editMode ? ( -