feat: add all missing fields to project update mutation and edit form
Adds competitionCategory, oceanIssue, institution, geographicZone, wantsMentorship, and foundedAt to the tRPC update mutation input schema and the admin project edit form UI (with CountrySelect + Switch). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,8 @@ import { Input } from '@/components/ui/input'
|
||||
import { Textarea } from '@/components/ui/textarea'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { CountrySelect } from '@/components/ui/country-select'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import {
|
||||
Select,
|
||||
@@ -89,6 +91,13 @@ const updateProjectSchema = z.object({
|
||||
'REJECTED',
|
||||
]),
|
||||
tags: z.array(z.string()),
|
||||
competitionCategory: z.string().optional(),
|
||||
oceanIssue: z.string().optional(),
|
||||
institution: z.string().optional(),
|
||||
country: z.string().optional(),
|
||||
geographicZone: z.string().optional(),
|
||||
wantsMentorship: z.boolean().optional(),
|
||||
foundedAt: z.string().optional(),
|
||||
})
|
||||
|
||||
type UpdateProjectForm = z.infer<typeof updateProjectSchema>
|
||||
@@ -157,6 +166,13 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
description: '',
|
||||
status: 'SUBMITTED',
|
||||
tags: [],
|
||||
competitionCategory: '',
|
||||
oceanIssue: '',
|
||||
institution: '',
|
||||
country: '',
|
||||
geographicZone: '',
|
||||
wantsMentorship: false,
|
||||
foundedAt: '',
|
||||
},
|
||||
})
|
||||
|
||||
@@ -169,6 +185,13 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
description: project.description || '',
|
||||
status: (project.status ?? 'SUBMITTED') as UpdateProjectForm['status'],
|
||||
tags: project.tags || [],
|
||||
competitionCategory: project.competitionCategory || '',
|
||||
oceanIssue: project.oceanIssue || '',
|
||||
institution: project.institution || '',
|
||||
country: project.country || '',
|
||||
geographicZone: project.geographicZone || '',
|
||||
wantsMentorship: project.wantsMentorship ?? false,
|
||||
foundedAt: project.foundedAt ? new Date(project.foundedAt).toISOString().split('T')[0] : '',
|
||||
})
|
||||
}
|
||||
}, [project, form])
|
||||
@@ -229,6 +252,13 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
description: data.description || null,
|
||||
status: data.status,
|
||||
tags: data.tags,
|
||||
competitionCategory: (data.competitionCategory || null) as 'STARTUP' | 'BUSINESS_CONCEPT' | null,
|
||||
oceanIssue: (data.oceanIssue || null) as 'POLLUTION_REDUCTION' | 'CLIMATE_MITIGATION' | 'TECHNOLOGY_INNOVATION' | 'SUSTAINABLE_SHIPPING' | 'BLUE_CARBON' | 'HABITAT_RESTORATION' | 'COMMUNITY_CAPACITY' | 'SUSTAINABLE_FISHING' | 'CONSUMER_AWARENESS' | 'OCEAN_ACIDIFICATION' | 'OTHER' | null,
|
||||
institution: data.institution || null,
|
||||
country: data.country || null,
|
||||
geographicZone: data.geographicZone || null,
|
||||
wantsMentorship: data.wantsMentorship,
|
||||
foundedAt: data.foundedAt ? new Date(data.foundedAt).toISOString() : null,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -438,6 +468,159 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Project Details */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">Project Details</CardTitle>
|
||||
<CardDescription>
|
||||
Additional categorization and metadata for this project
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="competitionCategory"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Competition Category</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value || ''}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select category..." />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="STARTUP">Startup</SelectItem>
|
||||
<SelectItem value="BUSINESS_CONCEPT">Business Concept</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="oceanIssue"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Ocean Issue</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value || ''}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select ocean issue..." />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="POLLUTION_REDUCTION">Pollution Reduction</SelectItem>
|
||||
<SelectItem value="CLIMATE_MITIGATION">Climate Mitigation</SelectItem>
|
||||
<SelectItem value="TECHNOLOGY_INNOVATION">Technology Innovation</SelectItem>
|
||||
<SelectItem value="SUSTAINABLE_SHIPPING">Sustainable Shipping</SelectItem>
|
||||
<SelectItem value="BLUE_CARBON">Blue Carbon</SelectItem>
|
||||
<SelectItem value="HABITAT_RESTORATION">Habitat Restoration</SelectItem>
|
||||
<SelectItem value="COMMUNITY_CAPACITY">Community Capacity</SelectItem>
|
||||
<SelectItem value="SUSTAINABLE_FISHING">Sustainable Fishing</SelectItem>
|
||||
<SelectItem value="CONSUMER_AWARENESS">Consumer Awareness</SelectItem>
|
||||
<SelectItem value="OCEAN_ACIDIFICATION">Ocean Acidification</SelectItem>
|
||||
<SelectItem value="OTHER">Other</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="institution"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Institution</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="Institution or organization" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="country"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Country</FormLabel>
|
||||
<FormControl>
|
||||
<CountrySelect
|
||||
value={field.value || ''}
|
||||
onChange={field.onChange}
|
||||
placeholder="Select country..."
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="geographicZone"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Geographic Zone</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="e.g. Europe, France" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="foundedAt"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Founded Date</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="date" {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="wantsMentorship"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel>Wants Mentorship</FormLabel>
|
||||
<FormDescription>
|
||||
Whether this project team is interested in mentorship
|
||||
</FormDescription>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value ?? false}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Tags */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
|
||||
Reference in New Issue
Block a user