import type { Metadata } from 'next'
import Link from 'next/link'
import { db } from '@/lib/db'
import { requireUser } from '@/lib/auth/current'
import { loadDashboard } from '@/lib/dashboard/load'
import { de } from '@/lib/i18n/de'
import { StampMark, classificationEdgeStyle } from '@/components/StampMark'
import { clearRecentAction } from './actions'
import type { RecentEntry } from '@/lib/recent/service'
export const metadata: Metadata = { title: de.dashboard.heading }
export const dynamic = 'force-dynamic'
/**
* Die Übersicht: vier Fragen, die man morgens hat.
*
* Woran arbeite ich, was ist fällig, wo hat jemand geschrieben, was hat sich
* getan. Jede Liste läuft durch dieselbe Sichtbarkeitsprüfung wie die
* Fallliste - das ist der Ort, an dem eine unachtsame Abfrage am ehesten eine
* Akte verrät, die man nicht sehen darf.
*/
export default async function DashboardPage() {
const user = await requireUser()
const [daten, levels] = await Promise.all([
loadDashboard(user.permissions),
db.clearanceLevelConfig.findMany({ orderBy: { level: 'asc' } }),
])
const levelName = new Map(levels.map((l) => [l.level, l.name]))
const heute = new Date()
return (
)
}
/**
* Ein leerer Zustand ohne Satz.
*
* „Noch nichts geöffnet" zu schreiben erklärt nichts, was das leere Feld nicht
* schon zeigt, und nimmt Platz weg, sobald etwas darin steht. Ein ruhiger
* Rahmen mit einem Strich sagt dasselbe und verschwindet von selbst, wenn die
* Liste sich füllt.
*/
function EmptyMark() {
return (
)
}
type Fall = {
id: string
caseNumber: string
title: string
status: string
classification: number
updatedAt: Date
dueAt?: Date | null
}
function Block({
titel,
leer,
eintraege,
children,
}: {
titel: string
leer: string
eintraege: Fall[]
children: (akte: Fall) => React.ReactNode
}) {
return (
{titel}
{eintraege.length === 0 ? (
{leer}
) : (
{eintraege.map((akte) => (
{children(akte)}
))}
)}
)
}
/**
* Eine Zeile der Sprungliste. Sie kann eine Akte, eine Person oder ein
* Dokument sein - deshalb steht die Art nicht dabei, sondern nur das, woran
* man sie erkennt: Aktenzeichen, Name oder Dokumentnummer.
*
* Eine Akte und ein Dokument tragen eine **Kennung**, eine Person nicht: ihr
* Name ist der Titel. Stünde er in der Kennungsspalte, stünde er in Mono, wäre
* abgeschnitten, und der Dienstgrad rutschte dorthin, wo sonst der Titel
* steht - untereinander ergäbe das keine Spalte mehr.
*
* Ohne Vorabruf, anders als die übrigen Listen: die Seiten dahinter merken
* sich, dass sie geöffnet wurden. Der Vorabruf wird zwar serverseitig erkannt
* und zählt nicht mit, aber ausgerechnet diese Liste sollte sich nicht selbst
* am Leben halten können, wenn diese Erkennung einmal nicht greift.
*/
function Sprung({
eintrag,
levelName,
}: {
eintrag: RecentEntry
levelName: Map
}) {
return (
{eintrag.targetType === 'PERSONNEL' ? (
<>
{/* Kein Aktenzeichen, aber auch keine Leerstelle: dort steht, was es
ist. Eine leere Spalte lässt die Zeile wie einen Fehler aussehen. */}
{de.personnel.one}
{eintrag.secondary ? `[${eintrag.secondary}]` : ''}
{eintrag.label}
>
) : (
<>
{eintrag.label}{eintrag.secondary}
>
)}
)
}
function Akte({
akte,
levelName,
zusatz,
dringend,
}: {
akte: Fall
levelName: Map
zusatz?: string
dringend?: boolean
}) {
return (
{akte.caseNumber}{akte.title}{zusatz}
)
}