109 lines
3.9 KiB
TypeScript
109 lines
3.9 KiB
TypeScript
|
|
'use client'
|
||
|
|
|
||
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||
|
|
import { Label } from '@/components/ui/label'
|
||
|
|
import { Switch } from '@/components/ui/switch'
|
||
|
|
import { Badge } from '@/components/ui/badge'
|
||
|
|
|
||
|
|
type SubmissionConfigProps = {
|
||
|
|
config: Record<string, unknown>
|
||
|
|
onChange: (config: Record<string, unknown>) => void
|
||
|
|
}
|
||
|
|
|
||
|
|
const STATUSES = [
|
||
|
|
{ value: 'PENDING', label: 'Pending', color: 'bg-gray-100 text-gray-700' },
|
||
|
|
{ value: 'IN_PROGRESS', label: 'In Progress', color: 'bg-blue-100 text-blue-700' },
|
||
|
|
{ value: 'PASSED', label: 'Passed', color: 'bg-emerald-100 text-emerald-700' },
|
||
|
|
{ value: 'REJECTED', label: 'Rejected', color: 'bg-red-100 text-red-700' },
|
||
|
|
{ value: 'COMPLETED', label: 'Completed', color: 'bg-purple-100 text-purple-700' },
|
||
|
|
{ value: 'WITHDRAWN', label: 'Withdrawn', color: 'bg-amber-100 text-amber-700' },
|
||
|
|
]
|
||
|
|
|
||
|
|
export function SubmissionConfig({ config, onChange }: SubmissionConfigProps) {
|
||
|
|
const update = (key: string, value: unknown) => {
|
||
|
|
onChange({ ...config, [key]: value })
|
||
|
|
}
|
||
|
|
|
||
|
|
const eligible = (config.eligibleStatuses as string[]) ?? ['PASSED']
|
||
|
|
|
||
|
|
const toggleStatus = (status: string) => {
|
||
|
|
const current = [...eligible]
|
||
|
|
const idx = current.indexOf(status)
|
||
|
|
if (idx >= 0) {
|
||
|
|
current.splice(idx, 1)
|
||
|
|
} else {
|
||
|
|
current.push(status)
|
||
|
|
}
|
||
|
|
update('eligibleStatuses', current)
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="space-y-6">
|
||
|
|
<Card>
|
||
|
|
<CardHeader>
|
||
|
|
<CardTitle className="text-base">Submission Eligibility</CardTitle>
|
||
|
|
<CardDescription>
|
||
|
|
Which project states from the previous round are eligible to submit documents in this round
|
||
|
|
</CardDescription>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent className="space-y-4">
|
||
|
|
<div className="space-y-2">
|
||
|
|
<Label>Eligible Project Statuses</Label>
|
||
|
|
<p className="text-xs text-muted-foreground">
|
||
|
|
Projects with these statuses from the previous round can submit
|
||
|
|
</p>
|
||
|
|
<div className="flex flex-wrap gap-2">
|
||
|
|
{STATUSES.map((s) => (
|
||
|
|
<Badge
|
||
|
|
key={s.value}
|
||
|
|
variant={eligible.includes(s.value) ? 'default' : 'outline'}
|
||
|
|
className="cursor-pointer select-none"
|
||
|
|
onClick={() => toggleStatus(s.value)}
|
||
|
|
>
|
||
|
|
{s.label}
|
||
|
|
</Badge>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
|
||
|
|
<Card>
|
||
|
|
<CardHeader>
|
||
|
|
<CardTitle className="text-base">Notifications & Locking</CardTitle>
|
||
|
|
<CardDescription>Behavior when the submission round activates</CardDescription>
|
||
|
|
</CardHeader>
|
||
|
|
<CardContent className="space-y-4">
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<div>
|
||
|
|
<Label htmlFor="notifyEligibleTeams">Notify Eligible Teams</Label>
|
||
|
|
<p className="text-xs text-muted-foreground">
|
||
|
|
Send email notification to teams when submission window opens
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<Switch
|
||
|
|
id="notifyEligibleTeams"
|
||
|
|
checked={(config.notifyEligibleTeams as boolean) ?? true}
|
||
|
|
onCheckedChange={(v) => update('notifyEligibleTeams', v)}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="flex items-center justify-between">
|
||
|
|
<div>
|
||
|
|
<Label htmlFor="lockPreviousWindows">Lock Previous Windows</Label>
|
||
|
|
<p className="text-xs text-muted-foreground">
|
||
|
|
Prevent uploads to earlier submission windows when this round activates
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<Switch
|
||
|
|
id="lockPreviousWindows"
|
||
|
|
checked={(config.lockPreviousWindows as boolean) ?? true}
|
||
|
|
onCheckedChange={(v) => update('lockPreviousWindows', v)}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</CardContent>
|
||
|
|
</Card>
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
}
|