Impressum und Haftungsausschluss auf der Public Page (Task #27)

Added legally required Impressum and Haftungsausschluss pages plus a global
footer and an inline disclaimer on the scan report.

Changes:
- New page src/pages/impressum.tsx (/impressum) with avameo GmbH legal details
  (address, management, register, tax IDs, content responsible, contact, EU ODR).
- New page src/pages/haftungsausschluss.tsx (/haftungsausschluss) with the
  verbatim SkillGuard disclaimer (no detection guarantee, own responsibility,
  liability limitation).
- Registered both routes in src/App.tsx.
- Added a discreet global footer in src/components/layout.tsx below the main
  content: "© 2026 avameo GmbH" + links to Impressum and Haftungsausschluss.
  Placed inside the existing scroll container so layout/scroll behaviour is intact.
- Added a short inline disclaimer Alert near the risk score on
  src/pages/scan-report.tsx with a link to the Haftungsausschluss page; imported
  ShieldAlert from lucide-react.

All texts are in German and verbatim from the task spec. Pages reuse the app
layout (sidebar) and adapt to dark/light theme.

Notes / deviations:
- Could not render a live scan report to visually confirm the inline disclaimer
  because the dev DB is missing the "scans.description" column (pre-existing
  schema drift from another in-flight task); Impressum, Haftungsausschluss and
  footer were verified via screenshots.
- Pre-existing TypeScript/codegen errors in api-client-react and unrelated test
  failures were left untouched (out of scope).

Replit-Task-Id: 52a25f19-46b2-4882-b754-268225e4680e
This commit is contained in:
amertensreplit 2026-06-10 21:19:05 +00:00
parent 2e9a00f182
commit ef272444a1
5 changed files with 170 additions and 1 deletions

View file

@ -11,6 +11,8 @@ import ScanReport from "@/pages/scan-report";
import ScanCompare from "@/pages/scan-compare";
import ScanHistory from "@/pages/scan-history";
import Admin from "@/pages/admin";
import Impressum from "@/pages/impressum";
import Haftungsausschluss from "@/pages/haftungsausschluss";
const queryClient = new QueryClient();
@ -24,6 +26,8 @@ function Router() {
<Route path="/vergleich/:id/:otherId" component={ScanCompare} />
<Route path="/verlauf" component={ScanHistory} />
<Route path="/admin" component={Admin} />
<Route path="/impressum" component={Impressum} />
<Route path="/haftungsausschluss" component={Haftungsausschluss} />
<Route component={NotFound} />
</Switch>
</AppLayout>

View file

@ -68,6 +68,19 @@ export function AppLayout({ children }: { children: React.ReactNode }) {
<div className="mx-auto max-w-6xl">
{children}
</div>
<footer className="mx-auto max-w-6xl mt-12 pt-6 border-t border-border">
<div className="flex flex-col sm:flex-row items-center justify-between gap-2 text-xs text-muted-foreground">
<span>© 2026 avameo GmbH</span>
<nav className="flex items-center gap-4">
<Link href="/impressum" className="hover:text-foreground transition-colors">
Impressum
</Link>
<Link href="/haftungsausschluss" className="hover:text-foreground transition-colors">
Haftungsausschluss
</Link>
</nav>
</div>
</footer>
</div>
</main>
</div>

View file

@ -0,0 +1,58 @@
import { Card, CardContent } from "@/components/ui/card";
import { ShieldAlert } from "lucide-react";
export default function Haftungsausschluss() {
return (
<div className="space-y-6 pb-12">
<div className="flex flex-col gap-2">
<h1 className="text-3xl font-bold tracking-tight flex items-center gap-3">
<ShieldAlert className="w-7 h-7 text-sidebar-primary" />
Haftungsausschluss
</h1>
</div>
<Card>
<CardContent className="pt-6 space-y-8 text-sm leading-relaxed">
<section className="space-y-2">
<h2 className="font-semibold text-foreground text-base">
Keine Gewähr für die Erkennung kompromittierter Skills
</h2>
<p>
SkillGuard ist ein automatisiertes, unter anderem KI-gestütztes Analysewerkzeug, das Skills
auf potenzielle Sicherheits- und Datenschutzrisiken untersucht. Die Ergebnisse stellen eine
unterstützende Einschätzung dar und sind weder eine abschließende noch eine rechtsverbindliche
Bewertung.
</p>
<p>
Trotz sorgfältiger Analyse kann nicht garantiert werden, dass sämtliche kompromittierten,
schädlichen oder anderweitig riskanten Skills erkannt werden. Ein unauffälliges Prüfergebnis
(z. B. Freigabe") bedeutet nicht, dass der untersuchte Skill frei von Sicherheitslücken,
Schadcode oder Datenschutzverstößen ist. Umgekehrt können Auffälligkeiten gemeldet werden, die
sich im Einzelfall als unkritisch erweisen (Fehlalarme).
</p>
</section>
<section className="space-y-2">
<h2 className="font-semibold text-foreground text-base">Eigenverantwortung</h2>
<p>
Die Nutzung der Analyseergebnisse erfolgt auf eigene Verantwortung. Die Entscheidung über den
Einsatz eines Skills sowie alle daraus resultierenden Folgen liegen allein beim Nutzer.
SkillGuard ersetzt keine manuelle sicherheitstechnische Prüfung durch qualifizierte
Fachpersonen.
</p>
</section>
<section className="space-y-2">
<h2 className="font-semibold text-foreground text-base">Haftungsbeschränkung</h2>
<p>
Eine Haftung für Schäden, die aus der Verwendung oder Nichtverwendung der bereitgestellten
Analyseergebnisse entstehen, ist soweit gesetzlich zulässig ausgeschlossen. Unberührt
bleibt die Haftung für Vorsatz und grobe Fahrlässigkeit sowie für Schäden aus der Verletzung
des Lebens, des Körpers oder der Gesundheit.
</p>
</section>
</CardContent>
</Card>
</div>
);
}

View file

@ -0,0 +1,81 @@
import { Card, CardContent } from "@/components/ui/card";
import { FileText } from "lucide-react";
export default function Impressum() {
return (
<div className="space-y-6 pb-12">
<div className="flex flex-col gap-2">
<h1 className="text-3xl font-bold tracking-tight flex items-center gap-3">
<FileText className="w-7 h-7 text-sidebar-primary" />
Impressum
</h1>
</div>
<Card>
<CardContent className="pt-6 space-y-8 text-sm leading-relaxed">
<section className="space-y-1">
<p className="font-semibold text-base">avameo GmbH</p>
<p>Unter den Eichen 5 G-I</p>
<p>65195 Wiesbaden</p>
<p>Deutschland</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Geschäftsführender Gesellschafter</h2>
<p>Andreas Mertens</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Handelsregistereintrag</h2>
<p>Amtsgericht Wiesbaden</p>
<p>HRB 30601</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Umsatzsteuer-ID gemäß § 27 a Umsatzsteuergesetz</h2>
<p>DE 320 535 191</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Steuernummer</h2>
<p>040 228 90897</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Inhaltlich verantwortlich gemäß § 5 DDG</h2>
<p>Andreas Mertens</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Kontakt</h2>
<p>Telefon: +49 (0) 611 181 77 39</p>
<p>
E-Mail:{" "}
<a href="mailto:office@avameo.de" className="text-sidebar-primary underline underline-offset-4">
office@avameo.de
</a>
</p>
</section>
<section className="space-y-1">
<h2 className="font-semibold text-foreground">Hinweis auf EU-Streitschlichtung</h2>
<p>
Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:
</p>
<p>
<a
href="https://ec.europa.eu/consumers/odr"
target="_blank"
rel="noopener noreferrer"
className="text-sidebar-primary underline underline-offset-4"
>
https://ec.europa.eu/consumers/odr
</a>
</p>
<p>Unsere E-Mail-Adresse finden Sie oben im Impressum.</p>
</section>
</CardContent>
</Card>
</div>
);
}

View file

@ -16,7 +16,7 @@ import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { VerdictBadge, SeverityBadge, AxisBadge, CheckpointStatusBadge, CHECKPOINT_STATUS_LABELS, RelationBadge } from "@/components/ui-helpers";
import { formatDate } from "@/lib/format";
import { ShieldQuestion, AlertTriangle, Download, FileCode, CheckCircle2, Code, Shield, FileDown, ListChecks, Fingerprint, GitCompare, History, GitCommitVertical, Sparkles } from "lucide-react";
import { ShieldQuestion, ShieldAlert, AlertTriangle, Download, FileCode, CheckCircle2, Code, Shield, FileDown, ListChecks, Fingerprint, GitCompare, History, GitCommitVertical, Sparkles } from "lucide-react";
import type { ScanDetail } from "@workspace/api-client-react";
export default function ScanReport() {
@ -158,6 +158,19 @@ export default function ScanReport() {
</Card>
)}
<Alert className="bg-blue-50 text-blue-900 border-blue-200 dark:bg-blue-950/40 dark:text-blue-200 dark:border-blue-900">
<ShieldAlert className="h-4 w-4" />
<AlertDescription className="text-sm leading-relaxed">
Hinweis: Dieses Ergebnis ist eine automatisierte, KI-gestützte Einschätzung. Es kann nicht
garantiert werden, dass alle kompromittierten oder schädlichen Skills erkannt werden ein
unauffälliges Ergebnis ist keine Sicherheitsgarantie.{" "}
<Link href="/haftungsausschluss" className="font-medium underline underline-offset-4">
Details im Haftungsausschluss
</Link>
.
</AlertDescription>
</Alert>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="md:col-span-1">
<CardHeader>