Dealer_Onboard_Frontend/src/features/dashboard/pages/DealerDashboard.tsx

290 lines
10 KiB
TypeScript

import { useState, useEffect } from 'react';
import { RefreshCcw, MapPin, Users, TrendingUp, Clock, CheckCircle, AlertCircle, ShoppingBag, Loader2 } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { User } from '@/lib/mock-data';
import { dealerService } from '@/services/dealer.service';
interface DealerDashboardProps {
currentUser: User | null;
onNavigate: (view: string) => void;
}
export function DealerDashboard({ currentUser, onNavigate }: DealerDashboardProps) {
const [loading, setLoading] = useState(true);
const [data, setData] = useState<any>(null);
useEffect(() => {
const fetchDashboard = async () => {
try {
const dashboardData = await dealerService.getDashboardData();
setData(dashboardData);
} catch (error) {
console.error('Failed to fetch dashboard:', error);
} finally {
setLoading(false);
}
};
fetchDashboard();
}, []);
if (loading) {
return (
<div className="flex flex-col items-center justify-center min-h-[400px]">
<Loader2 className="w-10 h-10 text-amber-600 animate-spin mb-4" />
<p className="text-slate-600">Loading your dashboard...</p>
</div>
);
}
const dashboardData = data || {};
const profile = dashboardData.profile || {};
const statsSummary = dashboardData.stats || { constitutional: 0, relocation: 0, resignation: 0, total: 0 };
const recentRequests = dashboardData.recentRequests || [];
const primaryOutlet = dashboardData.outlets?.[0] || {};
// Dealer stats
const stats = [
{
title: 'Constitutional Changes',
value: statsSummary.constitutional,
icon: RefreshCcw,
color: 'bg-blue-500',
change: 'Active Requests',
onClick: () => onNavigate('dealer-constitutional')
},
{
title: 'Relocation Requests',
value: statsSummary.relocation,
icon: MapPin,
color: 'bg-amber-500',
change: 'Active Requests',
onClick: () => onNavigate('dealer-relocation')
},
{
title: 'My Outlets',
value: dashboardData.outlets?.length || 0,
icon: ShoppingBag,
color: 'bg-purple-500',
change: 'Registered',
onClick: () => {}
},
{
title: 'Total Requests',
value: statsSummary.total,
icon: TrendingUp,
color: 'bg-green-500',
change: 'All time',
onClick: () => {}
},
];
// Recent requests by the dealer
// Quick actions for dealer
const quickActions = [
{
title: 'Constitutional Change',
description: 'Request change in business structure',
icon: RefreshCcw,
color: 'bg-blue-50 hover:bg-blue-100 border-blue-200',
textColor: 'text-blue-700',
onClick: () => onNavigate('dealer-constitutional')
},
{
title: 'Request Relocation',
description: 'Move dealership to new location',
icon: MapPin,
color: 'bg-amber-50 hover:bg-amber-100 border-amber-200',
textColor: 'text-amber-700',
onClick: () => onNavigate('dealer-relocation')
},
];
return (
<div className="space-y-6">
{/* Welcome Section */}
<div className="bg-gradient-to-r from-amber-500 to-amber-600 rounded-lg p-6 text-white">
<div className="flex items-center justify-between">
<div>
<h1 className="text-white mb-2">Welcome back, {profile.name || currentUser?.name}!</h1>
<p className="text-amber-100">
Dealer Code: {profile.dealerCode} {profile.businessName}
</p>
<p className="text-amber-100 text-sm mt-1">
{primaryOutlet.name} {primaryOutlet.location}
</p>
</div>
<div className="text-right">
<div className="text-white">Active Dealership</div>
<Badge className="bg-green-500 text-white border-0 mt-2">
<CheckCircle className="w-3 h-3 mr-1" />
Operational
</Badge>
</div>
</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{stats.map((stat, index) => {
const Icon = stat.icon;
return (
<Card
key={index}
className="cursor-pointer hover:shadow-lg transition-shadow"
onClick={stat.onClick}
>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm">{stat.title}</CardTitle>
<div className={`${stat.color} p-2 rounded-lg`}>
<Icon className="h-4 w-4 text-white" />
</div>
</CardHeader>
<CardContent>
<div className="text-slate-900 text-2xl">{stat.value}</div>
<p className="text-xs text-slate-600 mt-1">{stat.change}</p>
</CardContent>
</Card>
);
})}
</div>
{/* Quick Actions */}
<Card>
<CardHeader>
<CardTitle>Quick Actions</CardTitle>
<CardDescription>Submit new requests and manage your dealership</CardDescription>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{quickActions.map((action, index) => {
const Icon = action.icon;
return (
<button
key={index}
onClick={action.onClick}
className={`${action.color} border-2 rounded-lg p-4 text-left transition-all`}
>
<div className="flex items-start gap-3">
<div className={`${action.textColor} p-2 bg-white rounded-lg`}>
<Icon className="w-5 h-5" />
</div>
<div className="flex-1">
<h3 className={`${action.textColor} mb-1`}>{action.title}</h3>
<p className="text-slate-600 text-sm">{action.description}</p>
</div>
</div>
</button>
);
})}
</div>
</CardContent>
</Card>
{/* Recent Requests */}
<Card>
<CardHeader>
<CardTitle>My Recent Requests</CardTitle>
<CardDescription>Track the status of your submitted requests</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{recentRequests.map((request: any) => (
<div
key={request.id}
className="flex items-center justify-between p-4 border border-slate-200 rounded-lg hover:bg-slate-50 transition-colors"
>
<div className="flex-1">
<div className="flex items-center gap-2 mb-1">
<span className="text-slate-900">{request.id}</span>
<Badge variant="outline" className="text-xs">
{request.type}
</Badge>
</div>
<p className="text-slate-600 text-sm">{request.title}</p>
<p className="text-slate-500 text-xs mt-1">Submitted on {request.date}</p>
</div>
<div className="flex items-center gap-3">
<Badge className={`border ${request.color}`}>
{request.status}
</Badge>
<Button variant="ghost" size="sm">
View
</Button>
</div>
</div>
))}
</div>
</CardContent>
</Card>
{/* Information Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Clock className="w-5 h-5 text-amber-600" />
Important Reminders
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div className="flex items-start gap-2">
<AlertCircle className="w-4 h-4 text-amber-600 mt-0.5" />
<div>
<p className="text-slate-900 text-sm">GST Filing Due</p>
<p className="text-slate-600 text-xs">Due by Jan 15, 2026</p>
</div>
</div>
<div className="flex items-start gap-2">
<AlertCircle className="w-4 h-4 text-amber-600 mt-0.5" />
<div>
<p className="text-slate-900 text-sm">Inventory Audit Scheduled</p>
<p className="text-slate-600 text-xs">Jan 20, 2026</p>
</div>
</div>
<div className="flex items-start gap-2">
<CheckCircle className="w-4 h-4 text-green-600 mt-0.5" />
<div>
<p className="text-slate-900 text-sm">Compliance Report Submitted</p>
<p className="text-slate-600 text-xs">Jan 2, 2026</p>
</div>
</div>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Users className="w-5 h-5 text-blue-600" />
Support & Help
</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
<div>
<p className="text-slate-900 text-sm mb-1">Regional Manager</p>
<p className="text-slate-600 text-xs">Rajesh Kumar - +91 98765 43210</p>
</div>
<div>
<p className="text-slate-900 text-sm mb-1">Zonal Business Head</p>
<p className="text-slate-600 text-xs">Priya Sharma - +91 98765 43211</p>
</div>
<div>
<p className="text-slate-900 text-sm mb-1">Support Email</p>
<p className="text-slate-600 text-xs">dealer.support@royalenfield.com</p>
</div>
<Button variant="outline" className="w-full mt-2">
Contact Support
</Button>
</div>
</CardContent>
</Card>
</div>
</div>
);
}