mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 18:23:42 +00:00
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:
parent
899c125a62
commit
ad0bcaf8c1
7 changed files with 347 additions and 67 deletions
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
<div>
|
||||||
<h1 className="text-2xl font-bold">
|
<h1 className="text-2xl font-bold">
|
||||||
{pendingIcdOnly ? 'ICD-Eingabe' : 'Fälle'}
|
{pendingIcdOnly ? 'ICD-Eingabe' : 'Fälle'}
|
||||||
</h1>
|
</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 (
|
||||||
<>
|
<>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
<Button size="sm" variant="outline" onClick={() => setOpen(true)}>
|
<Button size="sm" variant="outline" onClick={() => setOpen(true)}>
|
||||||
Personendaten anfordern
|
Personendaten anfordern
|
||||||
</Button>
|
</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">
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
<div>
|
||||||
<h1 className="text-2xl font-bold">Meine Freigaben</h1>
|
<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,6 +141,8 @@ 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) && (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
@ -114,9 +152,14 @@ export function MyDisclosuresPage() {
|
||||||
<ShieldOff className="size-4 mr-1" />
|
<ShieldOff className="size-4 mr-1" />
|
||||||
Als erledigt markieren
|
Als erledigt markieren
|
||||||
</Button>
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Freigabe vorzeitig beenden — Personendaten werden wieder ausgeblendet</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
{isInactive(dr) && (
|
{isInactive(dr) && (
|
||||||
<>
|
<>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
@ -126,6 +169,11 @@ export function MyDisclosuresPage() {
|
||||||
<RefreshCw className="size-4 mr-1" />
|
<RefreshCw className="size-4 mr-1" />
|
||||||
Erneute Anfrage
|
Erneute Anfrage
|
||||||
</Button>
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Neue Freigabe mit gleicher oder geänderter Begründung beantragen</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
|
@ -135,6 +183,9 @@ export function MyDisclosuresPage() {
|
||||||
<Trash2 className="size-4 mr-1" />
|
<Trash2 className="size-4 mr-1" />
|
||||||
Verwerfen
|
Verwerfen
|
||||||
</Button>
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Diese Freigabe-Anfrage aus Ihrer Liste entfernen</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue