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/backups/lavocat.quebec/backup-20250730-021618/src/pages/judge/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/backups/lavocat.quebec/backup-20250730-021618/src/pages/judge/metrics.tsx
import React, { useState } from 'react';
import { useRouter } from 'next/router';
import { useRequireRole } from '../../lib/auth-utils';
import { USER_ROLES } from '../../lib/auth-utils';

interface PerformanceMetric {
  id: string;
  category: string;
  metric: string;
  value: number;
  target: number;
  unit: string;
  trend: 'up' | 'down' | 'stable';
  period: string;
  description: string;
}

interface CaseStatistic {
  id: string;
  caseType: string;
  totalCases: number;
  resolvedCases: number;
  pendingCases: number;
  averageResolutionTime: number;
  successRate: number;
  period: string;
}

const JudgeMetricsPage: React.FC = () => {
  const router = useRouter();
  const { session, status, isAuthorized } = useRequireRole([USER_ROLES.JUDGE, USER_ROLES.ADMIN, USER_ROLES.SUPERADMIN, USER_ROLES.SUPERADMIN]);
  const [selectedPeriod, setSelectedPeriod] = useState('current_year');
  const [selectedCategory, setSelectedCategory] = useState('all');

  // Mock data for performance metrics
  const [metrics] = useState<PerformanceMetric[]>([
    {
      id: '1',
      category: 'efficiency',
      metric: 'Case Resolution Rate',
      value: 94.2,
      target: 90.0,
      unit: '%',
      trend: 'up',
      period: 'Current Year',
      description: 'Percentage of cases resolved within target timeframe'
    },
    {
      id: '2',
      category: 'efficiency',
      metric: 'Average Case Duration',
      value: 45.3,
      target: 60.0,
      unit: 'days',
      trend: 'down',
      period: 'Current Year',
      description: 'Average time from filing to resolution'
    },
    {
      id: '3',
      category: 'quality',
      metric: 'Appeal Success Rate',
      value: 87.5,
      target: 85.0,
      unit: '%',
      trend: 'up',
      period: 'Current Year',
      description: 'Percentage of decisions upheld on appeal'
    },
    {
      id: '4',
      category: 'quality',
      metric: 'Client Satisfaction',
      value: 4.6,
      target: 4.0,
      unit: '/5',
      trend: 'up',
      period: 'Current Year',
      description: 'Average satisfaction rating from court users'
    },
    {
      id: '5',
      category: 'productivity',
      metric: 'Cases Per Month',
      value: 12.8,
      target: 10.0,
      unit: 'cases',
      trend: 'up',
      period: 'Current Year',
      description: 'Average number of cases handled per month'
    },
    {
      id: '6',
      category: 'productivity',
      metric: 'Education Credits',
      value: 24,
      target: 20,
      unit: 'credits',
      trend: 'up',
      period: 'Current Year',
      description: 'Continuing education credits earned'
    },
    {
      id: '7',
      category: 'timeliness',
      metric: 'Decision Turnaround',
      value: 3.2,
      target: 5.0,
      unit: 'days',
      trend: 'down',
      period: 'Current Year',
      description: 'Average days to issue written decisions'
    },
    {
      id: '8',
      category: 'timeliness',
      metric: 'Hearing Punctuality',
      value: 98.7,
      target: 95.0,
      unit: '%',
      trend: 'up',
      period: 'Current Year',
      description: 'Percentage of hearings started on time'
    }
  ]);

  // Mock data for case statistics
  const [caseStats] = useState<CaseStatistic[]>([
    {
      id: '1',
      caseType: 'Criminal',
      totalCases: 45,
      resolvedCases: 42,
      pendingCases: 3,
      averageResolutionTime: 38.5,
      successRate: 93.3,
      period: 'Current Year'
    },
    {
      id: '2',
      caseType: 'Civil',
      totalCases: 32,
      resolvedCases: 30,
      pendingCases: 2,
      averageResolutionTime: 52.1,
      successRate: 87.5,
      period: 'Current Year'
    },
    {
      id: '3',
      caseType: 'Family',
      totalCases: 28,
      resolvedCases: 25,
      pendingCases: 3,
      averageResolutionTime: 41.8,
      successRate: 89.3,
      period: 'Current Year'
    },
    {
      id: '4',
      caseType: 'Administrative',
      totalCases: 18,
      resolvedCases: 17,
      pendingCases: 1,
      averageResolutionTime: 29.3,
      successRate: 94.4,
      period: 'Current Year'
    }
  ]);

  const getTrendColor = (trend: string) => {
    switch (trend) {
      case 'up': return 'text-green-600';
      case 'down': return 'text-red-600';
      case 'stable': return 'text-gray-600';
      default: return 'text-gray-600';
    }
  };

  const getTrendIcon = (trend: string) => {
    switch (trend) {
      case 'up': return '↗';
      case 'down': return '↘';
      case 'stable': return '→';
      default: return '→';
    }
  };

  const getCategoryColor = (category: string) => {
    switch (category) {
      case 'efficiency': return 'bg-blue-100 text-blue-800';
      case 'quality': return 'bg-green-100 text-green-800';
      case 'productivity': return 'bg-purple-100 text-purple-800';
      case 'timeliness': return 'bg-orange-100 text-orange-800';
      default: return 'bg-gray-100 text-gray-800';
    }
  };

  const filteredMetrics = metrics.filter(metric => {
    return selectedCategory === 'all' || metric.category === selectedCategory;
  });

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

  return (
    <div className="min-h-screen bg-gray-50">
      {/* Header */}
      <div className="bg-white shadow-sm border-b">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex justify-between items-center py-6">
            <div>
              <h1 className="text-3xl font-bold text-gray-900">Performance Metrics</h1>
              <p className="mt-1 text-sm text-gray-500">
                Track judicial performance, case statistics, and professional development
              </p>
            </div>
            <div className="flex space-x-3">
              <button
                onClick={() => router.push('/judge/dashboard')}
                className="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
              >
                ← Back to Dashboard
              </button>
              <button className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
                Export Report
              </button>
            </div>
          </div>
        </div>
      </div>

      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        {/* Overview Stats */}
        <div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
          <div className="bg-white overflow-hidden shadow rounded-lg">
            <div className="p-5">
              <div className="flex items-center">
                <div className="flex-shrink-0">
                  <div className="w-8 h-8 bg-green-500 rounded-md 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="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                  </div>
                </div>
                <div className="ml-5 w-0 flex-1">
                  <dl>
                    <dt className="text-sm font-medium text-gray-500 truncate">Overall Performance</dt>
                    <dd className="text-lg font-medium text-gray-900">94.2%</dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>

          <div className="bg-white overflow-hidden shadow rounded-lg">
            <div className="p-5">
              <div className="flex items-center">
                <div className="flex-shrink-0">
                  <div className="w-8 h-8 bg-blue-500 rounded-md 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="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>
                </div>
                <div className="ml-5 w-0 flex-1">
                  <dl>
                    <dt className="text-sm font-medium text-gray-500 truncate">Total Cases</dt>
                    <dd className="text-lg font-medium text-gray-900">
                      {caseStats.reduce((sum, stat) => sum + stat.totalCases, 0)}
                    </dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>

          <div className="bg-white overflow-hidden shadow rounded-lg">
            <div className="p-5">
              <div className="flex items-center">
                <div className="flex-shrink-0">
                  <div className="w-8 h-8 bg-purple-500 rounded-md 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="M13 10V3L4 14h7v7l9-11h-7z" />
                    </svg>
                  </div>
                </div>
                <div className="ml-5 w-0 flex-1">
                  <dl>
                    <dt className="text-sm font-medium text-gray-500 truncate">Avg Resolution</dt>
                    <dd className="text-lg font-medium text-gray-900">
                      {Math.round(caseStats.reduce((sum, stat) => sum + stat.averageResolutionTime, 0) / caseStats.length)} days
                    </dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>

          <div className="bg-white overflow-hidden shadow rounded-lg">
            <div className="p-5">
              <div className="flex items-center">
                <div className="flex-shrink-0">
                  <div className="w-8 h-8 bg-orange-500 rounded-md 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="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                  </div>
                </div>
                <div className="ml-5 w-0 flex-1">
                  <dl>
                    <dt className="text-sm font-medium text-gray-500 truncate">Education Credits</dt>
                    <dd className="text-lg font-medium text-gray-900">24/20</dd>
                  </dl>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* Filters */}
        <div className="bg-white shadow rounded-lg mb-6">
          <div className="px-6 py-4 border-b border-gray-200">
            <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between space-y-4 sm:space-y-0">
              <h3 className="text-lg font-medium text-gray-900">Performance Metrics</h3>
              <div className="flex space-x-4">
                <select
                  value={selectedPeriod}
                  onChange={(e) => setSelectedPeriod(e.target.value)}
                  className="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md"
                >
                  <option value="current_year">Current Year</option>
                  <option value="last_year">Last Year</option>
                  <option value="last_quarter">Last Quarter</option>
                  <option value="last_month">Last Month</option>
                </select>
                <select
                  value={selectedCategory}
                  onChange={(e) => setSelectedCategory(e.target.value)}
                  className="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm rounded-md"
                >
                  <option value="all">All Categories</option>
                  <option value="efficiency">Efficiency</option>
                  <option value="quality">Quality</option>
                  <option value="productivity">Productivity</option>
                  <option value="timeliness">Timeliness</option>
                </select>
              </div>
            </div>
          </div>

          <div className="p-6">
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
              {filteredMetrics.map((metric) => (
                <div key={metric.id} className="bg-white border border-gray-200 rounded-lg p-6">
                  <div className="flex items-center justify-between mb-4">
                    <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getCategoryColor(metric.category)}`}>
                      {metric.category}
                    </span>
                    <span className={`text-sm font-medium ${getTrendColor(metric.trend)}`}>
                      {getTrendIcon(metric.trend)}
                    </span>
                  </div>
                  <h3 className="text-lg font-medium text-gray-900 mb-2">{metric.metric}</h3>
                  <div className="flex items-baseline">
                    <span className="text-2xl font-bold text-gray-900">
                      {metric.value}{metric.unit}
                    </span>
                    <span className="ml-2 text-sm text-gray-500">
                      / {metric.target}{metric.unit}
                    </span>
                  </div>
                  <p className="text-sm text-gray-600 mt-2">{metric.description}</p>
                  <div className="mt-4">
                    <div className="flex justify-between text-sm text-gray-500 mb-1">
                      <span>Progress</span>
                      <span>{Math.round((metric.value / metric.target) * 100)}%</span>
                    </div>
                    <div className="w-full bg-gray-200 rounded-full h-2">
                      <div
                        className={`h-2 rounded-full ${
                          metric.value >= metric.target ? 'bg-green-500' : 'bg-blue-500'
                        }`}
                        style={{ width: `${Math.min((metric.value / metric.target) * 100, 100)}%` }}
                      ></div>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Case Statistics */}
        <div className="bg-white shadow rounded-lg">
          <div className="px-6 py-4 border-b border-gray-200">
            <h3 className="text-lg font-medium text-gray-900">Case Statistics by Type</h3>
          </div>
          <div className="p-6">
            <div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
              <table className="min-w-full divide-y divide-gray-300">
                <thead className="bg-gray-50">
                  <tr>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Case Type</th>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Total Cases</th>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Resolved</th>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pending</th>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Avg Resolution (days)</th>
                    <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Success Rate</th>
                  </tr>
                </thead>
                <tbody className="bg-white divide-y divide-gray-200">
                  {caseStats.map((stat) => (
                    <tr key={stat.id}>
                      <td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
                        {stat.caseType}
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        {stat.totalCases}
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        <span className="text-green-600 font-medium">{stat.resolvedCases}</span>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        <span className="text-orange-600 font-medium">{stat.pendingCases}</span>
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                        {stat.averageResolutionTime.toFixed(1)}
                      </td>
                      <td className="px-6 py-4 whitespace-nowrap">
                        <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
                          stat.successRate >= 90 ? 'bg-green-100 text-green-800' :
                          stat.successRate >= 80 ? 'bg-yellow-100 text-yellow-800' :
                          'bg-red-100 text-red-800'
                        }`}>
                          {stat.successRate}%
                        </span>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        </div>

        {/* Performance Insights */}
        <div className="mt-6 bg-white shadow rounded-lg">
          <div className="px-6 py-4 border-b border-gray-200">
            <h3 className="text-lg font-medium text-gray-900">Performance Insights</h3>
          </div>
          <div className="p-6">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              <div>
                <h4 className="text-sm font-medium text-gray-900 mb-3">Strengths</h4>
                <ul className="space-y-2">
                  <li className="flex items-start">
                    <span className="text-green-500 mr-2">✓</span>
                    <span className="text-sm text-gray-600">Excellent case resolution rate (94.2%)</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-green-500 mr-2">✓</span>
                    <span className="text-sm text-gray-600">High client satisfaction rating (4.6/5)</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-green-500 mr-2">✓</span>
                    <span className="text-sm text-gray-600">Strong appeal success rate (87.5%)</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-green-500 mr-2">✓</span>
                    <span className="text-sm text-gray-600">Exceeded education credit requirements</span>
                  </li>
                </ul>
              </div>
              <div>
                <h4 className="text-sm font-medium text-gray-900 mb-3">Areas for Improvement</h4>
                <ul className="space-y-2">
                  <li className="flex items-start">
                    <span className="text-yellow-500 mr-2">⚠</span>
                    <span className="text-sm text-gray-600">Civil cases taking longer than target (52.1 days)</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-yellow-500 mr-2">⚠</span>
                    <span className="text-sm text-gray-600">Family law success rate below 90% (89.3%)</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-blue-500 mr-2">ℹ</span>
                    <span className="text-sm text-gray-600">Consider additional training in family law</span>
                  </li>
                  <li className="flex items-start">
                    <span className="text-blue-500 mr-2">ℹ</span>
                    <span className="text-sm text-gray-600">Monitor civil case backlog management</span>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default JudgeMetricsPage; 

CasperSecurity Mini