Fix pipeline config crashes, settings UX, invite roles, seed expertise tags

- Fix critical crash when clicking Edit on INTAKE stage configs: normalize
  DB fileRequirements shape (type/required → acceptedMimeTypes/isRequired),
  add null guard in getActiveCategoriesFromMimeTypes
- Fix config summary display for all stage types to handle seed data key
  mismatches (votingEnabled→juryVotingEnabled, minAssignmentsPerJuror→
  minLoadPerJuror, deterministic.rules→rules, etc.)
- Add AWARD_MASTER role to invite page dropdown and user router validations
- Restructure settings sidebar: Tags and Webhooks as direct links instead
  of nested tabs, remove redundant Quick Links section
- Seed 38 expertise tags across 7 categories (Marine Science, Technology,
  Policy, Conservation, Business, Education, Engineering)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 11:40:44 +01:00
parent ae0ac58547
commit c88f540633
7 changed files with 187 additions and 118 deletions

View File

@@ -27,7 +27,6 @@ import {
Webhook,
} from 'lucide-react'
import Link from 'next/link'
import { Button } from '@/components/ui/button'
import { AnimatedCard } from '@/components/shared/animated-container'
import { AISettingsForm } from './ai-settings-form'
import { AIUsageCard } from './ai-usage-card'
@@ -199,10 +198,10 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
AI
</TabsTrigger>
)}
<TabsTrigger value="tags" className="gap-2 shrink-0">
<Link href="/admin/settings/tags" className="inline-flex items-center justify-center gap-2 shrink-0 rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
<Tags className="h-4 w-4" />
Tags
</TabsTrigger>
</Link>
<TabsTrigger value="analytics" className="gap-2 shrink-0">
<BarChart3 className="h-4 w-4" />
Analytics
@@ -213,6 +212,12 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
Storage
</TabsTrigger>
)}
{isSuperAdmin && (
<Link href="/admin/settings/webhooks" className="inline-flex items-center justify-center gap-2 shrink-0 rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring">
<Webhook className="h-4 w-4" />
Webhooks
</Link>
)}
</TabsList>
<div className="lg:flex lg:gap-8">
@@ -279,10 +284,11 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
AI
</TabsTrigger>
)}
<TabsTrigger value="tags" className="justify-start gap-2 w-full px-3 py-2 h-auto data-[state=active]:bg-muted">
<Link href="/admin/settings/tags" className="inline-flex items-center justify-start gap-2 w-full px-3 py-2 rounded-md text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors">
<Tags className="h-4 w-4" />
Tags
</TabsTrigger>
<ExternalLink className="ml-auto h-3 w-3 opacity-50" />
</Link>
<TabsTrigger value="analytics" className="justify-start gap-2 w-full px-3 py-2 h-auto data-[state=active]:bg-muted">
<BarChart3 className="h-4 w-4" />
Analytics
@@ -298,6 +304,11 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
Storage
</TabsTrigger>
</TabsList>
<Link href="/admin/settings/webhooks" className="inline-flex items-center justify-start gap-2 w-full px-3 py-2 rounded-md text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors">
<Webhook className="h-4 w-4" />
Webhooks
<ExternalLink className="ml-auto h-3 w-3 opacity-50" />
</Link>
</div>
)}
</nav>
@@ -325,40 +336,6 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
</TabsContent>
)}
<TabsContent value="tags">
<AnimatedCard>
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Tags className="h-5 w-5" />
Expertise Tags
</CardTitle>
<CardDescription>
Manage tags used for jury expertise, project categorization, and AI-powered matching
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-sm text-muted-foreground">
Expertise tags are used across the platform to:
</p>
<ul className="text-sm text-muted-foreground list-disc list-inside space-y-1">
<li>Categorize jury members by their areas of expertise</li>
<li>Tag projects for better organization and filtering</li>
<li>Power AI-based project tagging</li>
<li>Enable smart jury-project matching</li>
</ul>
<Button asChild>
<Link href="/admin/settings/tags">
<Tags className="mr-2 h-4 w-4" />
Manage Expertise Tags
<ExternalLink className="ml-2 h-3 w-3" />
</Link>
</Button>
</CardContent>
</Card>
</AnimatedCard>
</TabsContent>
<TabsContent value="branding">
<AnimatedCard>
<Card>
@@ -528,31 +505,6 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
</div>{/* end lg:flex */}
</Tabs>
{/* Quick Links to sub-pages */}
<div className="grid gap-4 sm:grid-cols-2">
{isSuperAdmin && (
<Card className="transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md">
<CardHeader>
<CardTitle className="text-base flex items-center gap-2">
<Webhook className="h-4 w-4" />
Webhooks
</CardTitle>
<CardDescription>
Configure webhook endpoints for platform events
</CardDescription>
</CardHeader>
<CardContent>
<Button asChild>
<Link href="/admin/settings/webhooks">
<Webhook className="mr-2 h-4 w-4" />
Manage Webhooks
<ExternalLink className="ml-2 h-3 w-3" />
</Link>
</Button>
</CardContent>
</Card>
)}
</div>
</>
)
}