'use client' import { Suspense, useState } from 'react' import Link from 'next/link' import { useRouter, useSearchParams } from 'next/navigation' import { trpc } from '@/lib/trpc/client' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Skeleton } from '@/components/ui/skeleton' import { TagInput } from '@/components/shared/tag-input' import { toast } from 'sonner' import { ArrowLeft, Save, Loader2, AlertCircle, FolderPlus, Plus, X, } from 'lucide-react' function NewProjectPageContent() { const router = useRouter() const searchParams = useSearchParams() const roundIdParam = searchParams.get('round') const [selectedRoundId, setSelectedRoundId] = useState(roundIdParam || '') // Form state const [title, setTitle] = useState('') const [teamName, setTeamName] = useState('') const [description, setDescription] = useState('') const [tags, setTags] = useState([]) const [contactEmail, setContactEmail] = useState('') const [contactName, setContactName] = useState('') const [country, setCountry] = useState('') const [customFields, setCustomFields] = useState<{ key: string; value: string }[]>([]) // Fetch active programs with rounds const { data: programs, isLoading: loadingPrograms } = trpc.program.list.useQuery({ status: 'ACTIVE', includeRounds: true, }) // Create mutation const createProject = trpc.project.create.useMutation({ onSuccess: () => { toast.success('Project created successfully') router.push(`/admin/projects?round=${selectedRoundId}`) }, onError: (error) => { toast.error(error.message) }, }) // Get all rounds from programs const rounds = programs?.flatMap((p) => (p.rounds || []).map((r) => ({ ...r, programName: p.name, })) ) || [] const selectedRound = rounds.find((r) => r.id === selectedRoundId) const addCustomField = () => { setCustomFields([...customFields, { key: '', value: '' }]) } const updateCustomField = (index: number, key: string, value: string) => { const newFields = [...customFields] newFields[index] = { key, value } setCustomFields(newFields) } const removeCustomField = (index: number) => { setCustomFields(customFields.filter((_, i) => i !== index)) } const handleSubmit = () => { if (!title.trim()) { toast.error('Please enter a project title') return } if (!selectedRoundId) { toast.error('Please select a round') return } // Build metadata const metadataJson: Record = {} if (contactEmail) metadataJson.contactEmail = contactEmail if (contactName) metadataJson.contactName = contactName if (country) metadataJson.country = country // Add custom fields customFields.forEach((field) => { if (field.key.trim() && field.value.trim()) { metadataJson[field.key.trim()] = field.value.trim() } }) createProject.mutate({ roundId: selectedRoundId, title: title.trim(), teamName: teamName.trim() || undefined, description: description.trim() || undefined, tags: tags.length > 0 ? tags : undefined, metadataJson: Object.keys(metadataJson).length > 0 ? metadataJson : undefined, }) } if (loadingPrograms) { return } return (
{/* Header */}

Add Project

Manually create a new project submission

{/* Round selection */} {!selectedRoundId ? ( Select Round Choose the round for this project submission {rounds.length === 0 ? (

No Active Rounds

Create a round first before adding projects

) : ( <> )}
) : ( <> {/* Selected round info */}

{selectedRound?.programName}

{selectedRound?.name}

{/* Basic Info */} Project Details Basic information about the project
setTitle(e.target.value)} placeholder="e.g., Ocean Cleanup Initiative" />
setTeamName(e.target.value)} placeholder="e.g., Blue Ocean Foundation" />