Platform-wide UX fixes: assignment dialog, invalidation, settings, dashboard
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m4s
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:
@@ -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(',')
|
||||
|
||||
Reference in New Issue
Block a user