T.ME/BIBIL_0DAY
CasperSecurity


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.ca/private_html/src/pages/user/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/private_html/src/pages/user/dashboard.tsx
import { useEffect, useState } from 'react';
import type { NextPage } from 'next';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/router';
import LayoutWithSidebar from '../../components/LayoutWithSidebar';
import { useRequireRole, USER_ROLES } from '../../lib/auth-utils';
import { format } from 'date-fns';
import RegistrationForm from '@/components/RegistrationForm';
import { motion, AnimatePresence } from 'framer-motion';
import Link from 'next/link';
import { useTheme } from '../../context/ThemeContext';
import RegistrationDetailModal from '../../components/RegistrationDetailModal';
import DocumentViewer from '@/components/DocumentViewer';
import dynamic from 'next/dynamic';
import toast from 'react-hot-toast';
import { useWebSocket } from '../../context/StableWebSocketContext';
import BarreauBadge from '../../components/BarreauBadge';
const PrivateChat = dynamic(() => import('@/components/Chat/PrivateChat'), { ssr: false });

interface Registration {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
  phone: string;
  detaineeInfo: {
    name: string;
    facility: string;
    inmateId: string;
  } | null;
  status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'MISSING_DOCUMENTS' | 'DOCUMENTS_UNDER_REVIEW' | 'ADDITIONAL_INFO_NEEDED' | 'VERIFICATION_IN_PROGRESS' | 'LAWYER_VERIFICATION' | 'FACILITY_VERIFICATION' | 'DOCUMENTS_EXPIRED' | 'DOCUMENTS_INCOMPLETE' | 'INFORMATION_MISMATCH' | 'PENDING_PAYMENT' | 'PAYMENT_RECEIVED' | 'PENDING_LAWYER_APPROVAL' | 'PENDING_FACILITY_APPROVAL' | 'ON_HOLD' | 'ESCALATED' | 'FINAL_REVIEW' | 'COMPLETED';
  createdAt: string;
  updatedAt: string;
  userId?: string;
  createdBy?: string;
  creator?: {
    id: string;
    email: string;
    name: string;
  };
  user?: {
    id: string;
    email: string;
    name: string;
  };
  documents?: {
    id: string;
    name: string;
    url: string;
    type: string;
  }[];
  reasonForJoining?: string;
  urgentNeeds?: string;
}

// Quebec detention facilities list
const QUEBEC_FACILITIES = {
  'ABITIBI-TÉMISCAMINGUE': [
    { id: 'amos', name: "Établissement de détention d'Amos" }
  ],
  'BAS-SAINT-LAURENT': [
    { id: 'rimouski', name: "Établissement de détention de Rimouski" }
  ],
  'CAPITALE-NATIONALE': [
    { id: 'quebec-femme', name: 'Établissement de détention de Québec – secteur féminin' },
    { id: 'quebec-homme', name: 'Établissement de détention de Québec – secteur masculin' }
  ],
  'CÔTE-NORD': [
    { id: 'baie-comeau', name: 'Établissement de détention de Baie-Comeau' },
    { id: 'sept-iles', name: 'Établissement de détention de Sept-Îles' }
  ],
  'ESTRIE': [
    { id: 'sherbrooke', name: 'Établissement de détention de Sherbrooke' }
  ],
  'GASPÉSIE-ÎLES-DE-LA-MADELEINE': [
    { id: 'new-carlisle', name: 'Établissement de détention de New Carlisle' },
    { id: 'perce', name: 'Établissement de détention de Percé' },
    { id: 'havre-aubert', name: 'Établissement de détention de Havre-Aubert' }
  ],
  'OUTAOUAIS': [
    { id: 'hull', name: 'Établissement de détention de Hull' }
  ],
  'LAURENTIDES': [
    { id: 'saint-jerome', name: 'Établissement de détention de Saint-Jérôme' }
  ],
  'LAVAL': [
    { id: 'leclerc', name: 'Établissement Leclerc de Laval' }
  ],
  'MAURICIE ET CENTRE-DU-QUÉBEC': [
    { id: 'trois-rivieres', name: 'Établissement de détention de Trois-Rivières' }
  ],
  'MONTEREGIE': [
    { id: 'sorel-tracy', name: 'Établissement de détention de Sorel-Tracy' }
  ],
  'MONTRÉAL': [
    { id: 'bordeaux', name: 'Établissement de détention de Montréal (Bordeaux)' },
    { id: 'riviere-des-prairies', name: 'Établissement de détention de Rivière-des-Prairies' }
  ],
  'SAGUENAY–LAC-SAINT-JEAN': [
    { id: 'roberval', name: 'Établissement de détention de Roberval' }
  ]
};

function getFacilityName(facilityId: string) {
  for (const region of Object.values(QUEBEC_FACILITIES)) {
    const facility = region.find(f => f.id === facilityId);
    if (facility) return facility.name;
  }
  return facilityId;
}

// Add status helpers at the top
const getStatusColor = (status: string) => {
  switch (status) {
    case 'APPROVED':
    case 'COMPLETED':
    case 'PAYMENT_RECEIVED':
      return 'bg-green-100 text-green-800';
    case 'REJECTED':
    case 'DOCUMENTS_EXPIRED':
    case 'INFORMATION_MISMATCH':
    case 'ESCALATED':
      return 'bg-red-100 text-red-800';
    case 'PENDING':
    case 'ADDITIONAL_INFO_NEEDED':
    case 'PENDING_PAYMENT':
      return 'bg-yellow-100 text-yellow-800';
    case 'MISSING_DOCUMENTS':
    case 'DOCUMENTS_INCOMPLETE':
      return 'bg-orange-100 text-orange-800';
    case 'DOCUMENTS_UNDER_REVIEW':
    case 'PENDING_LAWYER_APPROVAL':
    case 'PENDING_FACILITY_APPROVAL':
      return 'bg-blue-100 text-blue-800';
    case 'VERIFICATION_IN_PROGRESS':
    case 'FINAL_REVIEW':
      return 'bg-purple-100 text-purple-800';
    case 'ON_HOLD':
      return 'bg-gray-100 text-gray-800';
    case 'WebAd':
      return 'bg-pink-100 text-pink-800';
    default:
      return 'bg-yellow-100 text-yellow-800';
  }
};

const getStatusLabel = (status: string) => {
  const statusMap: { [key: string]: string } = {
    PENDING: 'Pending',
    APPROVED: 'Approved',
    REJECTED: 'Rejected',
    MISSING_DOCUMENTS: 'Missing Documents',
    DOCUMENTS_UNDER_REVIEW: 'Documents Under Review',
    ADDITIONAL_INFO_NEEDED: 'Additional Info Needed',
    VERIFICATION_IN_PROGRESS: 'Verification in Progress',
    LAWYER_VERIFICATION: 'Lawyer Verification',
    FACILITY_VERIFICATION: 'Facility Verification',
    DOCUMENTS_EXPIRED: 'Documents Expired',
    DOCUMENTS_INCOMPLETE: 'Documents Incomplete',
    INFORMATION_MISMATCH: 'Information Mismatch',
    PENDING_PAYMENT: 'Pending Payment',
    PAYMENT_RECEIVED: 'Payment Received',
    PENDING_LAWYER_APPROVAL: 'Pending Lawyer Approval',
    PENDING_FACILITY_APPROVAL: 'Pending Facility Approval',
    ON_HOLD: 'On Hold',
    ESCALATED: 'Escalated',
    FINAL_REVIEW: 'Final Review',
    COMPLETED: 'Completed'
  };
  return statusMap[status] || status;
};

const getStatusEncouragement = (status: string) => {
  const encouragementMap: { [key: string]: string } = {
    PENDING: 'Your application is being reviewed. We will contact you soon.',
    APPROVED: 'Congratulations! Your application has been approved.',
    REJECTED: 'We\'re sorry, but your application has been rejected. Please contact us for more information.',
    MISSING_DOCUMENTS: 'Please upload the required documents to proceed.',
    DOCUMENTS_UNDER_REVIEW: 'Your documents are being reviewed. We will contact you if additional information is needed.',
    ADDITIONAL_INFO_NEEDED: 'Please provide the additional information requested.',
    VERIFICATION_IN_PROGRESS: 'Your information is being verified. This may take a few days.',
    LAWYER_VERIFICATION: 'Your application is being reviewed by our legal team.',
    FACILITY_VERIFICATION: 'We are verifying the facility information.',
    DOCUMENTS_EXPIRED: 'Some of your documents have expired. Please upload updated versions.',
    DOCUMENTS_INCOMPLETE: 'Please complete your document uploads.',
    INFORMATION_MISMATCH: 'There is a discrepancy in the information provided. Please review and update.',
    PENDING_PAYMENT: 'Please complete the payment process to continue.',
    PAYMENT_RECEIVED: 'Payment received. Your application is being processed.',
    PENDING_LAWYER_APPROVAL: 'Your application is awaiting lawyer approval.',
    PENDING_FACILITY_APPROVAL: 'Your application is awaiting facility approval.',
    ON_HOLD: 'Your application is temporarily on hold. We will contact you soon.',
    ESCALATED: 'Your application has been escalated for review.',
    FINAL_REVIEW: 'Your application is in final review.',
    COMPLETED: 'Your application has been completed successfully.'
  };
  return encouragementMap[status] || '';
};

// Enhanced status icon component with animations for ALL statuses
const StatusIcon = ({ status }: { status: string }) => {
  const iconMap: { [key: string]: JSX.Element } = {
    // Primary statuses with enhanced animations
    APPROVED: (
      <div className="relative">
        <div className="w-8 h-8 bg-green-500 rounded-full flex items-center justify-center">
          <svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
          </svg>
        </div>
        <div className="absolute -inset-1 bg-green-400 rounded-full animate-ping opacity-20"></div>
      </div>
    ),
    COMPLETED: (
      <div className="relative">
        <div className="w-8 h-8 bg-emerald-600 rounded-full flex items-center justify-center">
          <svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
          </svg>
        </div>
        <div className="absolute -inset-1 bg-emerald-500 rounded-full animate-ping opacity-20"></div>
      </div>
    ),
    REJECTED: (
      <div className="w-8 h-8 bg-red-500 rounded-full flex items-center justify-center">
        <svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
        </svg>
      </div>
    ),
    PENDING: (
      <div className="relative">
        <div className="animate-spin w-8 h-8 border-2 border-amber-500 border-t-transparent rounded-full"></div>
        <div className="absolute inset-0 flex items-center justify-center">
          <div className="w-3 h-3 bg-amber-500 rounded-full animate-pulse"></div>
        </div>
      </div>
    ),
    
    // Document-related statuses
    MISSING_DOCUMENTS: <span className="text-orange-500 text-2xl">📄❗</span>,
    DOCUMENTS_UNDER_REVIEW: <span className="text-blue-500 text-2xl">📄🔍</span>,
    DOCUMENTS_EXPIRED: <span className="text-red-500 text-2xl">📄⏰</span>,
    DOCUMENTS_INCOMPLETE: <span className="text-orange-600 text-2xl">📄⚠️</span>,
    
    // Review and verification statuses
    ADDITIONAL_INFO_NEEDED: <span className="text-yellow-600 text-2xl">❓📝</span>,
    VERIFICATION_IN_PROGRESS: <span className="text-purple-500 text-2xl">🔍✨</span>,
    LAWYER_VERIFICATION: <span className="text-indigo-600 text-2xl">⚖️👨‍💼</span>,
    FACILITY_VERIFICATION: <span className="text-blue-600 text-2xl">🏢🔍</span>,
    INFORMATION_MISMATCH: <span className="text-red-600 text-2xl">❌📊</span>,
    
    // Payment statuses
    PENDING_PAYMENT: <span className="text-yellow-500 text-2xl">💳⏳</span>,
    PAYMENT_RECEIVED: <span className="text-green-600 text-2xl">💳✅</span>,
    
    // Approval statuses
    PENDING_LAWYER_APPROVAL: <span className="text-indigo-500 text-2xl">⚖️⏳</span>,
    PENDING_FACILITY_APPROVAL: <span className="text-blue-400 text-2xl">🏢⏳</span>,
    
    // Process statuses
    ON_HOLD: <span className="text-gray-500 text-2xl">⏸️📋</span>,
    ESCALATED: <span className="text-red-700 text-2xl">🚨📈</span>,
    FINAL_REVIEW: <span className="text-purple-600 text-2xl">🏁🔍</span>,
  };
  return iconMap[status] || <span className="text-gray-400 text-2xl">📝</span>;
};

// Helper function to determine application type and display info
const getApplicationType = (registration: Registration, currentUserId?: string, currentUserEmail?: string) => {
  if (!currentUserId) return { type: 'unknown', label: 'Application', icon: '📝', description: '' };
  
  const isOwner = registration.userId === currentUserId;
  const isCreator = registration.createdBy === currentUserId;
  const isEmailMatch = registration.email === currentUserEmail && registration.userId === null;
  
  if (isOwner && isCreator) {
    return {
      type: 'own',
      label: 'My Application',
      icon: '👤',
      description: '',
      bgColor: 'bg-blue-50 border-blue-200',
      textColor: 'text-blue-800'
    };
  } else if (isCreator && !isOwner) {
    return {
      type: 'created-for-other',
      label: `Application for ${registration.firstName} ${registration.lastName}`,
      icon: '👥',
      description: `You created this application for ${registration.email}`,
      bgColor: 'bg-purple-50 border-purple-200',
      textColor: 'text-purple-800'
    };
  } else if (isOwner && !isCreator) {
    return {
      type: 'created-by-other',
      label: 'My Application',
      icon: '🤝',
      description: registration.creator ? `Originally created by ${registration.creator.name || registration.creator.email}` : 'Created by someone else for you',
      bgColor: 'bg-green-50 border-green-200',
      textColor: 'text-green-800'
    };
  } else if (isEmailMatch) {
    return {
      type: 'email-match',
      label: 'My Application',
      icon: '📧',
      description: 'Linked by email match',
      bgColor: 'bg-yellow-50 border-yellow-200',
      textColor: 'text-yellow-800'
    };
  }
  
  return {
    type: 'unknown',
    label: 'Application',
    icon: '❓',
    description: '',
    bgColor: 'bg-gray-50 border-gray-200',
    textColor: 'text-gray-800'
  };
};

const UserDashboard: NextPage = () => {
  const { data: session, status } = useSession();
  const router = useRouter();
  const { ws, connected, directMessageNotifications, getTotalUnreadDirectMessages } = useWebSocket();
  
  // Role-based access control - allow USER, CLIENT, ADMIN, SUPERADMIN to access user dashboard
  const { isAuthorized } = useRequireRole([
    USER_ROLES.USER, 
    USER_ROLES.CLIENT, 
    USER_ROLES.ADMIN, 
    USER_ROLES.SUPERADMIN
  ], '/');
  const [registrations, setRegistrations] = useState<Registration[]>([]);
  
  // Debug registrations state changes
  useEffect(() => {
    console.log('User Dashboard - Registrations state updated:', {
      count: registrations.length,
      registrations: registrations.map(r => ({ id: r.id, name: `${r.firstName} ${r.lastName}`, status: r.status }))
    });
  }, [registrations]);
  const [selectedRegistration, setSelectedRegistration] = useState<Registration | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [stats, setStats] = useState({
    total: 0,
    pending: 0,
    approved: 0,
    rejected: 0
  });
  const [showNewApplication, setShowNewApplication] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const { theme, setTheme } = useTheme();
  const [themes, setThemes] = useState<any[]>([]);
  const [themesLoading, setThemesLoading] = useState(false);
  const [themesError, setThemesError] = useState('');
  const [showModal, setShowModal] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<{
    url: string;
    type: string;
    name: string;
  } | null>(null);
  const [showPrivateChat, setShowPrivateChat] = useState<{ open: boolean; registrationId: string | null }>({ open: false, registrationId: null });

  // Mobile responsive states
  const [isMobile, setIsMobile] = useState(false);
  const [showMobileFilters, setShowMobileFilters] = useState(false);

  // Mobile detection
  useEffect(() => {
    const checkMobile = () => {
      const mobile = window.innerWidth < 768;
      setIsMobile(mobile);
    };

    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);

  // WebSocket status update and message listener
  useEffect(() => {
    if (!ws || !connected || !session?.user?.id) return;

    const handleMessage = (event: MessageEvent) => {
      try {
        const message = JSON.parse(event.data);
        
        if (message.type === 'STATUS_UPDATE' && message.data.userId === session.user.id) {
          const { statusLabel, registrationName, newStatus, registrationId } = message.data;
          
          // Update the registration in state
          setRegistrations(prev => prev.map(reg => 
            reg.id === registrationId 
              ? { ...reg, status: newStatus, updatedAt: new Date().toISOString() }
              : reg
          ));
          
          // Update stats
          fetchRegistrations();
          
          // Show toast notification
          toast.success(`📄 Application Status Updated: ${statusLabel}`, {
            duration: 5000,
            position: 'top-right',
            icon: '🔔',
          });
          
          // Show browser notification if permission granted
          if (Notification.permission === 'granted') {
            new Notification('Application Status Updated', {
              body: `Your application status has been updated to: ${statusLabel}`,
              icon: '/icons/apple-touch-icon-180x180.png'
            });
          }
          
          console.log(`[UserDashboard] ✅ Received status update: ${statusLabel} for registration ${registrationId}`);
        }
        
        // Handle private message notifications when chat is closed
        if (message.type === 'PRIVATE_MESSAGE' && message.data.sender.id !== session.user.id) {
          const isPrivateChatOpen = showPrivateChat.open && showPrivateChat.registrationId === message.data.registrationId;
          
          if (!isPrivateChatOpen) {
            // Show toast notification for new private message
            toast((t) => (
              <div className="flex items-center space-x-3">
                <div className="flex-shrink-0">
                  <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
                    <span className="text-white text-sm font-bold">
                      {message.data.sender.name?.charAt(0) || 'A'}
                    </span>
                  </div>
                </div>
                <div className="flex-1">
                  <p className="font-medium text-gray-900">
                    💬 New message from {message.data.sender.name || 'Admin'}
                  </p>
                  <p className="text-sm text-gray-600 truncate max-w-48">
                    {message.data.content}
                  </p>
                </div>
                <button
                  onClick={() => {
                    toast.dismiss(t.id);
                    setShowPrivateChat({ open: true, registrationId: message.data.registrationId });
                  }}
                  className="flex-shrink-0 bg-blue-500 text-white px-3 py-1 rounded text-sm hover:bg-blue-600"
                >
                  Reply
                </button>
              </div>
            ), {
              duration: 6000,
              position: 'top-right',
              style: {
                maxWidth: '400px',
              },
            });
            
            // Show browser notification
            if (Notification.permission === 'granted') {
              new Notification(`New message from ${message.data.sender.name || 'Admin'}`, {
                body: message.data.content,
                icon: '/icons/apple-touch-icon-180x180.png'
              });
            }
            
            console.log(`[UserDashboard] ✅ Received private message from ${message.data.sender.name}`);
          }
        }
      } catch (error) {
        console.error('[UserDashboard] ❌ Error parsing WebSocket message:', error);
      }
    };

    ws.addEventListener('message', handleMessage);
    return () => ws.removeEventListener('message', handleMessage);
  }, [ws, connected, session?.user?.id, showPrivateChat]);

  if (status === 'loading') {
    return (
      <LayoutWithSidebar>
        <div className="flex items-center justify-center min-h-screen">
          <div className="text-center">
            <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto"></div>
            <p className="mt-4 text-gray-600">Loading session...</p>
          </div>
        </div>
      </LayoutWithSidebar>
    );
  }

  // Request notification permission on mount
  useEffect(() => {
    if ('Notification' in window && Notification.permission === 'default') {
      Notification.requestPermission().then(permission => {
        console.log('[UserDashboard] Notification permission:', permission);
        if (permission === 'granted') {
          toast.success('🔔 Notifications enabled! You\'ll receive real-time updates.', {
            duration: 4000,
            position: 'top-right',
          });
        }
      });
    }
  }, []);

  useEffect(() => {
    console.log('User Dashboard - Session status:', status);
    console.log('User Dashboard - Session:', session);
    console.log('User Dashboard - Session user ID:', session?.user?.id);
    console.log('User Dashboard - Is authorized:', isAuthorized);
    
    if (status === 'unauthenticated') {
      console.log('User Dashboard - No session, redirecting to login');
      router.push('/auth/login');
      return;
    }
    
    if (status === 'authenticated' && session?.user?.id && isAuthorized) {
      console.log('User Dashboard - Session authenticated and authorized, fetching registrations');
      fetchRegistrations();
    }
  }, [session, status, router, isAuthorized]);

  const fetchRegistrations = async () => {
    try {
      console.log('User Dashboard - Starting to fetch registrations');
      console.log('User Dashboard - Session user ID before fetch:', session?.user?.id);
      
      setIsLoading(true);
      setError(null);
      
      const response = await fetch('/api/user/registrations', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'same-origin', // Ensure cookies are sent
      });
      
      console.log('User Dashboard - Response status:', response.status);
      console.log('User Dashboard - Response headers:', response.headers);
      
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        console.log('User Dashboard - Error response:', errorData);
        
        if (response.status === 401) {
          console.log('User Dashboard - Unauthorized, redirecting to login');
          router.push('/auth/login');
          return;
        }
        
        throw new Error(errorData.message || `Failed to fetch registrations (${response.status})`);
      }
      const data = await response.json();
      console.log('User Dashboard - Received data:', data);
      console.log('User Dashboard - Data type:', typeof data);
      console.log('User Dashboard - Is array:', Array.isArray(data));
      console.log('User Dashboard - Data length:', Array.isArray(data) ? data.length : 'N/A');
      
      // Ensure data is an array
      if (!Array.isArray(data)) {
        console.error('Expected array but got:', data);
        setError('Invalid data format received');
        setRegistrations([]);
        return;
      }

      console.log('User Dashboard - Setting registrations:', data);
      setRegistrations(data);

      // Calculate stats
      const newStats = {
        total: data.length,
        pending: data.filter((r: Registration) => r.status === 'PENDING').length,
        approved: data.filter((r: Registration) => r.status === 'APPROVED').length,
        rejected: data.filter((r: Registration) => r.status === 'REJECTED').length
      };
      setStats(newStats);
    } catch (err) {
      console.error('Error fetching registrations:', err);
      if (err instanceof Error && err.message.includes('401')) {
        router.push('/auth/login');
      } else {
        setError(`Error loading applications: ${err instanceof Error ? err.message : 'Unknown error'}`);
      }
      setRegistrations([]);
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    console.log('User Dashboard - Session status:', status);
    console.log('User Dashboard - Session user:', session?.user);
    console.log('User Dashboard - Session user ID:', session?.user?.id);
    console.log('User Dashboard - Session user role:', session?.user?.role);
    
    if (status === 'authenticated' && session?.user?.id) {
      console.log('User Dashboard - Fetching themes for user:', session.user.id);
      setThemesLoading(true);
      setThemesError('');
      
      fetch('/api/user/themes', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'same-origin', // Ensure cookies are sent
      })
        .then(res => {
          console.log('User Dashboard - Themes response status:', res.status);
          if (!res.ok) {
            if (res.status === 401) {
              console.log('User Dashboard - Themes unauthorized, redirecting to login');
              router.push('/auth/login');
              return;
            }
            throw new Error(`Failed to fetch themes (${res.status})`);
          }
          return res.json();
        })
        .then(data => {
          console.log('User Dashboard - Themes data:', data);
          if (Array.isArray(data)) {
            setThemes(
              data.map((theme: { colors: string | object }) => ({
                ...theme,
                colors: typeof theme.colors === 'string' ? JSON.parse(theme.colors) : theme.colors
              }))
            );
          } else {
            setThemes([]);
          }
        })
        .catch(error => {
          console.error('Error fetching themes:', error);
          if (!error.message.includes('401')) {
            setThemesError(`Error loading themes: ${error.message}`);
          }
          setThemes([]);
        })
        .finally(() => setThemesLoading(false));
    }
  }, [session?.user?.id, status, router]);

  const handleDeleteRegistration = async (id: string, e: React.MouseEvent) => {
    e.stopPropagation(); // Prevent row click
    if (!confirm('Are you sure you want to delete this application?')) {
      return;
    }

    setDeletingId(id);
    try {
      const response = await fetch(`/api/user/registrations/${id}`, {
        method: 'DELETE',
      });

      if (!response.ok) {
        throw new Error('Error deleting application');
      }

      // Remove the deleted registration from the state
      setRegistrations(prev => prev.filter(reg => reg.id !== id));
      
      // Update stats
      const updatedStats = {
        total: registrations.length - 1,
        pending: registrations.filter(r => r.status === 'PENDING' && r.id !== id).length,
        approved: registrations.filter(r => r.status === 'APPROVED' && r.id !== id).length,
        rejected: registrations.filter(r => r.status === 'REJECTED' && r.id !== id).length
      };
      setStats(updatedStats);
      
      toast.success('✅ Application deleted successfully', {
        duration: 3000,
        position: 'top-right',
      });
    } catch (err) {
      console.error('Error deleting application:', err);
      toast.error('❌ Failed to delete application', {
        duration: 4000,
        position: 'top-right',
      });
    } finally {
      setDeletingId(null);
    }
  };

  const handleApplyTheme = (colors: any) => {
    setTheme(colors);
  };

  const handleDeleteTheme = async (id: string) => {
    setDeletingId(id);
    try {
      await fetch('/api/user/themes', {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id }),
      });
      setThemes(themes.filter(t => t.id !== id));
    } catch {
      setThemesError('Failed to delete theme');
    } finally {
      setDeletingId(null);
    }
  };

  // Handler for successful registration
  const handleRegistrationSuccess = () => {
    setShowNewApplication(false);
    fetchRegistrations();
    toast.success('🎉 Application submitted successfully! You will receive updates via email and notifications.', {
      duration: 5000,
      position: 'top-right',
    });
  };

  const handleViewRegistration = (id: string) => {
    const reg = registrations.find(r => r.id === id);
    if (reg) setSelectedRegistration(reg);
  };

  if (isLoading) {
    return (
      <LayoutWithSidebar>
        <div className="flex items-center justify-center min-h-screen">
          <div className="text-center">
            <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto"></div>
            <p className="mt-4 text-gray-600">Loading...</p>
          </div>
        </div>
      </LayoutWithSidebar>
    );
  }

  return (
    <LayoutWithSidebar>
      <div className="container mx-auto px-4 py-8">
        <div className="mb-8">
          <div className={`${isMobile ? 'space-y-4' : 'flex justify-between items-center'}`}>
            <div>
              <div className="flex items-center gap-2 mb-2">
                <h1 className="text-2xl font-bold text-gray-900 dark:text-white">
                  Welcome back, {session?.user?.name}!
                </h1>
                <BarreauBadge 
                  verificationStatus={session?.user?.verificationStatus}
                  isVerified={session?.user?.isVerified}
                  size="sm"
                  showText={true}
                />
              </div>
              <h1 className={`font-bold text-gray-900 dark:text-white ${isMobile ? 'text-2xl' : 'text-3xl'}`}>My Applications</h1>
              <p className="mt-2 text-gray-600 dark:text-gray-400">Manage your class action applications here.</p>
            </div>
            <button
              onClick={() => setShowNewApplication(true)}
              className={`btn-primary ${isMobile ? 'w-full' : ''}`}
            >
              <span className="flex items-center justify-center">
                <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                </svg>
                New Application
              </span>
            </button>
          </div>
        </div>

        {/* Stats */}
        <div className={`grid gap-4 mb-8 ${isMobile ? 'grid-cols-2' : 'grid-cols-1 md:grid-cols-4'}`}>
          <div className={`bg-white dark:bg-gray-800 rounded-lg shadow ${isMobile ? 'p-4' : 'p-6'}`}>
            <div className="flex items-center">
              <div className="p-2 bg-blue-100 dark:bg-blue-900 rounded-full mr-3">
                <svg className="w-5 h-5 text-blue-600 dark:text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
                </svg>
              </div>
              <div>
                <h3 className={`font-semibold text-gray-900 dark:text-white ${isMobile ? 'text-sm' : 'text-lg'}`}>Total</h3>
                <p className={`font-bold text-primary ${isMobile ? 'text-2xl' : 'text-3xl'}`}>{stats.total}</p>
              </div>
            </div>
          </div>
          <div className={`bg-white dark:bg-gray-800 rounded-lg shadow ${isMobile ? 'p-4' : 'p-6'}`}>
            <div className="flex items-center">
              <div className="p-2 bg-yellow-100 dark:bg-yellow-900 rounded-full mr-3">
                <svg className="w-5 h-5 text-yellow-600 dark:text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <div>
                <h3 className={`font-semibold text-gray-900 dark:text-white ${isMobile ? 'text-sm' : 'text-lg'}`}>Pending</h3>
                <p className={`font-bold text-yellow-600 ${isMobile ? 'text-2xl' : 'text-3xl'}`}>{stats.pending}</p>
              </div>
            </div>
          </div>
          <div className={`bg-white dark:bg-gray-800 rounded-lg shadow ${isMobile ? 'p-4' : 'p-6'}`}>
            <div className="flex items-center">
              <div className="p-2 bg-green-100 dark:bg-green-900 rounded-full mr-3">
                <svg className="w-5 h-5 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <div>
                <h3 className={`font-semibold text-gray-900 dark:text-white ${isMobile ? 'text-sm' : 'text-lg'}`}>Approved</h3>
                <p className={`font-bold text-green-600 ${isMobile ? 'text-2xl' : 'text-3xl'}`}>{stats.approved}</p>
              </div>
            </div>
          </div>
          <div className={`bg-white dark:bg-gray-800 rounded-lg shadow ${isMobile ? 'p-4' : 'p-6'}`}>
            <div className="flex items-center">
              <div className="p-2 bg-red-100 dark:bg-red-900 rounded-full mr-3">
                <svg className="w-5 h-5 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </div>
              <div>
                <h3 className={`font-semibold text-gray-900 dark:text-white ${isMobile ? 'text-sm' : 'text-lg'}`}>Rejected</h3>
                <p className={`font-bold text-red-600 ${isMobile ? 'text-2xl' : 'text-3xl'}`}>{stats.rejected}</p>
              </div>
            </div>
          </div>
        </div>

        {/* Recent Registrations - Card/Grid Layout */}
        <div className="flex items-center justify-between mb-4">
          <h2 className={`font-semibold ${isMobile ? 'text-lg' : 'text-xl'}`}>Recent Registrations</h2>
          {registrations.length > 0 && (
            <span className="text-sm text-gray-500 dark:text-gray-400">
              {registrations.length} {registrations.length === 1 ? 'application' : 'applications'}
            </span>
          )}
        </div>
        
        {registrations.length === 0 ? (
          <div className="text-center py-12">
            <div className="bg-gray-100 dark:bg-gray-800 rounded-full w-16 h-16 flex items-center justify-center mx-auto mb-4">
              <svg className="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
              </svg>
            </div>
            <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-2">No Applications Yet</h3>
            <p className="text-gray-500 dark:text-gray-400 mb-4">Get started by creating your first application.</p>
            <button
              onClick={() => setShowNewApplication(true)}
              className="btn-primary"
            >
              Create Application
            </button>
          </div>
        ) : (
          <div className={`grid gap-6 ${isMobile ? 'grid-cols-1' : 'grid-cols-1 lg:grid-cols-2'}`}>
          {registrations.map(registration => {
            const appType = getApplicationType(registration, session?.user?.id, session?.user?.email);
            return (
            <div key={registration.id} className={`bg-white rounded-2xl shadow-xl flex flex-col border-2 ${isMobile ? 'p-4 min-h-[320px]' : 'p-8 min-h-[380px]'} ${appType.bgColor || 'border-primary/10'}`}>
              {/* Application Type Header */}
              <div className={`mb-3 px-3 py-2 rounded-lg ${appType.bgColor} border`}>
                <div className="flex items-center">
                  <span className="text-lg mr-2">{appType.icon}</span>
                  <span className={`font-semibold ${appType.textColor}`}>{appType.label}</span>
                </div>
                {appType.description && (
                  <p className={`text-sm mt-1 ${appType.textColor} opacity-80`}>{appType.description}</p>
                )}
              </div>
              
              {/* Enhanced Status Display for ALL statuses */}
              <div className="mb-4">
                {/* Special enhanced display for primary statuses */}
                {registration.status === 'PENDING' ? (
                  <div className="bg-gradient-to-r from-amber-100 to-orange-100 border-2 border-amber-300 rounded-xl p-3 shadow-sm">
                    <div className="flex items-center space-x-3">
                      <StatusIcon status={registration.status} />
                      <div>
                        <div className="font-bold text-amber-800 text-sm">⏳ Under Review</div>
                        <div className="text-amber-700 text-xs">Application being processed</div>
                      </div>
                    </div>
                    <div className="mt-2 bg-amber-200 rounded-full h-1.5 overflow-hidden">
                      <div className="bg-gradient-to-r from-amber-400 to-orange-500 h-full rounded-full animate-pulse" style={{ width: '45%' }}></div>
                    </div>
                  </div>
                ) : registration.status === 'APPROVED' || registration.status === 'COMPLETED' ? (
                  <div className="bg-gradient-to-r from-green-100 to-emerald-100 border-2 border-green-300 rounded-xl p-3 shadow-sm">
                    <div className="flex items-center space-x-3">
                      <StatusIcon status={registration.status} />
                      <div>
                        <div className="font-bold text-green-800 text-sm">
                          {registration.status === 'COMPLETED' ? '🎉 Completed' : '✅ Approved'}
                        </div>
                        <div className="text-green-700 text-xs">
                          {registration.status === 'COMPLETED' ? 'Process finished successfully!' : 'Welcome to the class action!'}
                        </div>
                      </div>
                    </div>
                    <div className="mt-2 bg-green-200 rounded-full h-1.5 overflow-hidden">
                      <div className="bg-gradient-to-r from-green-400 to-emerald-500 h-full rounded-full" style={{ width: '100%' }}></div>
                    </div>
                  </div>
                ) : registration.status === 'REJECTED' ? (
                  <div className="bg-gradient-to-r from-red-100 to-pink-100 border-2 border-red-300 rounded-xl p-3 shadow-sm">
                    <div className="flex items-center space-x-3">
                      <StatusIcon status={registration.status} />
                      <div>
                        <div className="font-bold text-red-800 text-sm">❌ Declined</div>
                        <div className="text-red-700 text-xs">Please check feedback</div>
                      </div>
                    </div>
                  </div>
                ) : (
                  /* Standard display for all other statuses */
                  <div className={`rounded-xl p-3 shadow-sm border-2 ${
                    registration.status.includes('DOCUMENTS') || registration.status === 'MISSING_DOCUMENTS' ? 'bg-orange-50 border-orange-200' :
                    registration.status.includes('VERIFICATION') || registration.status.includes('REVIEW') ? 'bg-purple-50 border-purple-200' :
                    registration.status.includes('PAYMENT') ? 'bg-yellow-50 border-yellow-200' :
                    registration.status.includes('APPROVAL') ? 'bg-blue-50 border-blue-200' :
                    registration.status === 'ON_HOLD' ? 'bg-gray-50 border-gray-200' :
                    registration.status === 'ESCALATED' ? 'bg-red-50 border-red-200' :
                    'bg-gray-50 border-gray-200'
                  }`}>
                    <div className="flex items-center space-x-3">
                      <StatusIcon status={registration.status} />
                      <div className="flex-1">
                        <div className={`font-bold text-sm ${
                          registration.status.includes('DOCUMENTS') || registration.status === 'MISSING_DOCUMENTS' ? 'text-orange-800' :
                          registration.status.includes('VERIFICATION') || registration.status.includes('REVIEW') ? 'text-purple-800' :
                          registration.status.includes('PAYMENT') ? 'text-yellow-800' :
                          registration.status.includes('APPROVAL') ? 'text-blue-800' :
                          registration.status === 'ON_HOLD' ? 'text-gray-800' :
                          registration.status === 'ESCALATED' ? 'text-red-800' :
                          'text-gray-800'
                        }`}>
                          {getStatusLabel(registration.status)}
                        </div>
                        <div className={`text-xs ${
                          registration.status.includes('DOCUMENTS') || registration.status === 'MISSING_DOCUMENTS' ? 'text-orange-700' :
                          registration.status.includes('VERIFICATION') || registration.status.includes('REVIEW') ? 'text-purple-700' :
                          registration.status.includes('PAYMENT') ? 'text-yellow-700' :
                          registration.status.includes('APPROVAL') ? 'text-blue-700' :
                          registration.status === 'ON_HOLD' ? 'text-gray-700' :
                          registration.status === 'ESCALATED' ? 'text-red-700' :
                          'text-gray-700'
                        }`}>
                          {getStatusEncouragement(registration.status)}
                        </div>
                      </div>
                    </div>
                  </div>
                )}
              </div>
              {/* Main Info */}
              <div className="mb-2">
                <div className={`font-extrabold ${isMobile ? 'text-xl' : 'text-2xl'}`}>{registration.firstName} {registration.lastName}</div>
                <div className="text-sm text-gray-500">{registration.email}</div>
              </div>
              <div className="mb-2">
                <span className="font-semibold">Detainee:</span> {registration.detaineeInfo?.name || '-'}
              </div>
              <div className="text-sm text-gray-500 mb-2">
                {getFacilityName(registration.detaineeInfo?.facility || '') || '-'}
              </div>
              {/* Extra Info */}
              <div className="mb-4">
                <div className="text-xs text-gray-400">{format(new Date(registration.createdAt), 'MMM d, yyyy')}</div>
                {registration.reasonForJoining && (
                  <div className="mt-2 text-gray-700 italic">"{registration.reasonForJoining}"</div>
                )}
                {registration.urgentNeeds && (
                  <div className="mt-1 text-pink-600 font-medium">{registration.urgentNeeds}</div>
                )}
              </div>
              {/* Documents */}
              {registration.documents && registration.documents.length > 0 && (
                <div className="mb-4">
                  <h4 className="text-sm font-semibold mb-2">Documents</h4>
                  <div className="space-y-2">
                    {registration.documents.map((doc) => (
                      <a
                        key={doc.id}
                        href={`/user/registrations/${registration.id}`}
                        className="flex items-center text-blue-600 hover:text-blue-800 underline"
                      >
                        <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                        </svg>
                        {doc.name}
                      </a>
                    ))}
                  </div>
                </div>
              )}
              {/* Encouragement */}
              <div className="mb-4 text-primary font-semibold">
                {getStatusEncouragement(registration.status)}
              </div>
              {/* Actions */}
              <div className={`mt-auto pt-4 ${isMobile ? 'space-y-2' : 'grid grid-cols-3 gap-2'}`}>
                <button
                  onClick={() => router.push(`/user/applications/${registration.id}`)}
                  className={`font-semibold text-sm px-4 py-2.5 rounded-lg flex items-center justify-center transition-all duration-200 shadow-md hover:shadow-lg transform hover:scale-105 text-white ${isMobile ? 'w-full' : ''}`}
                  style={{
                    background: `linear-gradient(135deg, #8b5cf6, #7c3aed)`,
                  }}
                  onMouseEnter={(e) => {
                    e.currentTarget.style.background = `linear-gradient(135deg, #7c3aed, #8b5cf6)`;
                  }}
                  onMouseLeave={(e) => {
                    e.currentTarget.style.background = `linear-gradient(135deg, #8b5cf6, #7c3aed)`;
                  }}
                >
                  <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
                  </svg>
                  Edit
                </button>
                <button
                  onClick={() => setShowPrivateChat({ open: true, registrationId: registration.id })}
                  className={`font-semibold text-sm px-4 py-2.5 rounded-lg flex items-center justify-center transition-all duration-200 shadow-md hover:shadow-lg transform hover:scale-105 text-white ${isMobile ? 'w-full' : ''}`}
                  style={{
                    background: `linear-gradient(135deg, #3b82f6, #2563eb)`,
                  }}
                  onMouseEnter={(e) => {
                    e.currentTarget.style.background = `linear-gradient(135deg, #2563eb, #3b82f6)`;
                  }}
                  onMouseLeave={(e) => {
                    e.currentTarget.style.background = `linear-gradient(135deg, #3b82f6, #2563eb)`;
                  }}
                >
                  <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
                  </svg>
                  Chat
                </button>
                <button
                  onClick={e => handleDeleteRegistration(registration.id, e)}
                  className={`bg-gradient-to-r from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 text-white font-semibold text-sm px-4 py-2.5 rounded-lg flex items-center justify-center transition-all duration-200 shadow-md hover:shadow-lg transform hover:scale-105 ${isMobile ? 'w-full' : ''}`}
                >
                  <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                  </svg>
                  Delete
                </button>
              </div>
            </div>
          );
          })}
          </div>
        )}

        {/* Document Viewer Modal */}
        <AnimatePresence>
          {selectedDocument && (
            <></>
          )}
        </AnimatePresence>

        {/* New Application Form */}
        <AnimatePresence>
          {showNewApplication && (
            <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"
            >
              <motion.div
                initial={{ scale: 0.95, opacity: 0 }}
                animate={{ scale: 1, opacity: 1 }}
                exit={{ scale: 0.95, opacity: 0 }}
                className={`rounded-xl shadow-xl w-full overflow-y-auto bg-white ${isMobile ? 'max-w-full h-full max-h-screen' : 'max-w-7xl max-h-[90vh]'}`}
              >
                <div className={`${isMobile ? 'p-4' : 'p-6'}`}>
                  <div className="flex justify-between items-center mb-6">
                    <h2 className={`font-bold ${isMobile ? 'text-xl' : 'text-2xl'}`}>Application Form</h2>
                    <button
                      onClick={() => setShowNewApplication(false)}
                      className="p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg"
                    >
                      {isMobile ? (
                        <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                        </svg>
                      ) : (
                        'Close'
                      )}
                    </button>
                  </div>
                  <RegistrationForm
                    isFrench={router.locale === 'fr'}
                    initialLocale={router.locale || 'en'}
                    onSuccess={handleRegistrationSuccess}
                    isAdmin={false}
                  />
                </div>
              </motion.div>
            </motion.div>
          )}
        </AnimatePresence>

        <AnimatePresence>
          {showPrivateChat.open && showPrivateChat.registrationId && (
            <PrivateChat
              registrationId={showPrivateChat.registrationId}
              onClose={() => setShowPrivateChat({ open: false, registrationId: null })}
            />
          )}
        </AnimatePresence>
      </div>
    </LayoutWithSidebar>
  );
};

export default UserDashboard;

CasperSecurity Mini