diff --git a/src/app/(admin)/admin/projects/[id]/page.tsx b/src/app/(admin)/admin/projects/[id]/page.tsx
index e8331c9..e56c742 100644
--- a/src/app/(admin)/admin/projects/[id]/page.tsx
+++ b/src/app/(admin)/admin/projects/[id]/page.tsx
@@ -927,7 +927,7 @@ function EvaluationDetailSheet({
if (type === 'section_header') return null
- if (type === 'boolean') {
+ if (type === 'boolean' || type === 'advance') {
return (
{label}
diff --git a/src/app/(jury)/jury/competitions/[roundId]/projects/[projectId]/evaluate/page.tsx b/src/app/(jury)/jury/competitions/[roundId]/projects/[projectId]/evaluate/page.tsx
index 52959f5..bb2a502 100644
--- a/src/app/(jury)/jury/competitions/[roundId]/projects/[projectId]/evaluate/page.tsx
+++ b/src/app/(jury)/jury/competitions/[roundId]/projects/[projectId]/evaluate/page.tsx
@@ -164,7 +164,7 @@ export default function JuryEvaluatePage({ params: paramsPromise }: PageProps) {
id: c.id,
label: c.label,
description: c.description,
- type: type as 'numeric' | 'text' | 'boolean' | 'section_header',
+ type: type as 'numeric' | 'text' | 'boolean' | 'advance' | 'section_header',
weight: c.weight,
minScore,
maxScore,
@@ -352,7 +352,7 @@ export default function JuryEvaluatePage({ params: paramsPromise }: PageProps) {
setIsSubmitting(false)
return
}
- if (c.type === 'boolean' && val === undefined) {
+ if ((c.type === 'boolean' || c.type === 'advance') && val === undefined) {
toast.error(`Please answer "${c.label}"`)
isSubmittingRef.current = false
setIsSubmitting(false)
@@ -657,6 +657,51 @@ export default function JuryEvaluatePage({ params: paramsPromise }: PageProps) {
)
}
+ if (criterion.type === 'advance') {
+ const currentValue = criteriaValues[criterion.id]
+ return (
+
+
+
+ {criterion.description && (
+
{criterion.description}
+ )}
+
+
+
+
+
+
+ )
+ }
+
if (criterion.type === 'boolean') {
const currentValue = criteriaValues[criterion.id]
return (
diff --git a/src/components/forms/evaluation-form.tsx b/src/components/forms/evaluation-form.tsx
index d789c68..ba9fcd6 100644
--- a/src/components/forms/evaluation-form.tsx
+++ b/src/components/forms/evaluation-form.tsx
@@ -42,7 +42,7 @@ import { toast } from 'sonner'
import { CountdownTimer } from '@/components/shared/countdown-timer'
// Define criterion type from the evaluation form JSON
-type CriterionType = 'numeric' | 'text' | 'boolean' | 'section_header'
+type CriterionType = 'numeric' | 'text' | 'boolean' | 'advance' | 'section_header'
interface CriterionCondition {
criterionId: string
@@ -96,7 +96,7 @@ const createEvaluationSchema = (criteria: Criterion[]) => {
criterionFields[c.id] = z.number()
} else if (type === 'text') {
criterionFields[c.id] = z.string()
- } else if (type === 'boolean') {
+ } else if (type === 'boolean' || type === 'advance') {
criterionFields[c.id] = z.boolean()
}
}
@@ -180,7 +180,7 @@ export function EvaluationForm({
defaultCriterionScores[c.id] = typeof existing === 'number' ? existing : Math.ceil((c.scale ?? 5) / 2)
} else if (type === 'text') {
defaultCriterionScores[c.id] = typeof existing === 'string' ? existing : ''
- } else if (type === 'boolean') {
+ } else if (type === 'boolean' || type === 'advance') {
defaultCriterionScores[c.id] = typeof existing === 'boolean' ? existing : false
}
})
@@ -225,7 +225,7 @@ export function EvaluationForm({
} else if (type === 'text') {
const val = watchedScores?.[c.id]
if (typeof val === 'string' && val.length > 0) criteriaDone++
- } else if (type === 'boolean') {
+ } else if (type === 'boolean' || type === 'advance') {
if (touchedCriteria.has(c.id)) criteriaDone++
}
}
@@ -470,6 +470,19 @@ export function EvaluationForm({
)
}
+ // Advance (prominent boolean-valued criterion)
+ if (type === 'advance') {
+ return (
+
+ )
+ }
+
return null
})}
@@ -947,6 +960,88 @@ function BooleanCriterionField({
)
}
+// Advance criterion field component (prominent boolean — "should this project advance?")
+function AdvanceCriterionField({
+ criterion,
+ control,
+ disabled,
+ onTouch,
+}: {
+ criterion: Criterion
+ control: any
+ disabled: boolean
+ onTouch: (criterionId: string) => void
+}) {
+ const trueLabel = criterion.trueLabel || 'Yes'
+ const falseLabel = criterion.falseLabel || 'No'
+
+ return (
+
(
+
+
+
+
+ {criterion.required && (
+ Required
+ )}
+
+ {criterion.description && (
+
+ {criterion.description}
+
+ )}
+
+
+
+
+
+
+ )}
+ />
+ )
+}
+
// Progress indicator component
function ProgressIndicator({
percentage,
diff --git a/src/components/observer/observer-project-detail.tsx b/src/components/observer/observer-project-detail.tsx
index 0b3e03d..c5f721d 100644
--- a/src/components/observer/observer-project-detail.tsx
+++ b/src/components/observer/observer-project-detail.tsx
@@ -737,7 +737,7 @@ export function ObserverProjectDetail({ projectId }: { projectId: string }) {
if (type === 'section_header') return null
- if (type === 'boolean') {
+ if (type === 'boolean' || type === 'advance') {
return (