Cloudtopiaa_Reseller_Frontend/src/pages/reseller/Dashboard.tsx
2025-08-05 18:15:16 +05:30

323 lines
15 KiB
TypeScript

import React, { useEffect } from 'react';
import { useAppSelector, useAppDispatch } from '../../store/hooks';
import { useNavigate } from 'react-router-dom';
import { setStats, setRecentActivities, setQuickActions } from '../../store/slices/dashboardSlice';
import { loginSuccess } from '../../store/slices/authSlice';
import { mockDashboardStats, mockRecentActivities, mockResellerQuickActions, mockResellerRecentActivities, mockUser } from '../../data/mockData';
import { formatNumber, formatRelativeTime, formatPercentage } from '../../utils/format';
import RevenueChart from '../../components/charts/RevenueChart';
import ResellerPerformanceChart from '../../components/charts/ResellerPerformanceChart';
import DualCurrencyDisplay from '../../components/DualCurrencyDisplay';
import {
TrendingUp,
Users,
Cloud,
DollarSign,
UserPlus,
CheckCircle,
Briefcase,
GraduationCap,
BarChart3,
CreditCard,
Headphones,
ShoppingBag,
Award,
HelpCircle,
Settings,
Wallet,
BookOpen,
Zap,
Target,
Star,
ArrowUpRight,
Activity
} from 'lucide-react';
import { cn } from '../../utils/cn';
const ResellerDashboard: React.FC = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const { stats, recentActivities, quickActions } = useAppSelector((state) => state.dashboard);
useEffect(() => {
// Initialize with mock data
dispatch(loginSuccess({
user: {
...mockUser,
role: 'reseller_admin',
company: 'Tech Solutions Inc'
},
token: 'mock-token',
refreshToken: 'mock-refresh-token'
}));
dispatch(setStats(mockDashboardStats));
dispatch(setRecentActivities(mockResellerRecentActivities));
dispatch(setQuickActions(mockResellerQuickActions));
}, [dispatch]);
const handleQuickAction = (action: any) => {
switch (action.id) {
case 'add-customer':
navigate('/reseller-dashboard/customers');
break;
case 'create-instance':
navigate('/reseller-dashboard/instances');
break;
case 'billing':
navigate('/reseller-dashboard/billing');
break;
case 'support':
navigate('/reseller-dashboard/support');
break;
case 'training':
navigate('/reseller-dashboard/training');
break;
case 'reports':
navigate('/reseller-dashboard/reports');
break;
case 'wallet':
navigate('/reseller-dashboard/wallet');
break;
case 'marketplace':
navigate('/reseller-dashboard/marketplace');
break;
case 'certifications':
navigate('/reseller-dashboard/certifications');
break;
case 'knowledge-base':
navigate('/reseller-dashboard/knowledge-base');
break;
case 'settings':
navigate('/reseller-dashboard/settings');
break;
default:
break;
}
};
return (
<div className="space-y-8">
{/* Welcome Section */}
<div className="bg-gradient-to-r from-emerald-600 via-teal-600 to-cyan-600 rounded-3xl p-8 text-white relative overflow-hidden">
<div className="absolute inset-0 bg-black/10"></div>
<div className="relative z-10">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold mb-2">Welcome back, John! </h1>
<p className="text-emerald-100 text-lg">Here's what's happening with your cloud services business today.</p>
</div>
<div className="hidden lg:flex items-center space-x-4">
<div className="text-center">
<div className="text-2xl font-bold">{formatNumber(stats.totalResellers)}</div>
<div className="text-emerald-100 text-sm">Active Customers</div>
</div>
<div className="text-center">
<DualCurrencyDisplay
amount={stats.commissionEarned}
currency={stats.currency}
className="text-2xl font-bold text-white"
/>
<div className="text-emerald-100 text-sm">Monthly Revenue</div>
</div>
</div>
</div>
</div>
<div className="absolute top-0 right-0 w-64 h-64 bg-white/10 rounded-full -translate-y-32 translate-x-32"></div>
<div className="absolute bottom-0 left-0 w-48 h-48 bg-white/5 rounded-full translate-y-24 -translate-x-24"></div>
</div>
{/* Key Metrics */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700 hover:shadow-xl transition-all duration-300 group">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
<DollarSign className="w-6 h-6 text-white" />
</div>
<TrendingUp className="w-5 h-5 text-green-500" />
</div>
<h3 className="text-2xl font-bold text-slate-900 dark:text-white mb-1">
<DualCurrencyDisplay
amount={stats.totalRevenue}
currency={stats.currency}
className="text-2xl"
/>
</h3>
<p className="text-slate-600 dark:text-slate-400 text-sm">Total Revenue</p>
<div className="flex items-center mt-2 text-green-600 text-sm">
<ArrowUpRight className="w-4 h-4 mr-1" />
+{stats.monthlyGrowth}% from last month
</div>
</div>
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700 hover:shadow-xl transition-all duration-300 group">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-gradient-to-r from-emerald-500 to-emerald-600 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
<Users className="w-6 h-6 text-white" />
</div>
<Activity className="w-5 h-5 text-emerald-500" />
</div>
<h3 className="text-2xl font-bold text-slate-900 dark:text-white mb-1">
{formatNumber(stats.totalResellers)}
</h3>
<p className="text-slate-600 dark:text-slate-400 text-sm">Active Customers</p>
<div className="flex items-center mt-2 text-emerald-600 text-sm">
<ArrowUpRight className="w-4 h-4 mr-1" />
+5 new this month
</div>
</div>
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700 hover:shadow-xl transition-all duration-300 group">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-gradient-to-r from-purple-500 to-purple-600 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
<Cloud className="w-6 h-6 text-white" />
</div>
<Zap className="w-5 h-5 text-purple-500" />
</div>
<h3 className="text-2xl font-bold text-slate-900 dark:text-white mb-1">
{formatNumber(stats.activePartnerships)}
</h3>
<p className="text-slate-600 dark:text-slate-400 text-sm">Cloud Instances</p>
<div className="flex items-center mt-2 text-purple-600 text-sm">
<ArrowUpRight className="w-4 h-4 mr-1" />
+12 new instances
</div>
</div>
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700 hover:shadow-xl transition-all duration-300 group">
<div className="flex items-center justify-between mb-4">
<div className="w-12 h-12 bg-gradient-to-r from-orange-500 to-orange-600 rounded-xl flex items-center justify-center group-hover:scale-110 transition-transform duration-300">
<Target className="w-6 h-6 text-white" />
</div>
<Star className="w-5 h-5 text-orange-500" />
</div>
<h3 className="text-2xl font-bold text-slate-900 dark:text-white mb-1">
{formatPercentage(15)}
</h3>
<p className="text-slate-600 dark:text-slate-400 text-sm">Commission Rate</p>
<div className="flex items-center mt-2 text-orange-600 text-sm">
<CheckCircle className="w-4 h-4 mr-1" />
Premium tier
</div>
</div>
</div>
{/* Quick Actions & Recent Activity */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Quick Actions */}
<div className="lg:col-span-1">
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700">
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-6 flex items-center">
<Zap className="w-5 h-5 mr-2 text-emerald-500" />
Quick Actions
</h3>
<div className="space-y-3">
{quickActions.slice(0, 6).map((action) => (
<button
key={action.id}
onClick={() => handleQuickAction(action)}
className="w-full flex items-center p-4 rounded-xl bg-gradient-to-r from-slate-50 to-slate-100 dark:from-slate-700 dark:to-slate-800 hover:from-emerald-50 hover:to-teal-50 dark:hover:from-emerald-900/20 dark:hover:to-teal-900/20 transition-all duration-300 group border border-slate-200 dark:border-slate-600"
>
<div className="w-10 h-10 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-lg flex items-center justify-center mr-4 group-hover:scale-110 transition-transform duration-300">
{action.icon === 'UserPlus' && <UserPlus className="w-5 h-5 text-white" />}
{action.icon === 'Cloud' && <Cloud className="w-5 h-5 text-white" />}
{action.icon === 'CreditCard' && <CreditCard className="w-5 h-5 text-white" />}
{action.icon === 'Headphones' && <Headphones className="w-5 h-5 text-white" />}
{action.icon === 'GraduationCap' && <GraduationCap className="w-5 h-5 text-white" />}
{action.icon === 'BarChart3' && <BarChart3 className="w-5 h-5 text-white" />}
{action.icon === 'Wallet' && <Wallet className="w-5 h-5 text-white" />}
{action.icon === 'ShoppingBag' && <ShoppingBag className="w-5 h-5 text-white" />}
{action.icon === 'Award' && <Award className="w-5 h-5 text-white" />}
{action.icon === 'HelpCircle' && <HelpCircle className="w-5 h-5 text-white" />}
{action.icon === 'Settings' && <Settings className="w-5 h-5 text-white" />}
{action.icon === 'BookOpen' && <BookOpen className="w-5 h-5 text-white" />}
</div>
<div className="text-left flex-1">
<p className="font-semibold text-slate-900 dark:text-white group-hover:text-emerald-600 dark:group-hover:text-emerald-400 transition-colors duration-300">
{action.title}
</p>
<p className="text-sm text-slate-600 dark:text-slate-400">{action.description}</p>
</div>
<ArrowUpRight className="w-4 h-4 text-slate-400 group-hover:text-emerald-500 transition-colors duration-300" />
</button>
))}
</div>
</div>
</div>
{/* Recent Activity */}
<div className="lg:col-span-2">
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700">
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-6 flex items-center">
<Activity className="w-5 h-5 mr-2 text-emerald-500" />
Recent Activity
</h3>
<div className="space-y-4">
{recentActivities.map((activity) => (
<div key={activity.id} className="flex items-start p-4 rounded-xl bg-slate-50 dark:bg-slate-700/50 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors duration-200">
<div className="w-10 h-10 bg-gradient-to-r from-emerald-500 to-teal-500 rounded-lg flex items-center justify-center mr-4 flex-shrink-0">
{activity.type === 'customer_added' && <UserPlus className="w-5 h-5 text-white" />}
{activity.type === 'instance_created' && <Cloud className="w-5 h-5 text-white" />}
{activity.type === 'payment_received' && <CreditCard className="w-5 h-5 text-white" />}
{activity.type === 'support_ticket' && <Headphones className="w-5 h-5 text-white" />}
{activity.type === 'training_completed' && <GraduationCap className="w-5 h-5 text-white" />}
</div>
<div className="flex-1 min-w-0">
<p className="font-semibold text-slate-900 dark:text-white mb-1">
{activity.title}
</p>
<p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
{activity.description}
</p>
{activity.amount && (
<div className="mb-2">
<DualCurrencyDisplay
amount={activity.amount}
currency={activity.currency}
className="text-sm font-semibold text-emerald-600"
/>
</div>
)}
<p className="text-xs text-slate-500 dark:text-slate-400">
{formatRelativeTime(activity.timestamp)}
</p>
</div>
</div>
))}
</div>
<div className="mt-6 pt-4 border-t border-slate-200 dark:border-slate-700">
<button className="text-emerald-600 hover:text-emerald-700 dark:text-emerald-400 dark:hover:text-emerald-300 font-medium flex items-center">
View all activities
<ArrowUpRight className="w-4 h-4 ml-1" />
</button>
</div>
</div>
</div>
</div>
{/* Charts Section */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700">
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-6 flex items-center">
<BarChart3 className="w-5 h-5 mr-2 text-emerald-500" />
Revenue Overview
</h3>
<div className="h-64">
<RevenueChart />
</div>
</div>
<div className="bg-white dark:bg-slate-800 rounded-2xl p-6 shadow-lg border border-slate-200 dark:border-slate-700">
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-6 flex items-center">
<Target className="w-5 h-5 mr-2 text-emerald-500" />
Customer Performance
</h3>
<div className="h-64">
<ResellerPerformanceChart />
</div>
</div>
</div>
</div>
);
};
export default ResellerDashboard;