![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/lavocat.quebec/private_html/src/components/ |
import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, ArrowLeft, ArrowRight, Loader2, FileText } from 'lucide-react';
import { useSession } from 'next-auth/react';
import toast from 'react-hot-toast';
import NewCaseForm from './NewCaseForm';
import MessagesPage from '../pages/messages';
interface DashboardModalProps {
isOpen: boolean;
onClose: () => void;
route: string;
title?: string;
}
interface ModalContent {
title: string;
component: React.ReactNode;
}
const DashboardModal: React.FC<DashboardModalProps> = ({
isOpen,
onClose,
route,
title
}) => {
const { data: session } = useSession();
const [content, setContent] = useState<ModalContent | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (isOpen && route) {
loadModalContent();
}
}, [isOpen, route]);
const loadModalContent = async () => {
setLoading(true);
setError(null);
try {
// Map routes to their modal content
const contentMap: { [key: string]: () => Promise<ModalContent> } = {
'/lawyer/cases': loadLawyerCases,
'/lawyer/consultations': loadConsultations,
'/lawyer/team': loadTeam,
'/lawyer/calendar': loadCalendar,
'/lawyer/analytics': loadAnalytics,
'/lawyer/clients': loadClients,
'/lawyer/profile': loadProfile,
'/lawyer/applications': loadLawyerApplications,
'/client/cases': loadClientCases,
'/client/documents': loadDocuments,
'/client/payments': loadPayments,
'/client/messages': loadClientMessagesModal,
'/admin/users': loadUsers,
'/admin/cases': loadAdminCases,
'/admin/registrations': loadRegistrations,
'/admin/analytics': loadAdminAnalytics,
'/admin/settings': loadSettings,
'/client/applications': loadClientApplications,
'/client/applications/full': loadClientApplicationsFull,
'/hire/new-case': loadNewCaseModal,
};
const contentLoader = contentMap[route];
if (contentLoader) {
const modalContent = await contentLoader();
setContent(modalContent);
} else {
setError('Content not available for this route');
}
} catch (err) {
setError('Failed to load content');
} finally {
setLoading(false);
}
};
// Content loaders for different routes
const loadLawyerCases = async (): Promise<ModalContent> => {
const response = await fetch('/api/lawyer/cases');
const data = await response.json();
return {
title: 'My Cases',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Cases</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View All
</button>
</div>
<div className="space-y-3">
{data.cases?.slice(0, 5).map((case_: any) => (
<div key={case_.id} className="border rounded-lg p-4 hover:bg-gray-50">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">{case_.title}</h4>
<p className="text-sm text-gray-600">{case_.status}</p>
</div>
<span className={
case_.status === 'ACTIVE' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
}
{case_.status}
</span>
</div>
</div>
))}
</div>
</div>
)
};
};
const loadConsultations = async (): Promise<ModalContent> => {
return {
title: 'Consultations',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">Upcoming Consultations</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Schedule New
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Client Consultation</h4>
<p className="text-sm text-gray-600">Tomorrow at 2:00 PM</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">
Scheduled
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadTeam = async (): Promise<ModalContent> => {
return {
title: 'Team Management',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Team</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Add Member
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">John Smith</h4>
<p className="text-sm text-gray-600">Associate Lawyer</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Active
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadCalendar = async (): Promise<ModalContent> => {
return {
title: 'Calendar',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">Today's Schedule</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Add Event
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Court Hearing</h4>
<p className="text-sm text-gray-600">10:00 AM - 11:00 AM</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-red-100 text-red-800">
Urgent
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadAnalytics = async (): Promise<ModalContent> => {
return {
title: 'Analytics',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">Performance Overview</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View Details
</button>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="border rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-blue-600">85%</div>
<div className="text-sm text-gray-600">Win Rate</div>
</div>
<div className="border rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-green-600">24</div>
<div className="text-sm text-gray-600">Active Cases</div>
</div>
</div>
</div>
)
};
};
const loadClients = async (): Promise<ModalContent> => {
return {
title: 'My Clients',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">Client List</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Add Client
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Sarah Johnson</h4>
<p className="text-sm text-gray-600">Civil Litigation</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Active
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadProfile = async (): Promise<ModalContent> => {
return {
title: 'Profile',
component: (
<div className="space-y-4">
<div className="text-center">
<div className="w-20 h-20 bg-gray-300 rounded-full mx-auto mb-4"></div>
<h3 className="text-lg font-semibold">{session?.user?.name}</h3>
<p className="text-gray-600">{session?.user?.email}</p>
</div>
<div className="space-y-3">
<button className="w-full text-left p-3 border rounded-lg hover:bg-gray-50">
Edit Profile
</button>
<button className="w-full text-left p-3 border rounded-lg hover:bg-gray-50">
Change Password
</button>
<button className="w-full text-left p-3 border rounded-lg hover:bg-gray-50">
Notification Settings
</button>
</div>
</div>
)
};
};
// Client dashboard content loaders
const loadClientCases = async (): Promise<ModalContent> => {
const response = await fetch('/api/client/cases');
const data = await response.json();
return {
title: 'My Cases',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Cases</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View All
</button>
</div>
<div className="space-y-3">
{data.cases?.slice(0, 5).map((case_: any) => (
<div key={case_.id} className="border rounded-lg p-4 hover:bg-gray-50">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">{case_.title}</h4>
<p className="text-sm text-gray-600">{case_.status}</p>
</div>
<span className={
case_.status === 'ACTIVE' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
}
{case_.status}
</span>
</div>
</div>
))}
</div>
</div>
)
};
};
const loadDocuments = async (): Promise<ModalContent> => {
return {
title: 'Documents',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Documents</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Upload New
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Legal Document.pdf</h4>
<p className="text-sm text-gray-600">Uploaded 2 days ago</p>
</div>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Download
</button>
</div>
</div>
</div>
</div>
)
};
};
const loadPayments = async (): Promise<ModalContent> => {
return {
title: 'Payments',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">Payment History</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Make Payment
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Legal Services</h4>
<p className="text-sm text-gray-600">$500.00</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Paid
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadClientMessagesModal = async (): Promise<ModalContent> => {
return {
title: 'Messages',
component: (
<div className="max-w-4xl mx-auto px-4 py-8">
<MessagesPage />
</div>
)
};
};
// Admin dashboard content loaders
const loadUsers = async (): Promise<ModalContent> => {
return {
title: 'User Management',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">All Users</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Add User
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">John Doe</h4>
<p className="text-sm text-gray-600">Client</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Active
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadAdminCases = async (): Promise<ModalContent> => {
return {
title: 'Case Management',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">All Cases</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Create Case
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Bordeaux Prison Case</h4>
<p className="text-sm text-gray-600">Active</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Active
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadRegistrations = async (): Promise<ModalContent> => {
return {
title: 'Registrations',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">All Registrations</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View All
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Case Registration</h4>
<p className="text-sm text-gray-600">Pending Review</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadAdminAnalytics = async (): Promise<ModalContent> => {
return {
title: 'Admin Analytics',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">System Overview</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Export Report
</button>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="border rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-blue-600">1,234</div>
<div className="text-sm text-gray-600">Total Users</div>
</div>
<div className="border rounded-lg p-4 text-center">
<div className="text-2xl font-bold text-green-600">567</div>
<div className="text-sm text-gray-600">Active Cases</div>
</div>
</div>
</div>
)
};
};
const loadSettings = async (): Promise<ModalContent> => {
return {
title: 'Settings',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">System Settings</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Save Changes
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-center">
<div>
<h4 className="font-medium">Email Notifications</h4>
<p className="text-sm text-gray-600">Enable email alerts</p>
</div>
<input type="checkbox" className="rounded" defaultChecked />
</div>
</div>
</div>
</div>
)
};
};
const loadLawyerApplications = async (): Promise<ModalContent> => {
return {
title: 'My Applications',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Applications</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View All
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Bordeaux Prison Case</h4>
<p className="text-sm text-gray-600">Submitted 2 days ago</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadClientApplications = async (): Promise<ModalContent> => {
return {
title: 'My Applications',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">My Applications</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
View All
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Legal Consultation</h4>
<p className="text-sm text-gray-600">Submitted 1 day ago</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Approved
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadClientApplicationsFull = async (): Promise<ModalContent> => {
return {
title: 'All Applications',
component: (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-semibold">All Applications</h3>
<button className="text-blue-600 hover:text-blue-800 text-sm">
Create New
</button>
</div>
<div className="space-y-3">
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Legal Consultation</h4>
<p className="text-sm text-gray-600">Submitted 1 day ago</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">
Approved
</span>
</div>
</div>
<div className="border rounded-lg p-4">
<div className="flex justify-between items-start">
<div>
<h4 className="font-medium">Case Review</h4>
<p className="text-sm text-gray-600">Submitted 3 days ago</p>
</div>
<span className="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">
Pending
</span>
</div>
</div>
</div>
</div>
)
};
};
const loadNewCaseModal = async (): Promise<ModalContent> => {
return {
title: 'Create New Case',
component: (
<div className="space-y-4">
<NewCaseForm />
</div>
)
};
};
if (!isOpen) return null;
return (
<AnimatePresence>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
onClick={onClose}
>
<motion.div
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0.9, opacity: 0 }}
className="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-hidden"
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="flex items-center justify-between p-6 border-b">
<div className="flex items-center space-x-3">
<button
onClick={onClose}
className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
>
<X className="h-5 w-5" />
</button>
<h2 className="text-xl font-semibold">
{title || content?.title || 'Dashboard'}
</h2>
</div>
</div>
{/* Content */}
<div className="p-6 overflow-y-auto max-h-[calc(90vh-120px)]">
{loading ? (
<div className="flex items-center justify-center py-8">
<Loader2 className="h-8 w-8 animate-spin text-blue-600" />
<span className="ml-2 text-gray-600">Loading...</span>
</div>
) : error ? (
<div className="text-center py-8">
<div className="text-red-600 mb-2">⚠️</div>
<p className="text-gray-600">{error}</p>
<button
onClick={loadModalContent}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
Try Again
</button>
</div>
) : content ? (
content.component
) : (
<div className="text-center py-8">
<FileText className="h-12 w-12 text-gray-400 mx-auto mb-4" />
<p className="text-gray-600">No content available</p>
</div>
)}
</div>
</motion.div>
</motion.div>
</AnimatePresence>
);
};
export default DashboardModal;