2026-01-30 13:41:32 +01:00
|
|
|
import { Suspense } from 'react'
|
|
|
|
|
import { redirect } from 'next/navigation'
|
|
|
|
|
import { auth } from '@/lib/auth'
|
|
|
|
|
import { prisma } from '@/lib/prisma'
|
|
|
|
|
|
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
|
import { Card, CardContent, CardHeader } from '@/components/ui/card'
|
|
|
|
|
import { Skeleton } from '@/components/ui/skeleton'
|
|
|
|
|
import { SettingsContent } from '@/components/settings/settings-content'
|
|
|
|
|
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
// Categories that only super admins can access
|
|
|
|
|
const SUPER_ADMIN_CATEGORIES = new Set(['AI', 'EMAIL', 'STORAGE', 'SECURITY'])
|
|
|
|
|
|
|
|
|
|
async function SettingsLoader({ isSuperAdmin }: { isSuperAdmin: boolean }) {
|
2026-01-30 13:41:32 +01:00
|
|
|
const settings = await prisma.systemSettings.findMany({
|
|
|
|
|
orderBy: [{ category: 'asc' }, { key: 'asc' }],
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Convert settings array to key-value map
|
|
|
|
|
// For secrets, pass a marker but not the actual value
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
// For non-super-admins, filter out infrastructure categories
|
2026-01-30 13:41:32 +01:00
|
|
|
const settingsMap: Record<string, string> = {}
|
|
|
|
|
settings.forEach((setting) => {
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
if (!isSuperAdmin && SUPER_ADMIN_CATEGORIES.has(setting.category)) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2026-01-30 13:41:32 +01:00
|
|
|
if (setting.isSecret && setting.value) {
|
|
|
|
|
// Pass marker for UI to show "existing" state
|
|
|
|
|
settingsMap[setting.key] = '********'
|
|
|
|
|
} else {
|
|
|
|
|
settingsMap[setting.key] = setting.value
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
return <SettingsContent initialSettings={settingsMap} isSuperAdmin={isSuperAdmin} />
|
2026-01-30 13:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function SettingsSkeleton() {
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
<Skeleton className="h-10 w-full" />
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader>
|
|
|
|
|
<Skeleton className="h-6 w-32" />
|
|
|
|
|
<Skeleton className="h-4 w-64" />
|
|
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent>
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
{[...Array(4)].map((_, i) => (
|
|
|
|
|
<Skeleton key={i} className="h-16 w-full" />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default async function SettingsPage() {
|
|
|
|
|
const session = await auth()
|
|
|
|
|
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
// Only admins (super admin + program admin) can access settings
|
|
|
|
|
if (session?.user?.role !== 'SUPER_ADMIN' && session?.user?.role !== 'PROGRAM_ADMIN') {
|
2026-01-30 13:41:32 +01:00
|
|
|
redirect('/admin')
|
|
|
|
|
}
|
|
|
|
|
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
const isSuperAdmin = session?.user?.role === 'SUPER_ADMIN'
|
|
|
|
|
|
2026-01-30 13:41:32 +01:00
|
|
|
return (
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
{/* Header */}
|
|
|
|
|
<div>
|
|
|
|
|
<h1 className="text-2xl font-semibold tracking-tight">Settings</h1>
|
|
|
|
|
<p className="text-muted-foreground">
|
|
|
|
|
Configure platform settings and preferences
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Content */}
|
|
|
|
|
<Suspense fallback={<SettingsSkeleton />}>
|
Inline filtering results, select-all across pages, country flags, settings RBAC, and inline role changes
- Round detail: add skeleton loading for filtering stats, inline results table
with expandable rows, pagination, override/reinstate, CSV export, and tooltip
on AI summaries button (removes need for separate results page)
- Projects: add select-all-across-pages with Gmail-style banner, show country
flags with tooltip instead of country codes (table + card views), add listAllIds
backend endpoint
- Settings: allow PROGRAM_ADMIN access to settings page, restrict infrastructure
tabs (AI, Email, Storage, Security, Webhooks) to SUPER_ADMIN only
- Members: add inline role change via dropdown submenu in user actions, enforce
role hierarchy (only super admins can modify admin/super-admin roles) in both
backend and UI
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 23:07:38 +01:00
|
|
|
<SettingsLoader isSuperAdmin={isSuperAdmin} />
|
2026-01-30 13:41:32 +01:00
|
|
|
</Suspense>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|