import { useState, useEffect } 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 { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Badge } from '@/components/ui/badge'; import { Progress } from '@/components/ui/progress'; import { Calendar } from '@/components/ui/calendar'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { motion, AnimatePresence } from 'framer-motion'; import { ArrowLeft, ArrowRight, Calendar as CalendarIcon, Check, Receipt, Building, MapPin, Clock, CheckCircle, Info, FileText, Users, } from 'lucide-react'; import { format } from 'date-fns'; import { toast } from 'sonner'; import { getAllDealers as fetchDealersFromAPI, getDealerByCode, type DealerInfo } from '@/services/dealerApi'; import { ClaimApproverSelectionStep } from './ClaimApproverSelectionStep'; import { useAuth } from '@/contexts/AuthContext'; interface ClaimManagementWizardProps { onBack?: () => void; onSubmit?: (claimData: any) => void; } const CLAIM_TYPES = [ 'Riders Mania Claims', 'Marketing Cost – Bike to Vendor', 'Media Bike Service', 'ARAI Motorcycle Liquidation', 'ARAI Certification – STA Approval CNR', 'Procurement of Spares/Apparel/GMA for Events', 'Fuel for Media Bike Used for Event', 'Motorcycle Buyback and Goodwill Support', 'Liquidation of Used Motorcycle', 'Motorcycle Registration CNR (Owned or Gifted by RE)', 'Legal Claims Reimbursement', 'Service Camp Claims', 'Corporate Claims – Institutional Sales PDI' ]; const STEP_NAMES = [ 'Claim Details', 'Approver Selection', 'Review & Submit' ]; export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizardProps) { const { user } = useAuth(); const [currentStep, setCurrentStep] = useState(1); const [dealers, setDealers] = useState([]); const [loadingDealers, setLoadingDealers] = useState(true); const [formData, setFormData] = useState({ activityName: '', activityType: '', dealerCode: '', dealerName: '', dealerEmail: '', dealerPhone: '', dealerAddress: '', activityDate: undefined as Date | undefined, location: '', requestDescription: '', periodStartDate: undefined as Date | undefined, periodEndDate: undefined as Date | undefined, estimatedBudget: '', // Approvers array for all 8 steps approvers: [] as Array<{ email: string; name?: string; userId?: string; level: number; tat?: number | string; tatType?: 'hours' | 'days'; }> }); const totalSteps = STEP_NAMES.length; // Fetch dealers from API on component mount useEffect(() => { const fetchDealers = async () => { setLoadingDealers(true); try { const fetchedDealers = await fetchDealersFromAPI(); setDealers(fetchedDealers); } catch (error) { toast.error('Failed to load dealer list.'); console.error('Error fetching dealers:', error); } finally { setLoadingDealers(false); } }; fetchDealers(); }, []); const updateFormData = (field: string, value: any) => { setFormData(prev => { const updated = { ...prev, [field]: value }; // Validate period dates if (field === 'periodStartDate') { // If start date is selected and end date exists, validate end date if (value && updated.periodEndDate && value > updated.periodEndDate) { // Clear end date if it's before the new start date updated.periodEndDate = undefined; toast.error('End date must be on or after the start date. End date has been cleared.'); } } else if (field === 'periodEndDate') { // If end date is selected and start date exists, validate end date if (value && updated.periodStartDate && value < updated.periodStartDate) { toast.error('End date must be on or after the start date.'); // Don't update the end date if it's invalid return prev; } } return updated; }); }; const isStepValid = () => { switch (currentStep) { case 1: return formData.activityName && formData.activityType && formData.dealerCode && formData.dealerName && formData.activityDate && formData.location && formData.requestDescription; case 2: // Validate that all required approvers are assigned (Step 3 only, Step 8 is now system/Finance) const approvers = formData.approvers || []; const step3Approver = approvers.find((a: any) => a.level === 3); // Step 8 is now a system step, no validation needed return step3Approver?.email && step3Approver?.userId && step3Approver?.tat; case 3: return true; default: return false; } }; const nextStep = () => { if (currentStep < totalSteps) { if (!isStepValid()) { // Show specific error messages for step 2 (approver selection) if (currentStep === 2) { const approvers = formData.approvers || []; const step3Approver = approvers.find((a: any) => a.level === 3); const missingSteps: string[] = []; if (!step3Approver?.email || !step3Approver?.userId || !step3Approver?.tat) { missingSteps.push('Step 3: Department Lead Approval'); } if (missingSteps.length > 0) { toast.error(`Please add missing approvers: ${missingSteps.join(', ')}`); } else { toast.error('Please complete all required approver selections (email, user verification, and TAT) before proceeding.'); } } else { toast.error('Please complete all required fields before proceeding.'); } return; } setCurrentStep(currentStep + 1); } }; const prevStep = () => { if (currentStep > 1) { setCurrentStep(currentStep - 1); } }; const handleDealerChange = async (dealerCode: string) => { const selectedDealer = dealers.find(d => d.dealerCode === dealerCode); if (selectedDealer) { updateFormData('dealerCode', dealerCode); updateFormData('dealerName', selectedDealer.dealerName); updateFormData('dealerEmail', selectedDealer.email || ''); updateFormData('dealerPhone', selectedDealer.phone || ''); updateFormData('dealerAddress', ''); // Address not available in API response // Try to fetch full dealer info from API try { const fullDealerInfo = await getDealerByCode(dealerCode); if (fullDealerInfo) { updateFormData('dealerEmail', fullDealerInfo.email || selectedDealer.email || ''); updateFormData('dealerPhone', fullDealerInfo.phone || selectedDealer.phone || ''); } } catch (error) { // Ignore error, use basic info from list console.debug('Could not fetch full dealer info:', error); } } }; const handleSubmit = () => { const claimData = { ...formData, templateType: 'claim-management', submittedAt: new Date().toISOString(), status: 'pending', currentStep: 'initiator-review', // Pass approvers array to backend approvers: formData.approvers || [] }; // Don't show toast here - let the parent component handle success/error after API call if (onSubmit) { onSubmit(claimData); } }; const renderStepContent = () => { switch (currentStep) { case 1: return (

Claim Details

Provide comprehensive information about your claim request

{/* Activity Name and Type */}
updateFormData('activityName', e.target.value)} className="mt-2 h-12" />
{/* Dealer Selection */}
{formData.dealerCode && (

Selected: {formData.dealerName} ({formData.dealerCode})

)}
{/* Date and Location */}
updateFormData('activityDate', date)} initialFocus />
updateFormData('location', e.target.value)} className="mt-2 h-12" />
{/* Request Detail */}