feat: add Impressum and Datenschutz links in sidebar

Legal links at sidebar footer open content in an iframe dialog,
keeping users within the portal instead of navigating away.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
CCS Admin 2026-02-27 16:59:06 +00:00
parent ad0bcaf8c1
commit 4dae529520

View file

@ -1,7 +1,11 @@
import { useState } from 'react'
import { NavLink } from 'react-router-dom'
import { useAuth } from '@/context/AuthContext'
import { cn } from '@/lib/utils'
import { Separator } from '@/components/ui/separator'
import {
Dialog, DialogContent, DialogHeader, DialogTitle,
} from '@/components/ui/dialog'
import dakLogo from '@/assets/DAK_Best-Practice-768x768.png'
import {
LayoutDashboard,
@ -16,6 +20,8 @@ import {
History,
UserCog,
ShieldCheck,
Scale,
ShieldAlert,
} from 'lucide-react'
interface NavItem {
@ -68,8 +74,14 @@ function NavItemLink({ item }: { item: NavItem }) {
)
}
const legalLinks = [
{ label: 'Impressum', icon: Scale, url: 'https://complexcaresolutions.de/impressum/' },
{ label: 'Datenschutz', icon: ShieldAlert, url: 'https://www.complexcaresolutions.de/datenschutzerklaerung/' },
]
export function Sidebar({ className }: { className?: string }) {
const { user, isAdmin } = useAuth()
const [legalDialog, setLegalDialog] = useState<{ title: string; url: string } | null>(null)
const filterItems = (items: NavItem[]) =>
items.filter((item) => {
@ -82,39 +94,72 @@ export function Sidebar({ className }: { className?: string }) {
const visibleAccountItems = filterItems(accountNavItems)
return (
<aside className={cn('flex h-full flex-col gap-4 p-4', className)}>
<NavLink to="/dashboard" className="flex items-center justify-center px-3 py-2">
<img src={dakLogo} alt="DAK Gesundheit" className="h-18 w-auto" />
</NavLink>
<>
<aside className={cn('flex h-full flex-col gap-4 p-4', className)}>
<NavLink to="/dashboard" className="flex items-center justify-center px-3 py-2">
<img src={dakLogo} alt="DAK Gesundheit" className="h-18 w-auto" />
</NavLink>
<nav className="flex flex-col gap-1">
{visibleMainItems.map((item) => (
<NavItemLink key={item.to} item={item} />
))}
</nav>
<nav className="flex flex-col gap-1">
{visibleMainItems.map((item) => (
<NavItemLink key={item.to} item={item} />
))}
</nav>
<Separator />
<nav className="flex flex-col gap-1">
{visibleAccountItems.map((item) => (
<NavItemLink key={item.to} item={item} />
))}
</nav>
<Separator />
<nav className="flex flex-col gap-1">
{visibleAccountItems.map((item) => (
<NavItemLink key={item.to} item={item} />
))}
</nav>
{isAdmin && (
<>
{isAdmin && (
<>
<Separator />
<div className="px-3 py-1">
<span className="text-xs font-semibold uppercase text-muted-foreground tracking-wider">
Administration
</span>
</div>
<nav className="flex flex-col gap-1">
{adminNavItems.map((item) => (
<NavItemLink key={item.to} item={item} />
))}
</nav>
</>
)}
{/* Legal footer — pushed to bottom */}
<div className="mt-auto">
<Separator />
<div className="px-3 py-1">
<span className="text-xs font-semibold uppercase text-muted-foreground tracking-wider">
Administration
</span>
</div>
<nav className="flex flex-col gap-1">
{adminNavItems.map((item) => (
<NavItemLink key={item.to} item={item} />
<nav className="flex flex-col gap-0.5 pt-2">
{legalLinks.map(({ label, icon: Icon, url }) => (
<button
key={label}
onClick={() => setLegalDialog({ title: label, url })}
className="flex items-center gap-3 rounded-lg px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors text-left"
>
<Icon className="h-3.5 w-3.5 shrink-0" />
<span>{label}</span>
</button>
))}
</nav>
</>
)}
</aside>
</div>
</aside>
{/* Legal content dialog */}
<Dialog open={!!legalDialog} onOpenChange={(open) => { if (!open) setLegalDialog(null) }}>
<DialogContent className="max-w-4xl h-[85vh] flex flex-col p-0">
<DialogHeader className="px-6 pt-6 pb-2">
<DialogTitle>{legalDialog?.title}</DialogTitle>
</DialogHeader>
<iframe
src={legalDialog?.url}
className="flex-1 w-full border-0 rounded-b-lg"
title={legalDialog?.title}
/>
</DialogContent>
</Dialog>
</>
)
}