![]() 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/backups/lavocat.quebec/backup-20250730-021618/src/pages/profiles/ |
import React, { useState, useEffect } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import Image from 'next/image';
import { motion } from 'framer-motion';
import { Star, Badge, DollarSign, Award, Users, TrendingUp } from 'lucide-react';
import LayoutWithSidebar from '../../components/LayoutWithSidebar';
import ImageModal from '@/components/ui/ImageModal';
import LawyerRatingStars from '../../components/LawyerRatingStars';
import EnhancedShareButton from '../../components/EnhancedShareButton';
interface SocietyDegree {
id: string;
degreeNumber: number;
name: string;
title: string;
track: string;
symbol: string;
color: string;
lodgeLevel: string;
isSecret: boolean;
}
interface UserDegree {
id: string;
achievedAt: string;
ceremonyCompleted: boolean;
progressPercentage: number;
degree: SocietyDegree;
}
interface Lodge {
id: string;
name: string;
track: string;
lodgeLevel: string;
isSecret: boolean;
}
interface LodgeMembership {
id: string;
role: string;
isActive: boolean;
joinedDate: string;
lodge: Lodge;
}
interface PublicProfile {
id: string;
username?: string;
name: string;
email: string;
role: string;
profilePicture?: string;
bio?: string;
title?: string;
specialization?: string;
yearsOfExperience?: number;
officeLocation?: string;
availability?: string;
// NEW: Lawyer-specific fields
hourlyRate?: number;
proBono?: boolean;
averageRating?: number;
totalCases?: number;
wonCases?: number;
isVerified?: boolean;
xpPoints?: number;
level?: number;
// NEW: Society fields
degrees?: UserDegree[];
lodgeMemberships?: LodgeMembership[];
reviewsWritten?: number;
forumPosts?: number;
helpedOthers?: number;
observationHours?: number;
reformProposals?: number;
wisdomScore?: number;
civicEngagement?: number;
}
const ProfilesDirectory: React.FC = () => {
const [profiles, setProfiles] = useState<PublicProfile[]>([]);
const [loading, setLoading] = useState(true);
const [filter, setFilter] = useState('all');
const [selectedImage, setSelectedImage] = useState<{
src: string;
alt: string;
title: string;
} | null>(null);
useEffect(() => {
fetchProfiles();
}, []);
const fetchProfiles = async () => {
try {
const response = await fetch('/api/public/profiles');
if (response.ok) {
const data = await response.json();
setProfiles(data);
}
} catch (error) {
console.error('Error fetching profiles:', error);
} finally {
setLoading(false);
}
};
const getRoleIcon = (role: string, email?: string) => {
// Danny is the Class Action Representative
if (email === 'dannywperez@msn.com' || email === 'support@gositeme.com') {
return 'ποΈ';
}
switch (role) {
case 'SUPERADMIN':
return 'π';
case 'ADMIN':
return 'π©ββοΈ';
case 'JUDGE':
return 'βοΈ';
case 'LAWYER':
return 'βοΈ';
case 'JURIST':
return 'π';
case 'MEDIATOR':
return 'π€';
case 'LEGAL_CONSULTANT':
return 'πΌ';
case 'INVESTIGATOR':
return 'π';
case 'EXPERT_WITNESS':
return 'π';
case 'SECRETARY':
return 'π';
case 'ASSISTANT':
return 'π€';
case 'CLERK':
return 'π';
case 'COURT_CLERK':
return 'ποΈ';
case 'LAW_STUDENT':
return 'π';
case 'LEGAL_INTERN':
return 'π';
case 'NOTARY':
return 'ποΈ';
case 'PARALEGAL':
return 'π';
case 'BUSINESS':
return 'π’';
case 'USER':
return 'π€';
default:
return 'π€';
}
};
const getRoleName = (role: string, email?: string) => {
// Danny is the Class Action Representative
if (email === 'dannywperez@msn.com' || email === 'support@gositeme.com') {
return 'Class Action Representative';
}
switch (role) {
case 'SUPERADMIN':
return 'System Administrator';
case 'ADMIN':
return 'Legal Team';
case 'JUDGE':
return 'Judge';
case 'LAWYER':
return 'Legal Counsel';
case 'JURIST':
return 'Jurist';
case 'MEDIATOR':
return 'Mediator';
case 'LEGAL_CONSULTANT':
return 'Legal Consultant';
case 'INVESTIGATOR':
return 'Investigator';
case 'EXPERT_WITNESS':
return 'Expert Witness';
case 'SECRETARY':
return 'Legal Secretary';
case 'ASSISTANT':
return 'Legal Assistant';
case 'CLERK':
return 'Law Clerk';
case 'COURT_CLERK':
return 'Court Clerk';
case 'LAW_STUDENT':
return 'Law Student';
case 'LEGAL_INTERN':
return 'Legal Intern';
case 'NOTARY':
return 'Notary Public';
case 'PARALEGAL':
return 'Paralegal';
case 'BUSINESS':
return 'Business';
case 'USER':
return 'Client';
default:
return 'Community Member';
}
};
const getStatusColor = (availability?: string) => {
switch (availability) {
case 'Available':
return 'bg-green-400';
case 'Busy':
return 'bg-yellow-400';
case 'Away':
return 'bg-orange-400';
case 'Do Not Disturb':
return 'bg-red-400';
default:
return 'bg-gray-400';
}
};
const getInitials = (name: string) => {
return name
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase()
.slice(0, 2);
};
// Role filter logic
const roleFilters = [
{ key: 'all', label: `All (${profiles.length})` },
{ key: 'judicial', label: `Judicial (${profiles.filter(p => ['JUDGE', 'COURT_CLERK'].includes(p.role)).length})` },
{ key: 'lawyers', label: `Lawyers (${profiles.filter(p => ['LAWYER', 'ADMIN', 'SUPERADMIN'].includes(p.role)).length})` },
{ key: 'specialists', label: `Specialists (${profiles.filter(p => ['MEDIATOR', 'LEGAL_CONSULTANT', 'INVESTIGATOR', 'EXPERT_WITNESS', 'NOTARY'].includes(p.role)).length})` },
{ key: 'support', label: `Support Staff (${profiles.filter(p => ['SECRETARY', 'ASSISTANT', 'CLERK', 'PARALEGAL'].includes(p.role)).length})` },
{ key: 'students', label: `Students (${profiles.filter(p => ['LAW_STUDENT', 'LEGAL_INTERN'].includes(p.role)).length})` },
{ key: 'clients', label: `Clients (${profiles.filter(p => p.role === 'USER').length})` },
{ key: 'business', label: `Business (${profiles.filter(p => p.role === 'BUSINESS').length})` },
];
const filteredProfiles = profiles.filter(profile => {
if (filter === 'all') return true;
if (filter === 'judicial') return ['JUDGE', 'COURT_CLERK'].includes(profile.role);
if (filter === 'lawyers') return ['LAWYER', 'ADMIN', 'SUPERADMIN'].includes(profile.role);
if (filter === 'specialists') return ['MEDIATOR', 'LEGAL_CONSULTANT', 'INVESTIGATOR', 'EXPERT_WITNESS', 'NOTARY'].includes(profile.role);
if (filter === 'support') return ['SECRETARY', 'ASSISTANT', 'CLERK', 'PARALEGAL'].includes(profile.role);
if (filter === 'students') return ['LAW_STUDENT', 'LEGAL_INTERN'].includes(profile.role);
if (filter === 'clients') return profile.role === 'USER';
if (filter === 'business') return profile.role === 'BUSINESS';
return true;
});
const lawyers = profiles.filter(p => ['LAWYER', 'ADMIN', 'SUPERADMIN', 'JUDGE'].includes(p.role));
const clients = profiles.filter(p => p.role === 'USER');
const openImageModal = (profile: PublicProfile) => {
if (profile.profilePicture) {
setSelectedImage({
src: profile.profilePicture,
alt: profile.name,
title: profile.name
});
}
};
const closeImageModal = () => {
setSelectedImage(null);
};
if (loading) {
return (
<LayoutWithSidebar>
<div className="flex items-center justify-center min-h-96">
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-purple-600"></div>
</div>
</LayoutWithSidebar>
);
}
return (
<LayoutWithSidebar>
<Head>
<title>Our Team - LibertΓ© MΓͺme en Prison</title>
<meta name="description" content="Meet our legal team and community members at LibertΓ© MΓͺme en Prison" />
<meta property="og:title" content="Our Team - LibertΓ© MΓͺme en Prison" />
<meta property="og:description" content="Meet our legal team and community members" />
</Head>
<div className="space-y-6">
{/* Quick Navigation */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1 }}
className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-blue-900/20 dark:to-purple-900/20 rounded-xl p-6 border border-blue-200 dark:border-blue-800 mb-8"
>
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-4 flex items-center">
ποΈ Judicial Ecosystem Navigation
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Link
href="/judicial-directory"
className="flex items-center space-x-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm hover:shadow-md transition-all duration-200 group"
>
<div className="w-10 h-10 bg-blue-100 dark:bg-blue-900/30 rounded-lg flex items-center justify-center group-hover:scale-110 transition-transform">
<span className="text-blue-600 text-lg">βοΈ</span>
</div>
<div>
<div className="font-medium text-gray-900 dark:text-white group-hover:text-blue-600 transition-colors">
Judicial Directory
</div>
<div className="text-sm text-gray-500 dark:text-gray-400">
Legal professionals & expertise
</div>
</div>
</Link>
<Link
href="/business-profiles"
className="flex items-center space-x-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm hover:shadow-md transition-all duration-200 group"
>
<div className="w-10 h-10 bg-purple-100 dark:bg-purple-900/30 rounded-lg flex items-center justify-center group-hover:scale-110 transition-transform">
<span className="text-purple-600 text-lg">π’</span>
</div>
<div>
<div className="font-medium text-gray-900 dark:text-white group-hover:text-purple-600 transition-colors">
Law Firms & Businesses
</div>
<div className="text-sm text-gray-500 dark:text-gray-400">
Professional organizations
</div>
</div>
</Link>
<Link
href="/profiles"
className="flex items-center space-x-3 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm hover:shadow-md transition-all duration-200 group border-2 border-blue-500"
>
<div className="w-10 h-10 bg-green-100 dark:bg-green-900/30 rounded-lg flex items-center justify-center group-hover:scale-110 transition-transform">
<span className="text-green-600 text-lg">π₯</span>
</div>
<div>
<div className="font-medium text-gray-900 dark:text-white group-hover:text-green-600 transition-colors">
Society Members
</div>
<div className="text-sm text-gray-500 dark:text-gray-400">
Community directory
</div>
</div>
</Link>
</div>
</motion.div>
{/* Header */}
<div className="mb-8">
<h1 className="text-4xl font-bold text-gray-900 dark:text-white mb-4">
π₯ Society Members Directory
</h1>
<p className="text-xl text-gray-600 dark:text-gray-400">
Discover our community of legal professionals and justice seekers, each with their unique expertise,
society degrees, and contributions to our judicial ecosystem
</p>
</div>
{/* Ecosystem Stats */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
className="grid grid-cols-2 md:grid-cols-4 gap-4"
>
<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-sm border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">Total Members</p>
<p className="text-2xl font-bold text-gray-900 dark:text-white">{profiles.length}</p>
</div>
<div className="w-8 h-8 bg-blue-100 dark:bg-blue-900/30 rounded-lg flex items-center justify-center">
<span className="text-blue-600 text-sm">π₯</span>
</div>
</div>
</div>
<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-sm border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">Legal Professionals</p>
<p className="text-2xl font-bold text-gray-900 dark:text-white">
{profiles.filter(p => ['LAWYER', 'ADMIN', 'SUPERADMIN', 'JUDGE', 'JURIST', 'MEDIATOR', 'LEGAL_CONSULTANT'].includes(p.role)).length}
</p>
</div>
<div className="w-8 h-8 bg-purple-100 dark:bg-purple-900/30 rounded-lg flex items-center justify-center">
<span className="text-purple-600 text-sm">βοΈ</span>
</div>
</div>
</div>
<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-sm border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">Support Staff</p>
<p className="text-2xl font-bold text-gray-900 dark:text-white">
{profiles.filter(p => ['SECRETARY', 'ASSISTANT', 'CLERK', 'PARALEGAL', 'COURT_CLERK'].includes(p.role)).length}
</p>
</div>
<div className="w-8 h-8 bg-green-100 dark:bg-green-900/30 rounded-lg flex items-center justify-center">
<span className="text-green-600 text-sm">π€</span>
</div>
</div>
</div>
<div className="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-sm border border-gray-200 dark:border-gray-700">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-600 dark:text-gray-400">Clients</p>
<p className="text-2xl font-bold text-gray-900 dark:text-white">
{profiles.filter(p => p.role === 'USER').length}
</p>
</div>
<div className="w-8 h-8 bg-orange-100 dark:bg-orange-900/30 rounded-lg flex items-center justify-center">
<span className="text-orange-600 text-sm">π€</span>
</div>
</div>
</div>
</motion.div>
{/* Filter Tabs */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
className="flex justify-center"
>
<div className="bg-white rounded-lg shadow-sm border border-gray-200 p-1 flex flex-wrap gap-2">
{roleFilters.map((tab) => (
<button
key={tab.key}
onClick={() => setFilter(tab.key)}
className={`px-4 py-2 rounded-md font-medium text-sm transition-colors ${
filter === tab.key
? 'bg-purple-600 text-white'
: 'text-gray-600 hover:text-gray-900'
}`}
>
{tab.label}
</button>
))}
</div>
</motion.div>
{/* Profiles Grid */}
{filteredProfiles.length === 0 ? (
<div className="text-center py-12">
<p className="text-gray-500 text-lg">No public profiles found.</p>
</div>
) : (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.4 }}
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"
>
{filteredProfiles.map((profile, index) => (
<motion.div
key={profile.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1 * index }}
whileHover={{ y: -5, scale: 1.02 }}
className="bg-white rounded-xl shadow-lg hover:shadow-2xl transition-all duration-300 overflow-hidden border border-gray-100 cursor-pointer group"
onClick={() => profile.username && window.open(`/profile/${profile.username}`, '_blank')}
>
<div className="p-6">
{/* Profile Header */}
<div className="flex items-center space-x-4 mb-4">
<div className="relative">
{profile.profilePicture ? (
<div
className="cursor-pointer hover:opacity-80 transition-opacity group relative"
onClick={(e) => {
e.stopPropagation();
openImageModal(profile);
}}
title="Click to view full size"
>
<Image
src={profile.profilePicture}
alt={profile.name}
width={64}
height={64}
className="rounded-full object-cover group-hover:scale-110 transition-transform"
/>
{/* Mobile-friendly overlay */}
<div className="absolute inset-0 rounded-full bg-black bg-opacity-0 group-hover:bg-opacity-20 transition-all duration-200 flex items-center justify-center">
<div className="opacity-0 group-hover:opacity-100 transition-opacity">
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" />
</svg>
</div>
</div>
</div>
) : (
<div className="w-16 h-16 rounded-full bg-gradient-to-r from-blue-500 to-purple-600 flex items-center justify-center text-white font-semibold text-lg group-hover:scale-110 transition-transform">
{getInitials(profile.name)}
</div>
)}
{/* Status Indicator */}
<div className={`absolute -bottom-1 -right-1 w-5 h-5 ${getStatusColor(profile.availability)} rounded-full border-2 border-white`}></div>
</div>
<div className="flex-1">
<h3 className="text-lg font-semibold text-gray-900 flex items-center group-hover:text-blue-600 transition-colors">
{profile.name}
<span className="ml-2 text-base">{getRoleIcon(profile.role, profile.email)}</span>
</h3>
{profile.title && (
<p className="text-sm text-purple-600 font-medium">{profile.title}</p>
)}
<p className="text-xs text-gray-500">{getRoleName(profile.role, profile.email)}</p>
{/* Share Button */}
<div className="mt-2">
<EnhancedShareButton
url={profile.username ? `${typeof window !== 'undefined' ? window.location.origin : ''}/profile/${profile.username}` : ''}
title={profile.name}
description={profile.bio || `Professional profile of ${profile.name}`}
hashtags={['profile', 'legal', profile.role.toLowerCase()]}
variant="minimal"
/>
</div>
</div>
{profile.username && (
<div className="opacity-0 group-hover:opacity-100 transition-opacity">
<span className="text-blue-600 text-sm">ποΈ View Profile</span>
</div>
)}
</div>
{/* Profile Info */}
<div className="space-y-3">
{/* Universal fields for all roles */}
<div className="flex items-center space-x-2">
<span className="text-gray-400">π§</span>
<span className="text-sm text-gray-600">{profile.email}</span>
</div>
{profile.officeLocation && (
<div className="flex items-center space-x-2">
<span className="text-gray-400">π</span>
<span className="text-sm text-gray-600">{profile.officeLocation}</span>
</div>
)}
{/* Role-specific fields */}
{profile.role === 'LAWYER' && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">π―</span>
<span className="text-sm text-gray-600">{profile.specialization || 'N/A'}</span>
</div>
<div className="flex items-center space-x-2">
<span className="text-gray-400">π</span>
<span className="text-sm text-gray-600">{profile.yearsOfExperience ? `${profile.yearsOfExperience} years experience` : 'N/A'}</span>
</div>
<div className="flex items-center space-x-2">
<span className="text-gray-400">πΌ</span>
<span className="text-sm text-gray-600">{profile.hourlyRate ? `$${profile.hourlyRate}/hr` : 'N/A'}</span>
</div>
{/* Lawyer Stats */}
{profile.totalCases && profile.totalCases > 0 && (
<div className="grid grid-cols-2 gap-2 text-sm">
<div className="text-center p-2 bg-green-50 dark:bg-green-900/20 rounded">
<div className="font-bold text-green-600">
{profile.totalCases > 0 ? ((profile.wonCases || 0) / profile.totalCases * 100).toFixed(1) : 'N/A'}%
</div>
<div className="text-xs text-gray-600 dark:text-gray-400">Win Rate</div>
</div>
<div className="text-center p-2 bg-blue-50 dark:bg-blue-900/20 rounded">
<div className="font-bold text-blue-600">{profile.totalCases}</div>
<div className="text-xs text-gray-600 dark:text-gray-400">Cases</div>
</div>
</div>
)}
</>
)}
{['CLIENT','USER'].includes(profile.role) && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">π</span>
<span className="text-sm text-gray-600">Client</span>
</div>
</>
)}
{profile.role === 'BUSINESS' && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">π’</span>
<span className="text-sm text-gray-600">Business User</span>
</div>
</>
)}
{['SECRETARY','ASSISTANT','CLERK','PARALEGAL'].includes(profile.role) && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">ποΈ</span>
<span className="text-sm text-gray-600">{profile.role.charAt(0) + profile.role.slice(1).toLowerCase()}</span>
</div>
</>
)}
{profile.role === 'ADMIN' && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">βοΈ</span>
<span className="text-sm text-gray-600">Admin</span>
</div>
</>
)}
{(profile.role === 'SUPERADMIN' || profile.role === 'SUPERADMIN' || profile.role === 'SUPERADMIN' || profile.role === 'SUPERADMIN') && (
<>
<div className="flex items-center space-x-2">
<span className="text-gray-400">π</span>
<span className="text-sm text-gray-600">Super Admin</span>
</div>
</>
)}
{/* XP and Level for all roles if present */}
{profile.xpPoints && profile.xpPoints > 0 ? (
<div className="flex items-center justify-between text-xs">
<span className="flex items-center gap-1 text-purple-600">
<TrendingUp className="h-3 w-3" />
Level {profile.level || 1}
</span>
<span className="flex items-center gap-1 text-orange-600">
<Award className="h-3 w-3" />
{profile.xpPoints} XP
</span>
</div>
) : (
<div className="flex items-center justify-between text-xs text-gray-400">
<span className="flex items-center gap-1">
<TrendingUp className="h-3 w-3" />
Level N/A
</span>
<span className="flex items-center gap-1">
<Award className="h-3 w-3" />
No XP yet
</span>
</div>
)}
{profile.bio && (
<p className="text-sm text-gray-600 line-clamp-3">
{profile.bio}
</p>
)}
</div>
{/* Quick Action Buttons */}
{profile.username && (
<div className="mt-6 flex gap-2">
<button
onClick={(e) => {
e.stopPropagation();
window.open(`/profile/${profile.username}`, '_blank');
}}
className="flex-1 bg-gradient-to-r from-blue-500 to-purple-600 text-white px-4 py-2 rounded-lg font-medium hover:from-blue-600 hover:to-purple-700 transition-all"
>
π€ View Profile
</button>
{profile.role === 'LAWYER' && (
<button
onClick={(e) => {
e.stopPropagation();
window.open(`/hire?lawyer=${profile.username}`, '_blank');
}}
className="bg-green-600 text-white px-4 py-2 rounded-lg font-medium hover:bg-green-700 transition-colors"
>
πΌ Hire
</button>
)}
</div>
)}
</div>
</motion.div>
))}
</motion.div>
)}
{/* Call to Action */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.6 }}
className="mt-16 text-center bg-gradient-to-r from-purple-600 to-pink-600 rounded-2xl p-8 text-white"
>
<h2 className="text-3xl font-bold mb-4">Need Legal Assistance?</h2>
<p className="text-xl mb-6 opacity-90">
Our experienced legal team is here to help with your case
</p>
<Link
href="/contact"
className="inline-block bg-white text-purple-600 px-8 py-3 rounded-lg font-medium hover:bg-gray-100 transition-colors"
>
Contact Us Today
</Link>
</motion.div>
</div>
{/* Image Modal */}
{selectedImage && (
<ImageModal
isOpen={!!selectedImage}
onClose={closeImageModal}
imageSrc={selectedImage.src}
imageAlt={selectedImage.alt}
title={selectedImage.title}
/>
)}
</LayoutWithSidebar>
);
};
export default ProfilesDirectory;