import { headers } from 'next/headers'; import { auth } from '@/lib/auth'; import { publicBaseUrl } from '@/lib/config'; import { prisma } from '@/lib/db'; import { loadSettings } from '@/lib/schedule/context'; import SettingsForm, { type DeviceRow } from './SettingsForm'; export const metadata = { title: 'Paramètres — ITA ITO' }; /** The audit trail is a log, not a database browser: the last fifty suffice. */ const AUDIT_LIMIT = 50; export default async function SettingsPage() { const [session, settings, headerList] = await Promise.all([auth(), loadSettings(), headers()]); const [devices, audit] = await Promise.all([ prisma.device.findMany({ orderBy: { createdAt: 'asc' } }), prisma.auditLog.findMany({ orderBy: { createdAt: 'desc' }, take: AUDIT_LIMIT }), ]); // Reconstructed from the incoming request so the value shown is the one the // device would actually have to reach. const baseUrl = publicBaseUrl( new Request('https://placeholder.invalid', { headers: headerList }), ); const deviceRows: DeviceRow[] = devices.map((device) => ({ id: device.id, friendlyId: device.friendlyId, macAddress: device.macAddress, lastSeenAt: device.lastSeenAt ? device.lastSeenAt.toLocaleString('fr-CH') : null, fwVersion: device.fwVersion, })); return (

Paramètres

Journal d’audit

Les {AUDIT_LIMIT} dernières actions. Qui a changé quoi, et quand.

{audit.length === 0 ? (

Aucune action enregistrée.

) : (
    {audit.map((entry) => (
  • {entry.createdAt.toLocaleString('fr-CH')} {entry.action} {entry.userEmail}
    {entry.diff ? (
      {Object.entries(entry.diff as Record).map( ([field, change]) => (
    • {field} :{' '} {render(change.before)} → {render(change.after)}
    • ), )}
    ) : null}
  • ))}
)}
); } function render(value: unknown): string { if (value === null || value === undefined) { return '—'; } if (typeof value === 'boolean') { return value ? 'oui' : 'non'; } return String(value); }