Add dynamic apply wizard customization with admin settings UI
- Create wizard config types, utilities, and defaults (wizard-config.ts) - Add admin apply settings page with drag-and-drop step ordering, dropdown option management, feature toggles, welcome message customization, and custom field builder with select/multiselect options editor - Build dynamic apply wizard component with animated step transitions, mobile-first responsive design, and config-driven form validation - Update step components to accept dynamic config (categories, ocean issues, field visibility, feature flags) - Replace hardcoded enum validation with string-based validation for admin-configurable dropdown values, with safe enum casting at storage layer - Add wizard template system (model, router, admin UI) with built-in MOPC Classic preset - Add program wizard config CRUD procedures to program router - Update application router getConfig to return wizardConfig, submit handler to store custom field data in metadataJson - Add edition-based apply page, project pool page, and supporting routers - Fix CSS (invalid sm:fixed-none), Enter key handler (skip textarea), safe area insets for notched phones, buildStepsArray field visibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { Card, CardContent } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { EvaluationFormWithCOI } from '@/components/forms/evaluation-form-with-coi'
|
||||
import { CollapsibleFilesSection } from '@/components/jury/collapsible-files-section'
|
||||
import { ArrowLeft, AlertCircle, Clock, FileText, Users } from 'lucide-react'
|
||||
import { isFuture, isPast } from 'date-fns'
|
||||
|
||||
@@ -76,6 +77,9 @@ async function EvaluateContent({ projectId }: { projectId: string }) {
|
||||
where: { id: projectId },
|
||||
include: {
|
||||
files: true,
|
||||
_count: {
|
||||
select: { files: true },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -266,6 +270,13 @@ async function EvaluateContent({ projectId }: { projectId: string }) {
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Project Files */}
|
||||
<CollapsibleFilesSection
|
||||
projectId={project.id}
|
||||
roundId={round.id}
|
||||
fileCount={project._count?.files || 0}
|
||||
/>
|
||||
|
||||
{/* Evaluation Form with COI Gate */}
|
||||
<EvaluationFormWithCOI
|
||||
assignmentId={assignment.id}
|
||||
|
||||
@@ -16,7 +16,8 @@ import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { FileViewer, FileViewerSkeleton } from '@/components/shared/file-viewer'
|
||||
import { FileViewerSkeleton } from '@/components/shared/file-viewer'
|
||||
import { ProjectFilesSection } from '@/components/jury/project-files-section'
|
||||
import {
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
@@ -255,7 +256,9 @@ async function ProjectContent({ projectId }: { projectId: string }) {
|
||||
</Card>
|
||||
|
||||
{/* Files */}
|
||||
<FileViewer files={project.files} />
|
||||
<Suspense fallback={<FileViewerSkeleton />}>
|
||||
<ProjectFilesSection projectId={project.id} roundId={assignment.roundId} />
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{/* Sidebar */}
|
||||
|
||||
Reference in New Issue
Block a user