769 lines
33 KiB
TypeScript
769 lines
33 KiB
TypeScript
import { FileText, Calendar, Building, Plus, Eye } from 'lucide-react';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card';
|
|
import { Badge } from '../ui/badge';
|
|
import { Button } from '../ui/button';
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
|
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog';
|
|
import { Input } from '../ui/input';
|
|
import { Label } from '../ui/label';
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';
|
|
import { Textarea } from '../ui/textarea';
|
|
import { useState } from 'react';
|
|
import { User } from '../../lib/mock-data';
|
|
import { toast } from 'sonner';
|
|
|
|
interface ResignationPageProps {
|
|
currentUser: User | null;
|
|
onViewDetails: (id: string) => void;
|
|
}
|
|
|
|
// Mock dealer data for auto-fetch
|
|
const mockDealerData: Record<string, any> = {
|
|
'DL-MH-001': {
|
|
dealerName: 'Amit Sharma Motors',
|
|
address: '123, MG Road, Bandra West',
|
|
cityCategory: 'Tier 1',
|
|
domainName: 'Mumbai Central',
|
|
dealershipName: 'Royal Enfield Mumbai',
|
|
gst: '27AABCU9603R1ZX',
|
|
salesCode: 'SAL-MH-001',
|
|
serviceCode: 'SRV-MH-001',
|
|
accessoriesCode: 'ACC-MH-001',
|
|
gmaCode: 'GMA-MH-001'
|
|
},
|
|
'DL-KA-045': {
|
|
dealerName: 'Priya Automobiles',
|
|
address: '456, Brigade Road, Whitefield',
|
|
cityCategory: 'Tier 1',
|
|
domainName: 'Bangalore South',
|
|
dealershipName: 'Royal Enfield Bangalore',
|
|
gst: '29AABCU9603R1ZX',
|
|
salesCode: 'SAL-KA-045',
|
|
serviceCode: 'SRV-KA-045',
|
|
accessoriesCode: 'ACC-KA-045',
|
|
gmaCode: 'GMA-KA-045'
|
|
}
|
|
};
|
|
|
|
// Mock resignation requests
|
|
export const mockResignationRequests = [
|
|
{
|
|
id: 'RES-001',
|
|
dealerCode: 'DL-MH-001',
|
|
dealerName: 'Amit Sharma Motors',
|
|
location: 'Mumbai, Maharashtra',
|
|
dealershipType: 'Main Dealer',
|
|
formatCategory: 'A+',
|
|
resignationReason: 'Personal Health Reasons',
|
|
status: 'ASM Review',
|
|
currentStage: 'ASM',
|
|
submittedOn: '2025-10-08',
|
|
submittedBy: 'DD Lead'
|
|
},
|
|
{
|
|
id: 'RES-002',
|
|
dealerCode: 'DL-KA-045',
|
|
dealerName: 'Priya Automobiles',
|
|
location: 'Bangalore, Karnataka',
|
|
dealershipType: 'Studio',
|
|
formatCategory: 'A',
|
|
resignationReason: 'Relocating to Different City',
|
|
status: 'DD Lead Review',
|
|
currentStage: 'DD Lead',
|
|
submittedOn: '2025-10-03',
|
|
submittedBy: 'DD Lead'
|
|
},
|
|
{
|
|
id: 'RES-003',
|
|
dealerCode: 'DL-TN-028',
|
|
dealerName: 'Rahul Motors',
|
|
location: 'Chennai, Tamil Nadu',
|
|
dealershipType: 'Main Dealer',
|
|
formatCategory: 'B',
|
|
resignationReason: 'Starting Own Venture',
|
|
status: 'NBH Approved',
|
|
currentStage: 'Legal',
|
|
submittedOn: '2025-10-05',
|
|
submittedBy: 'DD Lead'
|
|
}
|
|
];
|
|
|
|
const getStatusColor = (status: string) => {
|
|
if (status.includes('Approved')) return 'bg-green-100 text-green-700 border-green-300';
|
|
if (status.includes('Review') || status.includes('Pending')) return 'bg-yellow-100 text-yellow-700 border-yellow-300';
|
|
if (status.includes('Rejected')) return 'bg-red-100 text-red-700 border-red-300';
|
|
return 'bg-blue-100 text-blue-700 border-blue-300';
|
|
};
|
|
|
|
export function ResignationPage({ currentUser, onViewDetails }: ResignationPageProps) {
|
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
const [dealerCode, setDealerCode] = useState('');
|
|
const [autoFilledData, setAutoFilledData] = useState<any>(null);
|
|
const [formData, setFormData] = useState({
|
|
inaugurationMonth: '',
|
|
inaugurationYear: '',
|
|
loaMonth: '',
|
|
loaYear: '',
|
|
loiMonth: '',
|
|
loiYear: '',
|
|
lastSixMonthsSales: '',
|
|
numberOfDealerships: '',
|
|
numberOfStudios: '',
|
|
constitution: '',
|
|
dealershipType: '',
|
|
typeOfClosure: '',
|
|
formatCategory: '',
|
|
dealerScoreCardBand: '',
|
|
resignationReason: '',
|
|
customerDescription: '',
|
|
document: null as File | null
|
|
});
|
|
|
|
const handleDealerCodeChange = (code: string) => {
|
|
setDealerCode(code);
|
|
if (mockDealerData[code]) {
|
|
setAutoFilledData(mockDealerData[code]);
|
|
toast.success('Dealer details loaded successfully');
|
|
} else {
|
|
setAutoFilledData(null);
|
|
if (code) {
|
|
toast.error('Dealer code not found');
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (!autoFilledData) {
|
|
toast.error('Please enter a valid dealer code');
|
|
return;
|
|
}
|
|
toast.success('Resignation request submitted successfully');
|
|
setIsDialogOpen(false);
|
|
// Reset form
|
|
setDealerCode('');
|
|
setAutoFilledData(null);
|
|
setFormData({
|
|
inaugurationMonth: '',
|
|
inaugurationYear: '',
|
|
loaMonth: '',
|
|
loaYear: '',
|
|
loiMonth: '',
|
|
loiYear: '',
|
|
lastSixMonthsSales: '',
|
|
numberOfDealerships: '',
|
|
numberOfStudios: '',
|
|
constitution: '',
|
|
dealershipType: '',
|
|
typeOfClosure: '',
|
|
formatCategory: '',
|
|
dealerScoreCardBand: '',
|
|
resignationReason: '',
|
|
customerDescription: '',
|
|
document: null
|
|
});
|
|
};
|
|
|
|
const isDDLead = currentUser?.role === 'DD Lead';
|
|
|
|
// Helper function to check if request is at current user's level
|
|
const isRequestAtMyLevel = (request: any) => {
|
|
if (!currentUser) return false;
|
|
|
|
const roleToStageMapping: Record<string, string[]> = {
|
|
'DD Lead': ['DD Lead'],
|
|
'DD-ZM': ['DD-ZM'],
|
|
'RBM': ['RBM'],
|
|
'DD AM': ['ASM', 'DD AM'],
|
|
'ZBH': ['ZBH'],
|
|
'NBH': ['NBH'],
|
|
'Legal Admin': ['Legal'],
|
|
'DD Admin': ['DD Admin'],
|
|
'Super Admin': ['DD Admin', 'NBH', 'Legal', 'ZBH', 'RBM', 'ASM', 'DD Lead']
|
|
};
|
|
|
|
const userStages = roleToStageMapping[currentUser.role] || [];
|
|
return userStages.some(stage =>
|
|
request.currentStage.includes(stage) ||
|
|
request.status.includes(stage)
|
|
);
|
|
};
|
|
|
|
const openRequests = mockResignationRequests.filter(req =>
|
|
!req.status.includes('Completed') &&
|
|
!req.status.includes('Closed') &&
|
|
isRequestAtMyLevel(req)
|
|
);
|
|
|
|
const completedRequests = mockResignationRequests.filter(req =>
|
|
req.status.includes('Completed') ||
|
|
req.status.includes('Closed') ||
|
|
req.status.includes('Final Approval')
|
|
);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Header Stats */}
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<Card>
|
|
<CardHeader className="pb-3">
|
|
<CardDescription>All Requests</CardDescription>
|
|
<CardTitle className="text-3xl">{mockResignationRequests.length}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-slate-600">Total Requests</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="pb-3">
|
|
<CardDescription>Open</CardDescription>
|
|
<CardTitle className="text-3xl text-yellow-600">{openRequests.length}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-slate-600">Requires Your Action</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader className="pb-3">
|
|
<CardDescription>Completed</CardDescription>
|
|
<CardTitle className="text-3xl text-green-600">{completedRequests.length}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<p className="text-slate-600">Finalized</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Main Content */}
|
|
<Card>
|
|
<CardHeader>
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<CardTitle>Resignation Requests</CardTitle>
|
|
<CardDescription>
|
|
Track and manage dealer resignation requests
|
|
{!isDDLead && (
|
|
<span className="block mt-1 text-amber-600">
|
|
• Note: Only DD Lead can create resignation requests. Current role: {currentUser?.role || 'Not logged in'}
|
|
</span>
|
|
)}
|
|
</CardDescription>
|
|
</div>
|
|
{isDDLead && (
|
|
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
|
<DialogTrigger asChild>
|
|
<Button className="bg-amber-600 hover:bg-amber-700">
|
|
<Plus className="w-4 h-4 mr-2" />
|
|
Create Resignation Request
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
|
|
<DialogHeader>
|
|
<DialogTitle>Create Resignation Request</DialogTitle>
|
|
<DialogDescription>
|
|
Fill in the details to create a new resignation request
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
{/* Dealer Code - Auto-fetch trigger */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="dealerCode">Dealer Code *</Label>
|
|
<Input
|
|
id="dealerCode"
|
|
value={dealerCode}
|
|
onChange={(e) => handleDealerCodeChange(e.target.value)}
|
|
placeholder="e.g., DL-MH-001"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
{/* Auto-filled data */}
|
|
{autoFilledData && (
|
|
<div className="grid grid-cols-2 gap-4 p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<Label className="text-slate-600">Dealership Name</Label>
|
|
<p>{autoFilledData.dealerName}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">GST</Label>
|
|
<p>{autoFilledData.gst}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Address</Label>
|
|
<p>{autoFilledData.address}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">City Category</Label>
|
|
<p>{autoFilledData.cityCategory}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Domain Name</Label>
|
|
<p>{autoFilledData.domainName}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Dealership Principal Name</Label>
|
|
<p>{autoFilledData.dealershipName}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Sales Code</Label>
|
|
<p>{autoFilledData.salesCode}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Service Code</Label>
|
|
<p>{autoFilledData.serviceCode}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">Accessories Code</Label>
|
|
<p>{autoFilledData.accessoriesCode}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="text-slate-600">GMA Code</Label>
|
|
<p>{autoFilledData.gmaCode}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Date fields */}
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="space-y-2">
|
|
<Label>Inauguration *</Label>
|
|
<div className="flex gap-2">
|
|
<Input
|
|
type="number"
|
|
placeholder="Month (1-12)"
|
|
min="1"
|
|
max="12"
|
|
value={formData.inaugurationMonth}
|
|
onChange={(e) => setFormData({...formData, inaugurationMonth: e.target.value})}
|
|
required
|
|
/>
|
|
<Input
|
|
type="number"
|
|
placeholder="Year"
|
|
min="2000"
|
|
max="2025"
|
|
value={formData.inaugurationYear}
|
|
onChange={(e) => setFormData({...formData, inaugurationYear: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>LOA *</Label>
|
|
<div className="flex gap-2">
|
|
<Input
|
|
type="number"
|
|
placeholder="Month (1-12)"
|
|
min="1"
|
|
max="12"
|
|
value={formData.loaMonth}
|
|
onChange={(e) => setFormData({...formData, loaMonth: e.target.value})}
|
|
required
|
|
/>
|
|
<Input
|
|
type="number"
|
|
placeholder="Year"
|
|
min="2000"
|
|
max="2025"
|
|
value={formData.loaYear}
|
|
onChange={(e) => setFormData({...formData, loaYear: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>LOI *</Label>
|
|
<div className="flex gap-2">
|
|
<Input
|
|
type="number"
|
|
placeholder="Month (1-12)"
|
|
min="1"
|
|
max="12"
|
|
value={formData.loiMonth}
|
|
onChange={(e) => setFormData({...formData, loiMonth: e.target.value})}
|
|
required
|
|
/>
|
|
<Input
|
|
type="number"
|
|
placeholder="Year"
|
|
min="2000"
|
|
max="2025"
|
|
value={formData.loiYear}
|
|
onChange={(e) => setFormData({...formData, loiYear: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="sales">Last 6 Months Sales *</Label>
|
|
<Input
|
|
id="sales"
|
|
type="number"
|
|
placeholder="Enter sales figure"
|
|
value={formData.lastSixMonthsSales}
|
|
onChange={(e) => setFormData({...formData, lastSixMonthsSales: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Number fields */}
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="dealerships">Number of Dealerships *</Label>
|
|
<Input
|
|
id="dealerships"
|
|
type="number"
|
|
value={formData.numberOfDealerships}
|
|
onChange={(e) => setFormData({...formData, numberOfDealerships: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="studios">Number of Studios *</Label>
|
|
<Input
|
|
id="studios"
|
|
type="number"
|
|
value={formData.numberOfStudios}
|
|
onChange={(e) => setFormData({...formData, numberOfStudios: e.target.value})}
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Dropdown fields */}
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="space-y-2">
|
|
<Label>Constitution *</Label>
|
|
<Select value={formData.constitution} onValueChange={(value) => setFormData({...formData, constitution: value})}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select constitution" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="pvt-ltd">PVT. LTD.</SelectItem>
|
|
<SelectItem value="partnership">Partnership</SelectItem>
|
|
<SelectItem value="proprietorship">Proprietorship</SelectItem>
|
|
<SelectItem value="public-limited">Public Limited</SelectItem>
|
|
<SelectItem value="llp">LLP</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>Dealership Type *</Label>
|
|
<Select value={formData.dealershipType} onValueChange={(value) => setFormData({...formData, dealershipType: value})}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select type" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="main-dealer">Main Dealer</SelectItem>
|
|
<SelectItem value="studio">Studio</SelectItem>
|
|
<SelectItem value="asp">ASP</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>Type of Closure *</Label>
|
|
<Select value={formData.typeOfClosure} onValueChange={(value) => setFormData({...formData, typeOfClosure: value})}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select closure type" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="complete">Complete</SelectItem>
|
|
<SelectItem value="partial">Partial</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
{formData.dealershipType !== 'studio' && (
|
|
<div className="space-y-2">
|
|
<Label>Format Category *</Label>
|
|
<Select value={formData.formatCategory} onValueChange={(value) => setFormData({...formData, formatCategory: value})}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select category" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="a-plus">A+</SelectItem>
|
|
<SelectItem value="a">A</SelectItem>
|
|
<SelectItem value="b">B</SelectItem>
|
|
<SelectItem value="c">C</SelectItem>
|
|
<SelectItem value="d">D</SelectItem>
|
|
<SelectItem value="e">E</SelectItem>
|
|
<SelectItem value="r">R</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
)}
|
|
<div className="space-y-2">
|
|
<Label>Dealer Score Card Band *</Label>
|
|
<Select value={formData.dealerScoreCardBand} onValueChange={(value) => setFormData({...formData, dealerScoreCardBand: value})}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select band" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="platinum">Platinum</SelectItem>
|
|
<SelectItem value="gold">Gold</SelectItem>
|
|
<SelectItem value="silver">Silver</SelectItem>
|
|
<SelectItem value="bronze">Bronze</SelectItem>
|
|
<SelectItem value="no-band">No Band</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Text fields */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="reason">Resignation Reason *</Label>
|
|
<Input
|
|
id="reason"
|
|
value={formData.resignationReason}
|
|
onChange={(e) => setFormData({...formData, resignationReason: e.target.value})}
|
|
placeholder="Brief reason for resignation"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="description">Dealer Voice *</Label>
|
|
<Textarea
|
|
id="description"
|
|
value={formData.customerDescription}
|
|
onChange={(e) => setFormData({...formData, customerDescription: e.target.value})}
|
|
placeholder="Detailed description provided by customer"
|
|
rows={4}
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="document">Upload Document</Label>
|
|
<Input
|
|
id="document"
|
|
type="file"
|
|
onChange={(e) => setFormData({...formData, document: e.target.files?.[0] || null})}
|
|
/>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button type="button" variant="outline" onClick={() => setIsDialogOpen(false)}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="submit" className="bg-amber-600 hover:bg-amber-700">
|
|
Submit Request
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)}
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Tabs defaultValue="all" className="w-full">
|
|
<TabsList>
|
|
<TabsTrigger value="all">All Requests</TabsTrigger>
|
|
<TabsTrigger value="open">Open</TabsTrigger>
|
|
<TabsTrigger value="completed">Completed</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="all" className="mt-6">
|
|
<div className="space-y-4">
|
|
{mockResignationRequests.map((request) => (
|
|
<Card key={request.id} className="border-slate-200">
|
|
<CardContent className="pt-6">
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex items-start gap-4 flex-1">
|
|
<div className="p-3 bg-amber-100 rounded-lg">
|
|
<FileText className="w-6 h-6 text-amber-600" />
|
|
</div>
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-3 mb-2">
|
|
<h3 className="text-lg">{request.id}</h3>
|
|
<Badge className={getStatusColor(request.status)}>
|
|
{request.status}
|
|
</Badge>
|
|
</div>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div>
|
|
<p className="text-slate-600">Dealer Name</p>
|
|
<p>{request.dealerName}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Dealer Code</p>
|
|
<p>{request.dealerCode}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Location</p>
|
|
<p>{request.location}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Dealership Type</p>
|
|
<p>{request.dealershipType}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Format Category</p>
|
|
<p>{request.formatCategory}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Reason</p>
|
|
<p>{request.resignationReason}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Current Stage</p>
|
|
<p>{request.currentStage}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Submitted On</p>
|
|
<div className="flex items-center gap-1">
|
|
<Calendar className="w-4 h-4 text-slate-500" />
|
|
<p>{request.submittedOn}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => onViewDetails(request.id)}
|
|
className="ml-4"
|
|
>
|
|
<Eye className="w-4 h-4 mr-2" />
|
|
View Details
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</TabsContent>
|
|
|
|
{/* Open Tab */}
|
|
<TabsContent value="open" className="mt-6">
|
|
<div className="space-y-4">
|
|
{openRequests.length > 0 ? (
|
|
openRequests.map((request) => (
|
|
<Card key={request.id} className="border-slate-200">
|
|
<CardContent className="pt-6">
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex items-start gap-4 flex-1">
|
|
<div className="p-3 bg-yellow-100 rounded-lg">
|
|
<FileText className="w-6 h-6 text-yellow-600" />
|
|
</div>
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-3 mb-2">
|
|
<h3 className="text-lg">{request.id}</h3>
|
|
<Badge className={getStatusColor(request.status)}>
|
|
{request.status}
|
|
</Badge>
|
|
</div>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div>
|
|
<p className="text-slate-600">Dealer Name</p>
|
|
<p>{request.dealerName}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Location</p>
|
|
<p>{request.location}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Current Stage</p>
|
|
<p>{request.currentStage}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Submitted On</p>
|
|
<p>{request.submittedOn}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => onViewDetails(request.id)}
|
|
className="ml-4"
|
|
>
|
|
<Eye className="w-4 h-4 mr-2" />
|
|
View Details
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))
|
|
) : (
|
|
<div className="text-center py-12 text-slate-500">
|
|
<FileText className="w-12 h-12 mx-auto mb-4 text-slate-400" />
|
|
<p>No requests requiring your action</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</TabsContent>
|
|
|
|
{/* Completed Tab */}
|
|
<TabsContent value="completed" className="mt-6">
|
|
<div className="space-y-4">
|
|
{completedRequests.length > 0 ? (
|
|
completedRequests.map((request) => (
|
|
<Card key={request.id} className="border-slate-200">
|
|
<CardContent className="pt-6">
|
|
<div className="flex items-start justify-between">
|
|
<div className="flex items-start gap-4 flex-1">
|
|
<div className="p-3 bg-green-100 rounded-lg">
|
|
<FileText className="w-6 h-6 text-green-600" />
|
|
</div>
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-3 mb-2">
|
|
<h3 className="text-lg">{request.id}</h3>
|
|
<Badge className={getStatusColor(request.status)}>
|
|
{request.status}
|
|
</Badge>
|
|
</div>
|
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
|
|
<div>
|
|
<p className="text-slate-600">Dealer Name</p>
|
|
<p>{request.dealerName}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Location</p>
|
|
<p>{request.location}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Final Stage</p>
|
|
<p>{request.currentStage}</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-slate-600">Submitted On</p>
|
|
<p>{request.submittedOn}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => onViewDetails(request.id)}
|
|
className="ml-4"
|
|
>
|
|
<Eye className="w-4 h-4 mr-2" />
|
|
View Details
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
))
|
|
) : (
|
|
<div className="text-center py-12 text-slate-500">
|
|
<FileText className="w-12 h-12 mx-auto mb-4 text-slate-400" />
|
|
<p>No completed resignations to display</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</TabsContent>
|
|
</Tabs>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|