import { FileText, Calendar, Building, Eye, MapPin, Navigation, Loader2 } from 'lucide-react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Dialog, DialogContent, DialogDescription, DialogFooter, 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 { Textarea } from '@/components/ui/textarea'; import { Plus } from 'lucide-react'; import { useState, useEffect } from 'react'; import { User } from '@/lib/mock-data'; import { toast } from 'sonner'; import { API } from '@/api/API'; import { SlaBadge } from '@/components/sla/SlaBadge'; import { useSlaBatchStatus } from '@/hooks/useSlaBatchStatus'; import { formatDateTime } from '@/components/ui/utils'; import { getCurrentStageBadgeClass, getStatusProgressBarClass, } from '@/lib/statusProgressTheme'; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; interface RelocationRequestPageProps { currentUser: User | null; onViewDetails: (id: string) => void; } const getApiErrorMessage = (error: any, fallback: string) => error?.response?.data?.message || error?.data?.message || error?.message || fallback; const getStageBadgeClass = (stage: string, requestStatus?: string) => getCurrentStageBadgeClass(stage, requestStatus); export function RelocationRequestPage({ currentUser, onViewDetails }: RelocationRequestPageProps) { const [requests, setRequests] = useState([]); const [isLoading, setIsLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); const [paginationMeta, setPaginationMeta] = useState(null); const [activeTab, setActiveTab] = useState('all'); const itemsPerPage = 10; // Relocation Creation State (for Super Admin) const [isDialogOpen, setIsDialogOpen] = useState(false); const [outlets, setOutlets] = useState([]); const [selectedOutlet, setSelectedOutlet] = useState(null); const [newCity, setNewCity] = useState(''); const [newState, setNewState] = useState(''); const [newAddress, setNewAddress] = useState(''); const [reason, setReason] = useState(''); const [distance, setDistance] = useState(''); const [propertyType, setPropertyType] = useState(''); const [expectedDate, setExpectedDate] = useState(''); const [newLat, setNewLat] = useState(''); const [newLong, setNewLong] = useState(''); const [submitting, setSubmitting] = useState(false); // Master Data const [states, setStates] = useState([]); const [districts, setDistricts] = useState([]); const [selectedStateId, setSelectedStateId] = useState(''); const [selectedDistrictId, setSelectedDistrictId] = useState(''); const [masterDataLoading, setMasterDataLoading] = useState(false); // Constants const isSuperAdmin = currentUser?.role === 'Super Admin' || currentUser?.roleCode === 'Super Admin'; const slaItems = requests.map((r: any) => ({ entityType: 'relocation', entityId: r.id || r.requestId })); const { get: getSla } = useSlaBatchStatus(slaItems, requests.length > 0); const isCompletedRequest = (request: any) => request.status === 'Completed' || request.status === 'Closed' || request.currentStage === 'Completed'; const isRejectedRequest = (request: any) => request.status === 'Rejected' || request.status === 'Revoked' || request.currentStage === 'Rejected'; const isPendingReviewRequest = (request: any) => !isCompletedRequest(request) && !isRejectedRequest(request) && String(request.status || '').startsWith('Pending'); useEffect(() => { fetchRequests(); }, [currentPage, activeTab]); useEffect(() => { if (isSuperAdmin) { fetchOutlets(); fetchMasterData(); } }, [isSuperAdmin]); const handleTabChange = (val: string) => { setActiveTab(val); setCurrentPage(1); }; const fetchOutlets = async () => { try { const response = await API.getOutlets() as any; if (response.data.success) { setOutlets(response.data.outlets || response.data.data?.outlets || response.data.data || []); } } catch (error) { console.error('Fetch outlets error:', error); } }; const fetchMasterData = async () => { try { setMasterDataLoading(true); const [statesRes, districtsRes] = await Promise.all([ API.getStates().catch(() => ({ success: false })) as Promise, API.getDistricts({ limit: 'all' }).catch(() => ({ success: false })) as Promise ]); const statesData = statesRes?.data?.success ? (statesRes.data.data?.states || statesRes.data.data || []) : []; const districtsData = districtsRes?.data?.success ? (districtsRes.data.data?.districts || districtsRes.data.data || []) : []; setStates(statesData); setDistricts(districtsData); } catch (error) { console.error('Fetch master data error:', error); } finally { setMasterDataLoading(false); } }; const handleStateChange = (stateId: string) => { setSelectedStateId(stateId); setSelectedDistrictId(''); const selectedState = states.find(s => s.id === stateId); if (selectedState) { setNewState(selectedState.name); } }; const handleDistrictChange = (districtId: string) => { setSelectedDistrictId(districtId); const selectedDistrict = districts.find(d => d.id === districtId); if (selectedDistrict) { setNewCity(selectedDistrict.name); } }; const handleSubmitRequest = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedOutlet || !newCity || !newState || !newAddress || !reason || !distance || !propertyType || !expectedDate) { toast.error('Please fill all mandatory fields'); return; } try { setSubmitting(true); const payload = { outletId: selectedOutlet.id, relocationType: 'Intercity', currentAddress: selectedOutlet.address || '', currentCity: selectedOutlet.city || '', currentState: selectedOutlet.state || '', newAddress, newCity, newState, newDistrictId: selectedDistrictId || null, newStateId: selectedStateId || null, reason, distance, propertyType, proposedDate: expectedDate, newLatitude: newLat ? parseFloat(newLat) : null, newLongitude: newLong ? parseFloat(newLong) : null, currentLatitude: selectedOutlet.latitude || null, currentLongitude: selectedOutlet.longitude || null }; const response = await API.createRelocationRequest(payload) as any; if (response.data.success) { toast.success(`Relocation request submitted successfully for ${selectedOutlet.name}`); setIsDialogOpen(false); fetchRequests(); // Reset form setSelectedOutlet(null); setNewCity(''); setNewState(''); setNewAddress(''); setReason(''); setDistance(''); setPropertyType(''); setExpectedDate(''); setNewLat(''); setNewLong(''); } } catch (error) { console.error('Submit relocation error:', error); toast.error(getApiErrorMessage(error, 'Failed to submit relocation request')); } finally { setSubmitting(false); } }; const filteredDistricts = selectedStateId ? districts.filter(d => d.stateId === selectedStateId) : districts; const fetchRequests = async () => { try { setIsLoading(true); const response = await API.getRelocationRequests({ page: currentPage, limit: itemsPerPage, status: activeTab === 'all' ? undefined : activeTab }) as any; if (response.data.success) { setRequests(response.data.requests); setPaginationMeta(response.meta); } } catch (error) { console.error('Fetch relocation requests error:', error); toast.error('Failed to fetch relocation requests'); } finally { setIsLoading(false); } }; // Statistics const stats = [ { title: 'Total Requests', value: requests.length, icon: FileText, color: 'bg-blue-500', }, { title: 'Pending Review', value: requests.filter((r: any) => isPendingReviewRequest(r)).length, icon: Calendar, color: 'bg-re-red', }, { title: 'Completed', value: requests.filter((r: any) => isCompletedRequest(r)).length, icon: MapPin, color: 'bg-green-500', }, { title: 'Rejected / Revoked', value: requests.filter((r: any) => isRejectedRequest(r)).length, icon: Building, color: 'bg-red-500', }, ]; return (
{/* Header */}

Relocation Request Management

Manage dealer relocation requests - Moving dealership to a new location

• Note: Relocation requests are initiated by the dealer.
{isSuperAdmin && ( Submit Relocation Request Create a new relocation request on behalf of a dealer
{/* Select Outlet */}
{selectedOutlet && (

Current Location

{selectedOutlet.address}, {selectedOutlet.city}, {selectedOutlet.state} - {selectedOutlet.pincode}

)} {/* New Location Details - State/District Dropdowns */}