import React, { useState, useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; import { UserRole } from '../types'; import { supabase, uploadToSupabase } from '../supabase'; const compressImage = (base64Str: string): Promise => { return new Promise((resolve) => { const img = new Image(); img.src = base64Str; img.onload = () => { const canvas = document.createElement('canvas'); const MAX_WIDTH = 400; const MAX_HEIGHT = 400; let width = img.width; let height = img.height; if (width > height) { if (width > MAX_WIDTH) { height *= MAX_WIDTH / width; width = MAX_WIDTH; } } else { if (height > MAX_HEIGHT) { width *= MAX_HEIGHT / height; height = MAX_HEIGHT; } } canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); ctx?.drawImage(img, 0, 0, width, height); resolve(canvas.toDataURL('image/jpeg', 0.7)); }; }); }; interface ProfileViewProps { onLogout?: () => void; onSupabaseError?: () => void; } const ProfileView: React.FC = ({ onLogout, onSupabaseError }) => { const [loading, setLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [userData, setUserData] = useState(null); const [userRole, setUserRole] = useState('STUDENT'); const [userTable, setUserTable] = useState('Studentusers'); const [regCount, setRegCount] = useState(0); const [isEditing, setIsEditing] = useState(false); const [editForm, setEditForm] = useState({ name: '', phone: '', profile_photo: '', year: '', section: '' }); const [showSuccess, setShowSuccess] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const fileInputRef = useRef(null); const [pastEvents, setPastEvents] = useState([]); const fetchProfile = async () => { const { data: { user } } = await supabase.auth.getUser(); if (!user) return; try { let profile = null; let role: UserRole = 'STUDENT'; let table = 'Studentusers'; const HIGH_AUTH_ADMINS = [ 'adrit1highauth@gmail.com', 'adrit2highauth@gmail.com', 'adrit3highauth@gmail.com', 'adrit4highauth@gmail.com', 'adrit5highauth@gmail.com' ]; if (user.email && HIGH_AUTH_ADMINS.includes(user.email)) { const { data: faculty } = await supabase.from('Facultyusers').select('*').eq('id', user.id).single(); if (faculty) { profile = faculty; role = 'ADMIN'; table = 'Facultyusers'; } } else { const [studentRes, extRes, adminRes, facultyRes] = await Promise.all([ supabase.from('Studentusers').select('*').eq('id', user.id).single(), supabase.from('externalusers').select('*').eq('id', user.id).single(), supabase.from('Adminusers').select('*').eq('id', user.id).single(), supabase.from('Facultyusers').select('*').eq('id', user.id).single() ]); if (studentRes.data) { profile = studentRes.data; role = 'STUDENT'; table = 'Studentusers'; } else if (extRes.data) { profile = extRes.data; role = 'STUDENT'; table = 'externalusers'; } else if (adminRes.data) { profile = adminRes.data; role = 'COORDINATOR'; table = 'Adminusers'; } else if (facultyRes.data) { profile = facultyRes.data; role = 'COORDINATOR'; table = 'Facultyusers'; } } if (profile) { setUserData(profile); setUserRole(role); setUserTable(table); setEditForm({ name: profile.name || '', phone: profile.phone || '', profile_photo: profile.profile_photo || '', year: profile.year || '', section: profile.section || '' }); } // Fetch registration count & participation history concurrently const [countRes, historyRes] = await Promise.all([ supabase.from('registrations').select('*', { count: 'exact', head: true }).eq('user_id', user.id), supabase.from('participants').select('*, events(title, category)').eq('user_id', user.id).order('participation_date', { ascending: false }) ]); setRegCount(countRes.count || 0); if (historyRes.data) setPastEvents(historyRes.data); } catch (err) { console.error(err); } finally { setLoading(false); } }; useEffect(() => { fetchProfile(); }, []); const handleUpdate = async (e?: React.FormEvent) => { if (e) e.preventDefault(); setIsSaving(true); setErrorMessage(null); try { const { data: { user } } = await supabase.auth.getUser(); if (!user) return; let photoUrl = editForm.profile_photo; if (photoUrl.startsWith('data:')) { photoUrl = await uploadToSupabase(photoUrl, `avatars/${user.id}_${Date.now()}.jpg`, 'Profile'); } const { error } = await supabase.from(userTable).update({ name: editForm.name, phone: editForm.phone, profile_photo: photoUrl, year: editForm.year, section: editForm.section }).eq('id', user.id); if (error) throw error; setUserData({ ...userData, name: editForm.name, phone: editForm.phone, profile_photo: photoUrl, year: editForm.year, section: editForm.section }); setIsEditing(false); setShowSuccess(true); setTimeout(() => setShowSuccess(false), 3000); } catch (err: any) { setErrorMessage(err.message); if (err.message?.includes('RLS')) onSupabaseError?.(); } finally { setIsSaving(false); } }; const handlePhotoChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onloadend = async () => { const compressed = await compressImage(reader.result as string); setEditForm({ ...editForm, profile_photo: compressed }); }; reader.readAsDataURL(file); } }; if (loading) return
; const avatarUrl = isEditing ? (editForm.profile_photo || userData?.profile_photo) : userData?.profile_photo; return (
{showSuccess && createPortal(

Profile Updated

Your changes have been saved successfully.

, document.body )}
{/* Left Column: Profile Card */}
Profile {isEditing && (
fileInputRef.current?.click()} className="absolute inset-0 bg-black/50 flex items-center justify-center cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity" >
)}

{userData?.name}

{userRole}

{userData?.email}
{regCount} Registry
{pastEvents.length} Completed
{!isEditing && ( )}
{/* Right Column: Details & Edit Form */}
{/* Personal Information Card */}

Personal Information

{!isEditing && userRole !== 'STUDENT' && ( )}
{isEditing ? (
setEditForm({...editForm, name: e.target.value})} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all" placeholder="Enter your full name" />
setEditForm({...editForm, phone: e.target.value})} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all" placeholder="Enter your phone number" />
setEditForm({...editForm, section: e.target.value.toUpperCase()})} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all" placeholder="e.g. A, B, C" />
{errorMessage && (
{errorMessage}
)}
) : (

{userData?.name}

{userData?.email}

{userData?.phone || 'Not provided'}

{userRole}

{userData?.department && (

{userData.department}

)} {userData?.year && (

{userData.year}

)} {userData?.section && (

{userData.section}

)} {userData?.reg_no && (

{userData.reg_no}

)}
)}
{/* Additional Info / Activity Placeholder */} {!isEditing && (

Recent Activity

{pastEvents.length > 0 ? (
{pastEvents.map((pe, idx) => (

{pe.events?.title || 'Unknown Event'}

{pe.events?.category} • Completed on {new Date(pe.participation_date).toLocaleDateString()}

))}
) : (

No participation history yet

Events you participate in will appear here.

)}
)}
); }; export default ProfileView;