HEX
Server: nginx/1.18.0
System: Linux vcwordpress 5.15.0-174-generic #184-Ubuntu SMP Fri Mar 13 18:41:50 UTC 2026 x86_64
User: root (0)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/igsms.viitorcloud.co/igsmsportal/views/ProfileView.tsx
import React, { useState } from 'react';
import { User, UserRole, Grievance, GrievanceStatus } from '../types';

interface ProfileViewProps {
  user: User;
  grievances: Grievance[];
  onUpdateUser: (updatedFields: Partial<User>) => void;
}

const ProfileView: React.FC<ProfileViewProps> = ({ user, grievances, onUpdateUser }) => {
  const [isEditing, setIsEditing] = useState(false);
  const [editData, setEditData] = useState({
    name: user.name,
    department: user.department || ''
  });
  const [isSaving, setIsSaving] = useState(false);

  const getStats = () => {
    const total = grievances.length;
    const resolved = grievances.filter(g => g.status === GrievanceStatus.RESOLVED).length;
    const inProgress = grievances.filter(g => g.status === GrievanceStatus.IN_PROGRESS).length;

    if (user.role === UserRole.CITIZEN) {
      return [
        { label: 'Applications Filed', value: total, icon: 'fa-file-signature', color: 'blue' },
        { label: 'Successfully Resolved', value: resolved, icon: 'fa-check-double', color: 'emerald' },
        { label: 'Pending Action', value: total - resolved, icon: 'fa-clock', color: 'amber' }
      ];
    }
    
    if (user.role === UserRole.OFFICER) {
      return [
        { label: 'Cases Managed', value: total, icon: 'fa-briefcase', color: 'indigo' },
        { label: 'Redressal Rate', value: total > 0 ? `${Math.round((resolved / total) * 100)}%` : '0%', icon: 'fa-chart-pie', color: 'emerald' },
        { label: 'Current Load', value: inProgress, icon: 'fa-layer-group', color: 'orange' }
      ];
    }

    return [
      { label: 'State Oversight', value: 'Full', icon: 'fa-shield-halved', color: 'slate' },
      { label: 'System Uptime', value: '99.9%', icon: 'fa-microchip', color: 'blue' },
      { label: 'Dept Count', value: '12', icon: 'fa-building', color: 'indigo' }
    ];
  };

  const stats = getStats();

  const handleSave = () => {
    setIsSaving(true);
    // Simulate API delay
    setTimeout(() => {
      onUpdateUser({
        name: editData.name,
        department: user.role === UserRole.OFFICER ? editData.department : user.department
      });
      setIsSaving(false);
      setIsEditing(false);
    }, 800);
  };

  return (
    <div className="animate-fade-in space-y-8 py-4">
      <header className="mb-10">
        <h2 className="text-3xl font-black text-slate-900 tracking-tight">Profile Intelligence</h2>
        <p className="text-slate-500 font-medium">Managing identity and performance across the IGSMS ecosystem.</p>
      </header>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
        {/* Profile Card */}
        <div className="lg:col-span-1 space-y-8">
          <div className="bg-white rounded-[2.5rem] border border-slate-200 overflow-hidden shadow-sm">
            <div className="h-32 bg-slate-900 flex items-center justify-center">
               <div className="w-24 h-24 rounded-[2rem] bg-white border-4 border-slate-900 translate-y-12 flex items-center justify-center text-3xl font-black text-blue-600 shadow-xl">
                 {user.name.charAt(0)}
               </div>
            </div>
            <div className="pt-16 pb-10 px-8 text-center">
              {!isEditing ? (
                <>
                  <h3 className="text-xl font-black text-slate-900">{user.name}</h3>
                  <p className="text-[10px] font-black text-blue-600 uppercase tracking-[0.2em] mt-1">{user.role}</p>
                  
                  <div className="mt-8 pt-8 border-t border-slate-50 space-y-4">
                    <div className="flex justify-between items-center px-4">
                      <span className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Employee ID</span>
                      <span className="text-xs font-bold text-slate-700">GUJ-{user.id.padStart(4, '0')}</span>
                    </div>
                    {user.department && (
                      <div className="flex justify-between items-center px-4">
                        <span className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Department</span>
                        <span className="text-xs font-bold text-slate-700">{user.department}</span>
                      </div>
                    )}
                    <div className="flex justify-between items-center px-4">
                      <span className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Account Status</span>
                      <span className="text-[10px] px-3 py-1 bg-emerald-50 text-emerald-600 rounded-full font-black uppercase tracking-wider">Verified</span>
                    </div>
                  </div>

                  <button 
                    onClick={() => setIsEditing(true)}
                    className="w-full mt-10 py-4 bg-slate-900 text-white rounded-2xl font-black text-xs uppercase tracking-widest hover:bg-slate-800 transition-all shadow-lg shadow-slate-200"
                  >
                    Update Identity
                  </button>
                </>
              ) : (
                <div className="space-y-6 text-left">
                  <div className="space-y-2">
                    <label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Full Name</label>
                    <input 
                      type="text" 
                      value={editData.name} 
                      onChange={e => setEditData({...editData, name: e.target.value})}
                      className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl text-sm font-bold focus:ring-2 focus:ring-blue-500 outline-none"
                    />
                  </div>
                  {user.role === UserRole.OFFICER && (
                    <div className="space-y-2">
                      <label className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Department</label>
                      <input 
                        type="text" 
                        value={editData.department} 
                        onChange={e => setEditData({...editData, department: e.target.value})}
                        className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-xl text-sm font-bold focus:ring-2 focus:ring-blue-500 outline-none"
                      />
                    </div>
                  )}
                  <div className="flex gap-3 pt-4">
                    <button 
                      onClick={handleSave}
                      disabled={isSaving}
                      className="flex-1 py-3 bg-blue-600 text-white rounded-xl font-black text-[10px] uppercase tracking-widest shadow-lg shadow-blue-500/20 hover:bg-blue-700 transition-all"
                    >
                      {isSaving ? <i className="fa-solid fa-spinner animate-spin"></i> : 'Save Changes'}
                    </button>
                    <button 
                      onClick={() => { setIsEditing(false); setEditData({ name: user.name, department: user.department || '' }); }}
                      className="px-6 py-3 bg-slate-100 text-slate-600 rounded-xl font-black text-[10px] uppercase tracking-widest hover:bg-slate-200 transition-all"
                    >
                      Cancel
                    </button>
                  </div>
                </div>
              )}
            </div>
          </div>

          <div className="bg-blue-50 p-8 rounded-[2rem] border border-blue-100">
             <h4 className="text-xs font-black text-blue-800 uppercase tracking-widest mb-4">Security Notice</h4>
             <p className="text-xs font-bold text-blue-900/70 leading-relaxed italic">
               "This session is monitored for integrity. Please ensure your digital signature is updated every 90 days for uninterrupted access to IGSMS services."
             </p>
          </div>
        </div>

        {/* Stats and Activity */}
        <div className="lg:col-span-2 space-y-8">
           <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
             {stats.map((s, idx) => (
               <div key={idx} className="bg-white p-8 rounded-[2rem] border border-slate-100 shadow-sm flex flex-col items-center text-center group hover:border-blue-200 transition-colors">
                 <div className={`w-12 h-12 rounded-2xl flex items-center justify-center mb-6 text-xl transition-all ${
                    s.color === 'emerald' ? 'bg-emerald-50 text-emerald-600' :
                    s.color === 'blue' ? 'bg-blue-50 text-blue-600' :
                    s.color === 'amber' ? 'bg-amber-50 text-amber-600' :
                    s.color === 'orange' ? 'bg-orange-50 text-orange-600' : 'bg-slate-50 text-slate-600'
                 }`}>
                   <i className={`fa-solid ${s.icon}`}></i>
                 </div>
                 <p className="text-3xl font-black text-slate-900">{s.value}</p>
                 <p className="text-[10px] font-black text-slate-400 uppercase tracking-widest mt-2">{s.label}</p>
               </div>
             ))}
           </div>

           <div className="bg-white p-10 rounded-[2.5rem] border border-slate-100 shadow-sm">
             <div className="flex items-center justify-between mb-8">
               <h4 className="text-lg font-black text-slate-900">Recent System Engagement</h4>
               <button className="text-[10px] font-black text-blue-600 uppercase tracking-widest hover:underline">Download Log</button>
             </div>
             
             <div className="space-y-6">
                {grievances.slice(0, 4).map((g, idx) => (
                  <div key={idx} className="flex items-center justify-between p-5 bg-slate-50 rounded-2xl border border-slate-100 group hover:bg-white hover:shadow-md transition-all">
                    <div className="flex items-center gap-4">
                      <div className="w-10 h-10 bg-white rounded-xl border border-slate-200 flex items-center justify-center text-slate-400 group-hover:text-blue-600 group-hover:border-blue-200 transition-all">
                        <i className="fa-solid fa-clock-rotate-left text-xs"></i>
                      </div>
                      <div>
                        <p className="text-xs font-black text-slate-800">{g.title}</p>
                        <p className="text-[10px] font-bold text-slate-400 mt-1 uppercase tracking-tight">{g.ticketNumber} • {new Date(g.updatedAt).toLocaleDateString()}</p>
                      </div>
                    </div>
                    <div className="text-right">
                       <span className="text-[9px] font-black uppercase text-slate-400 tracking-widest">{g.status}</span>
                    </div>
                  </div>
                ))}
                {grievances.length === 0 && (
                  <div className="py-20 text-center">
                    <i className="fa-solid fa-ghost text-4xl text-slate-100 mb-4"></i>
                    <p className="text-xs font-bold text-slate-400">No activity logged in the current cycle.</p>
                  </div>
                )}
             </div>
           </div>
        </div>
      </div>
    </div>
  );
};

export default ProfileView;