import { FC, ReactElement, useState } from 'react'; import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; import { Button, Textarea } from '@imphnen-frontend-service/ui/atoms'; import { useNavigate } from 'react-router'; import { useForm, Controller } from 'react-hook-form'; import { teamCreateSchema, TTeamCreateForm, useCreateTeam, ETeamVisibility, useUploadFile } from '@imphnen-frontend-service/service'; import { zodResolver } from '@hookform/resolvers/zod'; import { toast } from 'sonner'; import { Icon } from '@iconify/react'; import { CitySelect } from '../../../components/city-select'; const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2MB // Team features deadline: 2025-11-30 23:59:00 WIB (UTC+7) const TEAM_FEATURES_DEADLINE = new Date('2025-11-30T16:59:00Z'); const CreateTeamPage: FC = (): ReactElement => { const navigate = useNavigate(); // Check if team features are closed const isTeamFeaturesClosed = new Date() >= TEAM_FEATURES_DEADLINE; const [logoFile, setLogoFile] = useState(null); const [logoPreview, setLogoPreview] = useState(''); const [bannerFile, setBannerFile] = useState(null); const [bannerPreview, setBannerPreview] = useState(''); const form = useForm({ resolver: zodResolver(teamCreateSchema), mode: 'all', defaultValues: { visibility: ETeamVisibility.PUBLIC, logo: null, banner: null, }, }); const { mutateAsync: createTeam, isPending: isCreating } = useCreateTeam(); const { mutateAsync: uploadFile, isPending: isUploading } = useUploadFile(); const handleLogoChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { if (file.size > MAX_FILE_SIZE) { toast.error('Logo image is too large. Maximum size is 2MB.'); e.target.value = ''; return; } setLogoFile(file); const reader = new FileReader(); reader.onloadend = () => { setLogoPreview(reader.result as string); }; reader.readAsDataURL(file); } }; const handleBannerChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { if (file.size > MAX_FILE_SIZE) { toast.error('Banner image is too large. Maximum size is 2MB.'); e.target.value = ''; return; } setBannerFile(file); const reader = new FileReader(); reader.onloadend = () => { setBannerPreview(reader.result as string); }; reader.readAsDataURL(file); } }; const onSubmit = form.handleSubmit(async (data) => { try { let logoUrl = null; let bannerUrl = null; if (logoFile) { const logoResult = await uploadFile(logoFile); logoUrl = logoResult.data.url; } if (bannerFile) { const bannerResult = await uploadFile(bannerFile); bannerUrl = bannerResult.data.url; } const result = await createTeam({ ...data, logo: logoUrl, banner: bannerUrl, }); toast.success('Team created successfully!'); navigate(`/teams/${result.data.id}`); } catch (error: any) { console.error('Failed to create team:', error); // Handle specific error messages const message = error?.message || ''; if (message.includes('413') || message.includes('length limit') || message.includes('too large')) { toast.error('Image file is too large. Please use smaller images (max 2MB each).'); } else if (message.includes('already a member')) { toast.error(message); } else { toast.error(message || 'Failed to create team. Please try again.'); } } }); // Show closed screen if team features are closed if (isTeamFeaturesClosed) { return (

Team Features Closed

Team creation is no longer available.

The deadline for team features was November 30, 2025 at 23:59 WIB.

); } return (
{/* Header */}

Create Your Team

Build your hackathon dream team

{/* Banner Upload */}
{bannerPreview ? (
Banner preview
) : ( )}
{/* Logo Upload */}
{logoPreview ? ( Logo preview ) : (
👥
)}
{logoPreview && ( )}

Max 2MB

{/* Team Name */} {/* City */}
( )} />
{/* Description */}
(