Jury evaluation UX overhaul + admin review features
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m53s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m53s
- Fix project documents not displaying on jury project page (rewrote MultiWindowDocViewer to use file.listByProject) - Add working download/preview for project files via presigned URLs - Display project tags on jury project detail page - Add autosave for evaluation drafts (debounced 3s + save on unmount/beforeunload) - Support mixed criterion types: numeric scores, yes/no booleans, text responses, section headers - Replace inline criteria editor with rich EvaluationFormBuilder on admin round page - Remove COI dialog from evaluation page - Update AI summary service to handle boolean/text criteria (yes/no counts, text synthesis) - Update EvaluationSummaryCard to show boolean criteria bars and text responses - Add evaluation detail sheet on admin project page (click juror row to view full scores + feedback) - Add Recent Evaluations dashboard widget showing latest jury reviews Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import { ProjectListCompact } from '@/components/dashboard/project-list-compact'
|
||||
import { ActivityFeed } from '@/components/dashboard/activity-feed'
|
||||
import { CategoryBreakdown } from '@/components/dashboard/category-breakdown'
|
||||
import { DashboardSkeleton } from '@/components/dashboard/dashboard-skeleton'
|
||||
import { RecentEvaluations } from '@/components/dashboard/recent-evaluations'
|
||||
|
||||
type DashboardContentProps = {
|
||||
editionId: string
|
||||
@@ -33,6 +34,10 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
|
||||
{ editionId },
|
||||
{ enabled: !!editionId, retry: 1, refetchInterval: 30_000 }
|
||||
)
|
||||
const { data: recentEvals } = trpc.dashboard.getRecentEvaluations.useQuery(
|
||||
{ editionId, limit: 8 },
|
||||
{ enabled: !!editionId, refetchInterval: 30_000 }
|
||||
)
|
||||
|
||||
if (isLoading) {
|
||||
return <DashboardSkeleton />
|
||||
@@ -158,15 +163,21 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
|
||||
<AnimatedCard index={3}>
|
||||
<ProjectListCompact projects={latestProjects} />
|
||||
</AnimatedCard>
|
||||
|
||||
{recentEvals && recentEvals.length > 0 && (
|
||||
<AnimatedCard index={4}>
|
||||
<RecentEvaluations evaluations={recentEvals} />
|
||||
</AnimatedCard>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right Column */}
|
||||
<div className="space-y-6 lg:col-span-4">
|
||||
<AnimatedCard index={4}>
|
||||
<AnimatedCard index={5}>
|
||||
<SmartActions actions={nextActions} />
|
||||
</AnimatedCard>
|
||||
|
||||
<AnimatedCard index={5}>
|
||||
<AnimatedCard index={6}>
|
||||
<ActivityFeed activity={recentActivity} />
|
||||
</AnimatedCard>
|
||||
</div>
|
||||
@@ -175,12 +186,12 @@ export function DashboardContent({ editionId, sessionName }: DashboardContentPro
|
||||
{/* Bottom Full Width */}
|
||||
<div className="grid gap-6 lg:grid-cols-12">
|
||||
<div className="lg:col-span-8">
|
||||
<AnimatedCard index={6}>
|
||||
<AnimatedCard index={7}>
|
||||
<GeographicSummaryCard programId={editionId} />
|
||||
</AnimatedCard>
|
||||
</div>
|
||||
<div className="lg:col-span-4">
|
||||
<AnimatedCard index={7}>
|
||||
<AnimatedCard index={8}>
|
||||
<CategoryBreakdown
|
||||
categories={categoryBreakdown}
|
||||
issues={oceanIssueBreakdown}
|
||||
|
||||
Reference in New Issue
Block a user