feat: add tooltips and explanatory text for DAK-Mitarbeiter pages

Add contextual tooltips on table headers, KPI cards, status badges,
and action buttons across Dashboard, Cases, Wochenübersicht, Reports,
and My Disclosures pages. Wrap global TooltipProvider in App.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
CCS Admin 2026-02-27 16:12:59 +00:00
parent 899c125a62
commit ad0bcaf8c1
7 changed files with 347 additions and 67 deletions

View file

@ -1,5 +1,6 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { TooltipProvider } from '@/components/ui/tooltip'
import { AuthProvider } from '@/context/AuthContext' import { AuthProvider } from '@/context/AuthContext'
import { ProtectedRoute } from '@/components/layout/ProtectedRoute' import { ProtectedRoute } from '@/components/layout/ProtectedRoute'
import { AppLayout } from '@/components/layout/AppLayout' import { AppLayout } from '@/components/layout/AppLayout'
@ -33,6 +34,7 @@ const queryClient = new QueryClient({
function App() { function App() {
return ( return (
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<TooltipProvider>
<BrowserRouter> <BrowserRouter>
<AuthProvider> <AuthProvider>
<Routes> <Routes>
@ -58,6 +60,7 @@ function App() {
</Routes> </Routes>
</AuthProvider> </AuthProvider>
</BrowserRouter> </BrowserRouter>
</TooltipProvider>
</QueryClientProvider> </QueryClientProvider>
) )
} }

View file

@ -18,7 +18,7 @@ import {
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert' import { Alert, AlertDescription } from '@/components/ui/alert'
import { import {
Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip' } from '@/components/ui/tooltip'
export function AdminInvitationsPage() { export function AdminInvitationsPage() {
@ -120,7 +120,6 @@ export function AdminInvitationsPage() {
))} ))}
</div> </div>
) : invitations.length > 0 ? ( ) : invitations.length > 0 ? (
<TooltipProvider>
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
@ -177,7 +176,6 @@ export function AdminInvitationsPage() {
})} })}
</TableBody> </TableBody>
</Table> </Table>
</TooltipProvider>
) : ( ) : (
<p className="py-8 text-center text-muted-foreground"> <p className="py-8 text-center text-muted-foreground">
Keine Einladungen vorhanden. Keine Einladungen vorhanden.

View file

@ -1,6 +1,6 @@
import { useState, useEffect, useCallback, useRef } from 'react' import { useState, useEffect, useCallback, useRef } from 'react'
import { import {
Search, ChevronLeft, ChevronRight, Save, CheckCircle, XCircle, Pencil, X, Search, ChevronLeft, ChevronRight, Save, CheckCircle, XCircle, Pencil, X, Info,
} from 'lucide-react' } from 'lucide-react'
import type { Case } from '@/types' import type { Case } from '@/types'
import { useAuth } from '@/context/AuthContext' import { useAuth } from '@/context/AuthContext'
@ -19,6 +19,9 @@ import {
} from '@/components/ui/sheet' } from '@/components/ui/sheet'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert' import { Alert, AlertDescription } from '@/components/ui/alert'
import {
Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'
import { CASE_SECTIONS } from './cases/fieldConfig' import { CASE_SECTIONS } from './cases/fieldConfig'
import { useInlineEdit } from './cases/useInlineEdit' import { useInlineEdit } from './cases/useInlineEdit'
import { EditableField } from './cases/EditableField' import { EditableField } from './cases/EditableField'
@ -107,9 +110,16 @@ export function CasesPage({ pendingIcdOnly = false }: CasesPageProps) {
return ( return (
<div className="p-6 space-y-4"> <div className="p-6 space-y-4">
<h1 className="text-2xl font-bold"> <div>
{pendingIcdOnly ? 'ICD-Eingabe' : 'Fälle'} <h1 className="text-2xl font-bold">
</h1> {pendingIcdOnly ? 'ICD-Eingabe' : 'Fälle'}
</h1>
{pendingIcdOnly && (
<p className="text-sm text-muted-foreground mt-1">
Fälle, die noch einen ICD-10-Diagnosecode benötigen. Klicken Sie auf einen Fall, um den Code einzugeben.
</p>
)}
</div>
{/* Filter bar */} {/* Filter bar */}
{!pendingIcdOnly && ( {!pendingIcdOnly && (
@ -169,15 +179,65 @@ export function CasesPage({ pendingIcdOnly = false }: CasesPageProps) {
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>Fall-ID</TableHead> <TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Fall-ID
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Eindeutige Kennung: Jahr-KW-Fallgruppe-KVNR</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>Datum</TableHead> <TableHead>Datum</TableHead>
{isAdmin && <TableHead>Nachname</TableHead>} {isAdmin && <TableHead>Nachname</TableHead>}
{isAdmin && <TableHead>Vorname</TableHead>} {isAdmin && <TableHead>Vorname</TableHead>}
<TableHead>KVNR</TableHead> <TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
KVNR
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Krankenversichertennummer des Versicherten</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>Fallgruppe</TableHead> <TableHead>Fallgruppe</TableHead>
<TableHead>ICD</TableHead> <TableHead>
<TableHead>Gutachten</TableHead> <Tooltip>
<TableHead>Status</TableHead> <TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
ICD
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Internationale Klassifikation der Krankheiten (Diagnosecode)</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Gutachten
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Schriftliche medizinische Stellungnahme vorhanden</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Status
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Aktueller Bearbeitungsstatus des Falls</TooltipContent>
</Tooltip>
</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>
@ -272,11 +332,46 @@ export function CasesPage({ pendingIcdOnly = false }: CasesPageProps) {
function StatusBadges({ c }: { c: Case }) { function StatusBadges({ c }: { c: Case }) {
return ( return (
<div className="flex gap-1"> <div className="flex gap-1">
{c.unterlagen && <Badge variant="secondary" className="text-xs">Unterlagen</Badge>} {c.unterlagen && (
{c.gutachten && <Badge variant="secondary" className="text-xs">Gutachten</Badge>} <Tooltip>
{c.abgerechnet && <Badge className="text-xs">Abgerechnet</Badge>} <TooltipTrigger asChild>
{c.ablehnung && <Badge variant="destructive" className="text-xs">Abgelehnt</Badge>} <Badge variant="secondary" className="text-xs cursor-help">Unterlagen</Badge>
{c.abbruch && <Badge variant="destructive" className="text-xs">Abbruch</Badge>} </TooltipTrigger>
<TooltipContent>Patientenunterlagen wurden eingereicht</TooltipContent>
</Tooltip>
)}
{c.gutachten && (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="secondary" className="text-xs cursor-help">Gutachten</Badge>
</TooltipTrigger>
<TooltipContent>Medizinisches Gutachten wurde erstellt</TooltipContent>
</Tooltip>
)}
{c.abgerechnet && (
<Tooltip>
<TooltipTrigger asChild>
<Badge className="text-xs cursor-help">Abgerechnet</Badge>
</TooltipTrigger>
<TooltipContent>Fall wurde abgerechnet</TooltipContent>
</Tooltip>
)}
{c.ablehnung && (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="destructive" className="text-xs cursor-help">Abgelehnt</Badge>
</TooltipTrigger>
<TooltipContent>Leistung wurde abgelehnt</TooltipContent>
</Tooltip>
)}
{c.abbruch && (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="destructive" className="text-xs cursor-help">Abbruch</Badge>
</TooltipTrigger>
<TooltipContent>Verfahren wurde abgebrochen</TooltipContent>
</Tooltip>
)}
</div> </div>
) )
} }
@ -410,7 +505,15 @@ function CaseDetail({ caseData }: { caseData: Case }) {
{/* ICD section — own endpoint with validation */} {/* ICD section — own endpoint with validation */}
<div className="border-t pt-3 space-y-2"> <div className="border-t pt-3 space-y-2">
<label className="text-sm font-semibold">ICD-Code</label> <Tooltip>
<TooltipTrigger asChild>
<label className="text-sm font-semibold inline-flex items-center gap-1 cursor-help">
ICD-Code
<Info className="size-3 text-muted-foreground" />
</label>
</TooltipTrigger>
<TooltipContent>ICD-10-GM Diagnoseschlüssel, z.B. C50.9 für bösartige Neubildung der Brustdrüse</TooltipContent>
</Tooltip>
<div className="flex gap-2"> <div className="flex gap-2">
<Input <Input
value={icdValue} value={icdValue}
@ -488,9 +591,14 @@ function DisclosureRequestButton({ caseId }: { caseId: number }) {
return ( return (
<> <>
<Button size="sm" variant="outline" onClick={() => setOpen(true)}> <Tooltip>
Personendaten anfordern <TooltipTrigger asChild>
</Button> <Button size="sm" variant="outline" onClick={() => setOpen(true)}>
Personendaten anfordern
</Button>
</TooltipTrigger>
<TooltipContent>Zeitlich begrenzte Freigabe (24h) der Personendaten beantragen</TooltipContent>
</Tooltip>
{open && ( {open && (
<div className="space-y-2 border rounded-lg p-3"> <div className="space-y-2 border rounded-lg p-3">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">

View file

@ -4,7 +4,7 @@ import {
BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend,
PieChart, Pie, Cell, ResponsiveContainer, PieChart, Pie, Cell, ResponsiveContainer,
} from 'recharts' } from 'recharts'
import { FileText, Clock, Code, Stethoscope } from 'lucide-react' import { FileText, Clock, Code, Stethoscope, Info } from 'lucide-react'
import { useAuth } from '@/context/AuthContext' import { useAuth } from '@/context/AuthContext'
import { useDashboard } from '@/hooks/useDashboard' import { useDashboard } from '@/hooks/useDashboard'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
@ -12,6 +12,9 @@ import {
Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from '@/components/ui/select' } from '@/components/ui/select'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import {
Tooltip as UiTooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'
const FALLGRUPPEN_LABELS: Record<string, string> = { const FALLGRUPPEN_LABELS: Record<string, string> = {
onko: 'Onkologie', onko: 'Onkologie',
@ -81,24 +84,28 @@ export function DashboardPage() {
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4"> <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
<KpiCard <KpiCard
title="Fälle gesamt" title="Fälle gesamt"
tooltip="Gesamtzahl aller erfassten Fälle im gewählten Jahr"
value={data.kpis.total_cases} value={data.kpis.total_cases}
icon={<FileText className="size-5 text-muted-foreground" />} icon={<FileText className="size-5 text-muted-foreground" />}
href="/cases" href="/cases"
/> />
<KpiCard <KpiCard
title="Offene ICD" title="Offene ICD"
tooltip="Fälle, denen noch ein ICD-10-Diagnosecode zugewiesen werden muss"
value={data.kpis.pending_icd} value={data.kpis.pending_icd}
icon={<Clock className="size-5 text-muted-foreground" />} icon={<Clock className="size-5 text-muted-foreground" />}
href="/icd" href="/icd"
/> />
<KpiCard <KpiCard
title="Offene Codierung" title="Offene Codierung"
tooltip="Fälle, die noch nicht abschließend klassifiziert wurden"
value={data.kpis.pending_coding} value={data.kpis.pending_coding}
icon={<Code className="size-5 text-muted-foreground" />} icon={<Code className="size-5 text-muted-foreground" />}
href={isAdmin ? '/coding' : undefined} href={isAdmin ? '/coding' : undefined}
/> />
<KpiCard <KpiCard
title="Gutachten gesamt" title="Gutachten gesamt"
tooltip="Anzahl der Fälle mit erstelltem Gutachten"
value={data.kpis.total_gutachten} value={data.kpis.total_gutachten}
icon={<Stethoscope className="size-5 text-muted-foreground" />} icon={<Stethoscope className="size-5 text-muted-foreground" />}
href="/gutachten-statistik" href="/gutachten-statistik"
@ -115,6 +122,7 @@ export function DashboardPage() {
<Card className="lg:col-span-2"> <Card className="lg:col-span-2">
<CardHeader> <CardHeader>
<CardTitle>Wöchentliche Übersicht</CardTitle> <CardTitle>Wöchentliche Übersicht</CardTitle>
<p className="text-xs text-muted-foreground">Ablehnungen, fehlende Rückmeldungen und Gutachten pro Kalenderwoche</p>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<ResponsiveContainer width="100%" height={350}> <ResponsiveContainer width="100%" height={350}>
@ -165,6 +173,7 @@ export function DashboardPage() {
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Fallgruppen</CardTitle> <CardTitle>Fallgruppen</CardTitle>
<p className="text-xs text-muted-foreground">Verteilung der Fälle nach medizinischer Fachgruppe</p>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<ResponsiveContainer width="100%" height={350}> <ResponsiveContainer width="100%" height={350}>
@ -212,11 +221,23 @@ export function DashboardPage() {
) )
} }
function KpiCard({ title, value, icon, href }: { title: string; value: number; icon: React.ReactNode; href?: string }) { function KpiCard({ title, tooltip, value, icon, href }: { title: string; tooltip?: string; value: number; icon: React.ReactNode; href?: string }) {
const card = ( const card = (
<Card className={href ? 'transition-colors hover:border-primary/50 hover:shadow-md' : undefined}> <Card className={href ? 'transition-colors hover:border-primary/50 hover:shadow-md' : undefined}>
<CardHeader className="flex flex-row items-center justify-between pb-2"> <CardHeader className="flex flex-row items-center justify-between pb-2">
<CardTitle className="text-sm font-medium">{title}</CardTitle> <CardTitle className="text-sm font-medium">
{tooltip ? (
<UiTooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help">
{title}
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>{tooltip}</TooltipContent>
</UiTooltip>
) : title}
</CardTitle>
{icon} {icon}
</CardHeader> </CardHeader>
<CardContent> <CardContent>

View file

@ -14,21 +14,52 @@ import {
useMyDisclosures, useRevokeDisclosure, useMyDisclosures, useRevokeDisclosure,
useDeleteDisclosure, useRequestDisclosure, useDeleteDisclosure, useRequestDisclosure,
} from '@/hooks/useDisclosures' } from '@/hooks/useDisclosures'
import {
Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'
import type { DisclosureRequest } from '@/types' import type { DisclosureRequest } from '@/types'
function statusBadge(dr: DisclosureRequest) { function statusBadge(dr: DisclosureRequest) {
const now = new Date() const now = new Date()
if (dr.status === 'pending') { if (dr.status === 'pending') {
return <Badge variant="outline" className="bg-yellow-50 text-yellow-700 border-yellow-300">Ausstehend</Badge> return (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="outline" className="bg-yellow-50 text-yellow-700 border-yellow-300 cursor-help">Ausstehend</Badge>
</TooltipTrigger>
<TooltipContent>Ihre Anfrage wird vom Administrator geprüft</TooltipContent>
</Tooltip>
)
} }
if (dr.status === 'rejected') { if (dr.status === 'rejected') {
return <Badge variant="outline" className="bg-red-50 text-red-700 border-red-300">Abgelehnt</Badge> return (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="outline" className="bg-red-50 text-red-700 border-red-300 cursor-help">Abgelehnt</Badge>
</TooltipTrigger>
<TooltipContent>Der Administrator hat Ihre Anfrage abgelehnt</TooltipContent>
</Tooltip>
)
} }
// approved // approved
if (dr.expires_at && new Date(dr.expires_at) <= now) { if (dr.expires_at && new Date(dr.expires_at) <= now) {
return <Badge variant="outline" className="bg-gray-50 text-gray-500 border-gray-300">Abgelaufen</Badge> return (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="outline" className="bg-gray-50 text-gray-500 border-gray-300 cursor-help">Abgelaufen</Badge>
</TooltipTrigger>
<TooltipContent>Die Freigabe ist nicht mehr gültig</TooltipContent>
</Tooltip>
)
} }
return <Badge variant="outline" className="bg-green-50 text-green-700 border-green-300">Genehmigt</Badge> return (
<Tooltip>
<TooltipTrigger asChild>
<Badge variant="outline" className="bg-green-50 text-green-700 border-green-300 cursor-help">Genehmigt</Badge>
</TooltipTrigger>
<TooltipContent>Personendaten sind bis zum Ablaufdatum sichtbar</TooltipContent>
</Tooltip>
)
} }
function isActive(dr: DisclosureRequest): boolean { function isActive(dr: DisclosureRequest): boolean {
@ -67,7 +98,12 @@ export function MyDisclosuresPage() {
return ( return (
<div className="p-6 space-y-4"> <div className="p-6 space-y-4">
<h1 className="text-2xl font-bold">Meine Freigaben</h1> <div>
<h1 className="text-2xl font-bold">Meine Freigaben</h1>
<p className="text-sm text-muted-foreground mt-1">
Übersicht Ihrer Freigabe-Anfragen für Personendaten. Genehmigte Freigaben sind 24 Stunden gültig.
</p>
</div>
{isLoading ? ( {isLoading ? (
<div className="space-y-2"> <div className="space-y-2">
@ -105,36 +141,51 @@ export function MyDisclosuresPage() {
<TableCell className="text-right"> <TableCell className="text-right">
<div className="flex justify-end gap-1"> <div className="flex justify-end gap-1">
{isActive(dr) && ( {isActive(dr) && (
<Button <Tooltip>
size="sm" <TooltipTrigger asChild>
variant="outline" <Button
disabled={revokeMutation.isPending} size="sm"
onClick={() => revokeMutation.mutate(dr.id)} variant="outline"
> disabled={revokeMutation.isPending}
<ShieldOff className="size-4 mr-1" /> onClick={() => revokeMutation.mutate(dr.id)}
Als erledigt markieren >
</Button> <ShieldOff className="size-4 mr-1" />
Als erledigt markieren
</Button>
</TooltipTrigger>
<TooltipContent>Freigabe vorzeitig beenden Personendaten werden wieder ausgeblendet</TooltipContent>
</Tooltip>
)} )}
{isInactive(dr) && ( {isInactive(dr) && (
<> <>
<Button <Tooltip>
size="sm" <TooltipTrigger asChild>
variant="outline" <Button
disabled={requestMutation.isPending} size="sm"
onClick={() => openReRequestDialog(dr)} variant="outline"
> disabled={requestMutation.isPending}
<RefreshCw className="size-4 mr-1" /> onClick={() => openReRequestDialog(dr)}
Erneute Anfrage >
</Button> <RefreshCw className="size-4 mr-1" />
<Button Erneute Anfrage
size="sm" </Button>
variant="ghost" </TooltipTrigger>
disabled={deleteMutation.isPending} <TooltipContent>Neue Freigabe mit gleicher oder geänderter Begründung beantragen</TooltipContent>
onClick={() => deleteMutation.mutate(dr.id)} </Tooltip>
> <Tooltip>
<Trash2 className="size-4 mr-1" /> <TooltipTrigger asChild>
Verwerfen <Button
</Button> size="sm"
variant="ghost"
disabled={deleteMutation.isPending}
onClick={() => deleteMutation.mutate(dr.id)}
>
<Trash2 className="size-4 mr-1" />
Verwerfen
</Button>
</TooltipTrigger>
<TooltipContent>Diese Freigabe-Anfrage aus Ihrer Liste entfernen</TooltipContent>
</Tooltip>
</> </>
)} )}
</div> </div>

View file

@ -1,5 +1,5 @@
import { Fragment, useState } from 'react' import { Fragment, useState } from 'react'
import { ChevronDown, ChevronRight, Download, FileSpreadsheet, Loader2, Plus, Trash2 } from 'lucide-react' import { ChevronDown, ChevronRight, Download, FileSpreadsheet, Info, Loader2, Plus, Trash2 } from 'lucide-react'
import api from '@/services/api' import api from '@/services/api'
import { useAuth } from '@/context/AuthContext' import { useAuth } from '@/context/AuthContext'
import { useReports, useGenerateReport, useDeleteReports, useReportData } from '@/hooks/useReports' import { useReports, useGenerateReport, useDeleteReports, useReportData } from '@/hooks/useReports'
@ -17,6 +17,9 @@ import {
} from '@/components/ui/select' } from '@/components/ui/select'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert' import { Alert, AlertDescription } from '@/components/ui/alert'
import {
Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'
const REPORT_TYPES = [ const REPORT_TYPES = [
{ value: 'gesamt', label: 'Gesamt' }, { value: 'gesamt', label: 'Gesamt' },
@ -253,10 +256,40 @@ export function ReportsPage() {
/> />
</TableHead> </TableHead>
)} )}
<TableHead>Berichtsdatum</TableHead> <TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Berichtsdatum
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Stichtag des Berichts</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>Jahr</TableHead> <TableHead>Jahr</TableHead>
<TableHead>KW</TableHead> <TableHead>
<TableHead>Typ</TableHead> <Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
KW
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Kalenderwoche des Berichtszeitraums</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Typ
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Berichtstyp: Gesamt, Onko-Intensiv oder Galle-Schild</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>Erstellt am</TableHead> <TableHead>Erstellt am</TableHead>
<TableHead className="text-right">Aktion</TableHead> <TableHead className="text-right">Aktion</TableHead>
</TableRow> </TableRow>

View file

@ -1,5 +1,5 @@
import { Fragment, useCallback, useState } from 'react' import { Fragment, useCallback, useState } from 'react'
import { ChevronDown, ChevronRight, Download, FileSpreadsheet, Loader2, Plus, Upload } from 'lucide-react' import { ChevronDown, ChevronRight, Download, FileSpreadsheet, Info, Loader2, Plus, Upload } from 'lucide-react'
import api from '@/services/api' import api from '@/services/api'
import { useAuth } from '@/context/AuthContext' import { useAuth } from '@/context/AuthContext'
import { import {
@ -21,6 +21,9 @@ import {
} from '@/components/ui/table' } from '@/components/ui/table'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert' import { Alert, AlertDescription } from '@/components/ui/alert'
import {
Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'
const EXPORT_TYPES = [ const EXPORT_TYPES = [
{ value: 'c2s', label: 'Onko-Intensiv (c2s)' }, { value: 'c2s', label: 'Onko-Intensiv (c2s)' },
@ -390,6 +393,9 @@ export function WochenuebersichtPage() {
Laden Sie die ausgefüllte Wochenübersicht mit den ergänzten ICD-Codes hoch. Laden Sie die ausgefüllte Wochenübersicht mit den ergänzten ICD-Codes hoch.
Die ICD-Codes werden automatisch den Fällen anhand der KVNR zugeordnet. Die ICD-Codes werden automatisch den Fällen anhand der KVNR zugeordnet.
</p> </p>
<p className="text-xs text-muted-foreground">
Unterstützte Formate: .xlsx, .xls Die KVNR wird zum Abgleich der Fälle verwendet.
</p>
<div <div
className={`border-2 border-dashed rounded-lg p-8 text-center transition-colors ${ className={`border-2 border-dashed rounded-lg p-8 text-center transition-colors ${
@ -541,15 +547,75 @@ function WochenuebersichtViewer({ data }: { data: Record<string, any> }) {
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>KVNR</TableHead> <TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
KVNR
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Krankenversichertennummer</TooltipContent>
</Tooltip>
</TableHead>
<TableHead>Datum</TableHead> <TableHead>Datum</TableHead>
<TableHead className="text-center">Erstgespräch</TableHead> <TableHead className="text-center">
<TableHead className="text-center">Abbruch</TableHead> <Tooltip>
<TableHead className="text-center">Unterlagen</TableHead> <TooltipTrigger asChild>
<TableHead className="text-center">Gutachten</TableHead> <span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Erstgespräch
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Initialkontakt mit dem Versicherten erfolgt</TooltipContent>
</Tooltip>
</TableHead>
<TableHead className="text-center">
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Abbruch
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Zweitmeinung/Vorbereitung bei Ablehnung oder Abbruch</TooltipContent>
</Tooltip>
</TableHead>
<TableHead className="text-center">
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Unterlagen
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Zweitmeinung/Vorbereitung mit Erteilung</TooltipContent>
</Tooltip>
</TableHead>
<TableHead className="text-center">
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
Gutachten
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Schriftliche Dokumentation (Gutachten) erstellt</TooltipContent>
</Tooltip>
</TableHead>
<TableHead className="text-center">{fg1Label}</TableHead> <TableHead className="text-center">{fg1Label}</TableHead>
<TableHead className="text-center">{fg2Label}</TableHead> <TableHead className="text-center">{fg2Label}</TableHead>
<TableHead>ICD-10</TableHead> <TableHead>
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
ICD-10
<Info className="size-3 text-muted-foreground" />
</span>
</TooltipTrigger>
<TooltipContent>Internationale Klassifikation der Krankheiten</TooltipContent>
</Tooltip>
</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody> <TableBody>