import { FC, ReactElement, useEffect, useMemo, useState } from 'react'; import { Link, useNavigate } from 'react-router'; import { useMyTeams, useMyInvitations, useRespondToInvitation, useAuthStore, useWinners, } from '@imphnen-frontend-service/service'; import { toast } from 'sonner'; import { Button } from '@imphnen-frontend-service/ui/atoms'; import { Icon } from '@iconify/react'; import ProfilePage from '../profile/page'; import { encodeWinnerCertificateId } from '../../utils/certificate'; // Team features deadline: 2025-11-30 23:59:00 WIB (UTC+7) const TEAM_FEATURES_DEADLINE = new Date('2025-11-30T16:59:00Z'); // Submission deadline: 2025-12-07 23:59:00 WIB (UTC+7) const SUBMISSION_DEADLINE = new Date('2025-12-07T16:59:00Z'); type Invitation = { id: string; team: { id?: string; name?: string; logo?: string; banner?: string; description?: string; city?: string; visibility?: string; leader_id?: string; }; inviter: { id?: string; fullname?: string; email?: string; avatar?: string; }; }; const DashboardPage: FC = (): ReactElement => { const { session } = useAuthStore(); const navigate = useNavigate(); const [showProfileModal, setShowProfileModal] = useState(false); const [timeLeft, setTimeLeft] = useState<{ days: number; hours: number; minutes: number; seconds: number; } | null>(null); // Check if team features are closed const isTeamFeaturesClosed = new Date() >= TEAM_FEATURES_DEADLINE; // Check if submission deadline passed const isSubmissionDeadlinePassed = new Date() >= SUBMISSION_DEADLINE; // Countdown timer useEffect(() => { if (isSubmissionDeadlinePassed) return; const calculateTimeLeft = () => { const now = new Date(); const difference = SUBMISSION_DEADLINE.getTime() - now.getTime(); if (difference <= 0) { setTimeLeft(null); return; } const days = Math.floor(difference / (1000 * 60 * 60 * 24)); const hours = Math.floor((difference / (1000 * 60 * 60)) % 24); const minutes = Math.floor((difference / 1000 / 60) % 60); const seconds = Math.floor((difference / 1000) % 60); setTimeLeft({ days, hours, minutes, seconds }); }; calculateTimeLeft(); const timer = setInterval(calculateTimeLeft, 1000); return () => clearInterval(timer); }, [isSubmissionDeadlinePassed]); // Lock background scroll when profile modal is open useEffect(() => { if (showProfileModal) { const originalOverflow = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { document.body.style.overflow = originalOverflow || ''; }; } }, [showProfileModal]); const { data: teamsData } = useMyTeams(); const { data: winnersResponse } = useWinners(); const { data: invitationsData } = useMyInvitations(); const { mutateAsync: respondToInvitation } = useRespondToInvitation(); const user = session?.user; const myTeams = teamsData?.data || []; const invitations: Invitation[] = (invitationsData?.data || []) as Invitation[]; const winnerEntry = useMemo(() => { const team = (myTeams[0] as { id?: string } | null | undefined) || null; const winners = winnersResponse?.data || []; if (!team?.id) return null; return winners.find((w) => w.team_id === team.id) || null; }, [myTeams, winnersResponse?.data]); const handleAcceptInvitation = async (invitationId: string) => { try { await respondToInvitation({ invitationId, action: 'accept' }); toast.success('Invitation accepted! You are now a team member.'); } catch (error) { console.error('Failed to accept invitation:', error); toast.error('Failed to accept invitation'); } }; const handleRejectInvitation = async (invitationId: string) => { try { await respondToInvitation({ invitationId, action: 'reject' }); toast.success('Invitation declined'); } catch (error) { console.error('Failed to reject invitation:', error); toast.error('Failed to decline invitation'); } }; return ( <>
Anda dapat generate sertifikat penghargaan dan membagikannya.
Project submissions close on December 7, 2025 at 23:59 WIB
{invitation.team?.name ?? 'Unnamed Team'}
Invited by{' '} {invitation.inviter?.fullname ?? 'Unknown User'}
{team.description}
)}Use the sidebar to browse teams or create your own
{user.bio}