Platform-wide UX fixes: assignment dialog, invalidation, settings, dashboard
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m4s

1. Assignment dialog overhaul: replace raw UUID inputs with searchable
   juror Combobox (shows name, email, capacity) and multi-select project
   checklist with bulk assignment support

2. Query invalidation sweep: fix missing invalidations in
   assignment-preview-sheet (roundAssignment.execute) and
   filtering-dashboard (filtering.finalizeResults) so data refreshes
   without page reload

3. Rename Submissions tab to Document Windows with descriptive
   header explaining upload window configuration

4. Connect 6 disconnected settings: storage_provider, local_storage_path,
   avatar_max_size_mb, allowed_image_types, whatsapp_enabled,
   whatsapp_provider - all now accessible in Settings UI

5. Admin dashboard redesign: branded Editorial Command Center with
   Dark Blue gradient header, colored border-l-4 stat cards, staggered
   animations, 2-column layout, action-required panel, activity timeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt
2026-02-16 16:05:25 +01:00
parent b2279067e2
commit 5965f7889d
7 changed files with 1086 additions and 614 deletions

View File

@@ -25,6 +25,7 @@ import {
ShieldAlert,
Globe,
Webhook,
MessageCircle,
} from 'lucide-react'
import Link from 'next/link'
import { AnimatedCard } from '@/components/shared/animated-container'
@@ -103,8 +104,12 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
])
const storageSettings = getSettingsByKeys([
'storage_provider',
'local_storage_path',
'max_file_size_mb',
'avatar_max_size_mb',
'allowed_file_types',
'allowed_image_types',
])
const securitySettings = getSettingsByKeys([
@@ -147,6 +152,11 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
'anomaly_off_hours_end',
])
const whatsappSettings = getSettingsByKeys([
'whatsapp_enabled',
'whatsapp_provider',
])
const localizationSettings = getSettingsByKeys([
'localization_enabled_locales',
'localization_default_locale',
@@ -183,6 +193,12 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
<Newspaper className="h-4 w-4" />
Digest
</TabsTrigger>
{isSuperAdmin && (
<TabsTrigger value="whatsapp" className="gap-2 shrink-0">
<MessageCircle className="h-4 w-4" />
WhatsApp
</TabsTrigger>
)}
{isSuperAdmin && (
<TabsTrigger value="security" className="gap-2 shrink-0">
<Shield className="h-4 w-4" />
@@ -259,6 +275,12 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
<Newspaper className="h-4 w-4" />
Digest
</TabsTrigger>
{isSuperAdmin && (
<TabsTrigger value="whatsapp" className="justify-start gap-2 w-full px-3 py-2 h-auto data-[state=active]:bg-muted">
<MessageCircle className="h-4 w-4" />
WhatsApp
</TabsTrigger>
)}
</TabsList>
</div>
<div>
@@ -502,6 +524,24 @@ export function SettingsContent({ initialSettings, isSuperAdmin = true }: Settin
</Card>
</AnimatedCard>
</TabsContent>
{isSuperAdmin && (
<TabsContent value="whatsapp" className="space-y-6">
<AnimatedCard>
<Card>
<CardHeader>
<CardTitle>WhatsApp Notifications</CardTitle>
<CardDescription>
Configure WhatsApp messaging for notifications
</CardDescription>
</CardHeader>
<CardContent>
<WhatsAppSettingsSection settings={whatsappSettings} />
</CardContent>
</Card>
</AnimatedCard>
</TabsContent>
)}
</div>{/* end content area */}
</div>{/* end lg:flex */}
</Tabs>
@@ -794,6 +834,29 @@ function AuditSettingsSection({ settings }: { settings: Record<string, string> }
)
}
function WhatsAppSettingsSection({ settings }: { settings: Record<string, string> }) {
return (
<div className="space-y-4">
<SettingToggle
label="Enable WhatsApp Notifications"
description="Send notifications via WhatsApp in addition to email"
settingKey="whatsapp_enabled"
value={settings.whatsapp_enabled || 'false'}
/>
<SettingSelect
label="WhatsApp Provider"
description="Select the API provider for sending WhatsApp messages"
settingKey="whatsapp_provider"
value={settings.whatsapp_provider || 'META'}
options={[
{ value: 'META', label: 'Meta (WhatsApp Business API)' },
{ value: 'TWILIO', label: 'Twilio' },
]}
/>
</div>
)
}
function LocalizationSettingsSection({ settings }: { settings: Record<string, string> }) {
const mutation = useSettingsMutation()
const enabledLocales = (settings.localization_enabled_locales || 'en').split(',')