import React from 'react'; import { createPortal } from 'react-dom'; import type { Event } from '../../types'; import EventCard from './EventCard'; import { API_BASE_URL } from '../../lib/config'; import { useAuth } from '../../context/AuthContext'; interface RegistrationsViewProps { events: Event[]; bookedEventIds: string[]; userRegistrations: any[]; onToggleBooking: (id: string) => void; onTrackStatus: (event: Event) => void; currentUserName: string; userRole?: string; } const Portal: React.FC<{ children: React.ReactNode }> = ({ children }) => { return createPortal(children, document.body); }; const RegistrationsView: React.FC = ({ events, bookedEventIds, userRegistrations, onToggleBooking, onTrackStatus, currentUserName, userRole }) => { const { user } = useAuth(); const [showInspectModal, setShowInspectModal] = React.useState<{eventId: string, title: string, teamCode: string} | null>(null); const [showRemoveConfirm, setShowRemoveConfirm] = React.useState<{member: any, eventId: string, teamCode: string} | null>(null); const [showRemoveSuccess, setShowRemoveSuccess] = React.useState<{name: string} | null>(null); const [showDisbandConfirm, setShowDisbandConfirm] = React.useState<{eventId: string, teamCode: string} | null>(null); const [showLeaveConfirm, setShowLeaveConfirm] = React.useState<{eventId: string} | null>(null); const [teamMembers, setTeamMembers] = React.useState([]); const [isProcessing, setIsProcessing] = React.useState(false); const [copyingCode, setCopyingCode] = React.useState(null); const bookedEvents = events.filter(e => bookedEventIds.includes(e.id)); const handleCopyCode = async (code: string) => { try { await navigator.clipboard.writeText(code); setCopyingCode(code); setTimeout(() => setCopyingCode(null), 2000); } catch (err) { console.error("Copy failed", err); } }; const executeLeaveTeam = async (eventId: string) => { if (!user) return; setIsProcessing(true); try { const registrationId = `${user.id}_${eventId}`; const res = await fetch(`${API_BASE_URL}/api/registrations/${registrationId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ team_code: null, team_name: null, is_team_leader: false }) }); if (!res.ok) throw new Error("Failed to leave team"); setShowLeaveConfirm(null); setShowInspectModal(null); window.location.reload(); } catch (err) { console.error(err); alert("Failed to leave team"); } finally { setIsProcessing(false); } }; const executeDisbandTeam = async (eventId: string, code: string) => { setIsProcessing(true); try { // Fetch all members of this team const resMembers = await fetch(`${API_BASE_URL}/api/registrations?eventId=${eventId}&teamCode=${code}`); const members = resMembers.ok ? await resMembers.json() : []; // Update all members to disband for (const m of members) { const regId = m.id || `${m.userId || m.user_id}_${eventId}`; await fetch(`${API_BASE_URL}/api/registrations/${regId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ team_code: null, team_name: null, is_team_leader: false }) }); } setShowDisbandConfirm(null); setShowInspectModal(null); window.location.reload(); } catch (err) { console.error(err); alert("Failed to disband team"); } finally { setIsProcessing(false); } }; const handleInspectTeam = async (eventId: string, code: string, title: string) => { setIsProcessing(true); try { const res = await fetch(`${API_BASE_URL}/api/registrations?eventId=${eventId}&teamCode=${code}`); if (!res.ok) throw new Error("Failed to fetch team roster"); const members = await res.json(); const formattedMembers = members.map((m: any) => ({ user_id: m.userId || m.user_id, name: m.userName || m.user_name, reg_no: m.regNo || m.reg_no, year: m.year, department: m.dept || m.department, section: m.section, is_team_leader: m.isTeamLeader || m.is_team_leader })); setTeamMembers(formattedMembers); setShowInspectModal({ eventId, title, teamCode: code }); } catch (err) { console.error(err); alert("Failed to fetch team members"); } finally { setIsProcessing(false); } }; return (

My Registrations

{bookedEvents.length > 0 ? (
{bookedEvents.map(event => { const reg = userRegistrations.find(r => String(r.eventId || r.event_id) === String(event.id)); const teamCodeVal = reg?.teamCode || reg?.team_code; const teamNameVal = reg?.teamName || reg?.team_name; const isLeaderVal = reg?.isTeamLeader || reg?.is_team_leader; return (
onToggleBooking(event.id)} onTrackStatus={onTrackStatus} currentUserName={currentUserName} userRole={userRole} registration={reg} /> {event.isTeamEvent && (
{teamCodeVal ? (
Status: Teamed Up

{teamNameVal}

CODE: {teamCodeVal}

) : (
Team Required

Please use the "Track Progress" button to manage your team for this event.

)}
)}
); })}
) : (

You haven't booked any events yet, or your previously registered events have been removed.

)} {showInspectModal && (

Team Roster

Code: {showInspectModal.teamCode} | {showInspectModal.title}

{teamMembers.map((member, idx) => { const isLeader = teamMembers.find(m => m.is_team_leader && m.name === currentUserName); return (

{member.name}

{member.is_team_leader && Leader}

{member.reg_no}

{member.department}

{member.year} • SEC {member.section}

{isLeader && !member.is_team_leader && ( )}
); })}
{teamMembers.find(m => m.is_team_leader && m.name === currentUserName) ? ( ) : ( )}
{/* Confirmation Modals (Portaled to prevent clipping) */} {showRemoveConfirm && (

Remove Member?

Are you sure you want to remove {showRemoveConfirm.member.name} from the team?

)} {showRemoveSuccess && (

Member Removed

{showRemoveSuccess.name} has been removed.

)} {showLeaveConfirm && (

Leave Team?

Are you sure you want to leave this team?

)} {showDisbandConfirm && (

Disband Team?

Are you sure? This will disband the team for ALL members.

)}
)}
); }; export default RegistrationsView;