stadtwerke/innungsapp/apps/admin/app/components/LegalPageShell.tsx

355 lines
9.2 KiB
TypeScript

'use client'
import { useEffect, useState, type ReactNode } from 'react'
import Link from 'next/link'
import { Syne } from 'next/font/google'
import { Moon, Sun, ArrowLeft } from 'lucide-react'
const syne = Syne({ subsets: ['latin'], weight: ['400', '500', '600', '700', '800'] })
type LegalPageShellProps = {
title: string
subtitle: string
children: ReactNode
}
export default function LegalPageShell({ title, subtitle, children }: LegalPageShellProps) {
const [theme, setTheme] = useState('theme-light')
useEffect(() => {
const savedTheme = localStorage.getItem('theme')
if (savedTheme) {
setTheme(savedTheme)
}
}, [])
const toggleTheme = () => {
const newTheme = theme === 'theme-dark' ? 'theme-light' : 'theme-dark'
setTheme(newTheme)
localStorage.setItem('theme', newTheme)
}
return (
<>
<style>{`
.theme-light {
--bg: #FAFAFA;
--nav-bg: rgba(250, 250, 250, 0.85);
--ink: #111111;
--ink-muted: rgba(17, 17, 17, 0.62);
--ink-faint: rgba(17, 17, 17, 0.1);
--gold: #C9973A;
--gold-light: #B8862D;
--gold-faint: rgba(201, 151, 58, 0.08);
--card-bg: rgba(255, 255, 255, 0.64);
--glass-border: rgba(17, 17, 17, 0.06);
}
.theme-dark {
--bg: #0C0B09;
--nav-bg: rgba(12, 11, 9, 0.85);
--ink: #EAE6DA;
--ink-muted: rgba(234, 230, 218, 0.58);
--ink-faint: rgba(234, 230, 218, 0.12);
--gold: #C9973A;
--gold-light: #DFB25C;
--gold-faint: rgba(201, 151, 58, 0.16);
--card-bg: rgba(20, 19, 17, 0.45);
--glass-border: rgba(234, 230, 218, 0.08);
}
.legal-page {
min-height: 100vh;
background: var(--bg);
color: var(--ink);
background-image:
radial-gradient(circle at 15% 40%, var(--gold-faint), transparent 28%),
radial-gradient(circle at 84% 22%, var(--gold-faint), transparent 24%);
transition: background 0.25s, color 0.25s;
}
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 40;
height: 64px;
display: flex;
align-items: center;
background: var(--nav-bg);
border-bottom: 1px solid var(--ink-faint);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
}
.nav-inner {
max-width: 1280px;
width: 100%;
margin: 0 auto;
padding: 0 32px;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
font-weight: 800;
font-size: 1.125rem;
letter-spacing: -0.02em;
display: flex;
align-items: center;
}
.logo-accent { color: var(--gold); }
.logo-pro {
font-size: 0.65rem;
background: var(--gold-faint);
color: var(--gold);
padding: 3px 6px;
border-radius: 4px;
margin-left: 8px;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.nav-links {
display: flex;
align-items: center;
gap: 26px;
}
.nav-link {
font-size: 0.875rem;
color: var(--ink-muted);
text-decoration: none;
transition: color 0.15s;
}
.nav-link:hover { color: var(--ink); }
.theme-btn {
background: none;
border: none;
cursor: pointer;
padding: 4px;
display: inline-flex;
align-items: center;
color: var(--ink-muted);
}
.theme-btn:hover { color: var(--ink); }
.back-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--ink-muted);
text-decoration: none;
font-size: 0.875rem;
margin-bottom: 24px;
transition: color 0.15s;
}
.back-link:hover { color: var(--ink); }
.main-wrap {
max-width: 980px;
margin: 0 auto;
padding: 132px 32px 76px;
}
.eyebrow {
font-size: 0.75rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--gold);
font-weight: 600;
margin-bottom: 16px;
}
.page-title {
font-weight: 800;
letter-spacing: -0.03em;
line-height: 0.96;
font-size: clamp(2rem, 5vw, 3.3rem);
margin: 0 0 22px;
color: var(--ink);
}
.page-subtitle {
margin: 0 0 30px;
max-width: 760px;
color: var(--ink-muted);
line-height: 1.7;
font-size: 0.98rem;
}
.legal-card {
background: var(--card-bg);
border: 1px solid var(--glass-border);
border-radius: 18px;
padding: 34px;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
.legal-sections {
display: flex;
flex-direction: column;
gap: 30px;
}
.legal-section h2 {
margin: 0 0 12px;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--gold);
}
.legal-section p {
margin: 0 0 8px;
color: var(--ink);
line-height: 1.7;
font-size: 0.95rem;
}
.legal-section .muted { color: var(--ink-muted); }
.legal-list {
margin: 0;
padding-left: 18px;
color: var(--ink);
}
.legal-list li {
margin-bottom: 6px;
line-height: 1.7;
font-size: 0.95rem;
}
.legal-link {
color: var(--gold);
text-decoration: none;
}
.legal-link:hover {
color: var(--gold-light);
text-decoration: underline;
}
.footer {
border-top: 1px solid var(--ink-faint);
padding: 34px 0;
}
.footer-inner {
max-width: 1280px;
margin: 0 auto;
padding: 0 32px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
}
.footer-copy {
margin: 0;
font-size: 0.75rem;
color: var(--ink-muted);
font-family: Georgia, serif;
}
.footer-links {
display: flex;
gap: 24px;
}
.footer-link {
font-size: 0.8125rem;
color: var(--ink-muted);
text-decoration: none;
transition: color 0.15s;
}
.footer-link:hover { color: var(--ink); }
@media (max-width: 767px) {
.nav-inner,
.main-wrap,
.footer-inner {
padding-left: 18px;
padding-right: 18px;
}
.nav-links .nav-link[data-hide-mobile="true"] { display: none; }
.legal-card { padding: 22px 18px; }
.footer-inner {
flex-direction: column;
align-items: flex-start;
}
}
`}</style>
<div className={`legal-page ${syne.className} ${theme}`}>
<nav className="nav">
<div className="nav-inner">
<Link href="/" className="logo">
Innungs<span className="logo-accent">App</span>{' '}
<span className="logo-pro">PRO</span>
</Link>
<div className="nav-links">
<Link href="/#leistungen" className="nav-link" data-hide-mobile="true">
Leistungen
</Link>
<button
type="button"
onClick={toggleTheme}
className="theme-btn"
aria-label="Theme wechseln"
title={theme === 'theme-dark' ? 'Light Mode' : 'Dark Mode'}
>
{theme === 'theme-dark' ? <Sun size={18} /> : <Moon size={18} />}
</button>
<Link href="/login" className="nav-link">
Login
</Link>
</div>
</div>
</nav>
<main className="main-wrap">
<Link href="/" className="back-link">
<ArrowLeft size={16} />
Zurück zur Startseite
</Link>
<div className="eyebrow">Rechtliches</div>
<h1 className="page-title">{title}</h1>
<p className="page-subtitle">{subtitle}</p>
<div className="legal-card">{children}</div>
</main>
<footer className="footer">
<div className="footer-inner">
<p className="footer-copy">
© {new Date().getFullYear()} InnungsApp SaaS. Alle Rechte vorbehalten.
</p>
<div className="footer-links">
<Link href="/impressum" className="footer-link">
Impressum
</Link>
<Link href="/datenschutz" className="footer-link">
Datenschutz
</Link>
</div>
</div>
</footer>
</div>
</>
)
}