991 lines
53 KiB
TypeScript
991 lines
53 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
||
import { Link, useNavigate } from 'react-router-dom';
|
||
import { useTranslation } from 'react-i18next';
|
||
import { Shield, Phone, Mail, CheckCircle, Star, Car, FileText, Calculator, Users, Download, Search, AlertCircle, AlertTriangle, Clock, FileCheck, PhoneCall, MapPin, Gauge, Heart, Ambulance, Activity } from 'lucide-react';
|
||
import Layout from '@/components/Layout';
|
||
import { Button } from '@/components/ui/button';
|
||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||
import GeneralNotice from '@/components/GeneralNotice';
|
||
import HeroSlider from '@/components/HeroSlider';
|
||
import TwoColumnTab from '@/components/tab-pages/TwoColumnTab';
|
||
|
||
declare global {
|
||
interface Window {
|
||
Dropbox?: {
|
||
choose: (options: {
|
||
linkType?: 'preview' | 'direct';
|
||
multiselect?: boolean;
|
||
extensions?: string[];
|
||
success: (files: Array<{ link: string; name: string; bytes: number }>) => void;
|
||
}) => void;
|
||
};
|
||
}
|
||
}
|
||
|
||
const Unfall = () => {
|
||
const { t } = useTranslation('unfall');
|
||
const navigate = useNavigate();
|
||
const baseUrl = import.meta.env.BASE_URL;
|
||
const assetUrl = (fileName: string) => `${baseUrl}${encodeURI(fileName)}`;
|
||
const [activeTab, setActiveTab] = useState('overview');
|
||
const [searchQuery, setSearchQuery] = useState('');
|
||
const dropboxAppKey = import.meta.env.VITE_DROPBOX_APP_KEY as string | undefined;
|
||
const dropboxFileRequestUrl = import.meta.env.VITE_DROPBOX_FILE_REQUEST_URL as string | undefined;
|
||
const [calculatorData, setCalculatorData] = useState({
|
||
profession: '',
|
||
coverageType: '',
|
||
});
|
||
const [formData, setFormData] = useState({
|
||
name: '',
|
||
phone: '',
|
||
email: '',
|
||
accidentDateTime: '',
|
||
accidentLocation: '',
|
||
accidentType: '',
|
||
accidentDescription: '',
|
||
injuries: '',
|
||
otherParties: '',
|
||
witnesses: '',
|
||
policeReport: '',
|
||
policyNumber: '',
|
||
message: '',
|
||
});
|
||
|
||
const [attachments, setAttachments] = useState<Array<{ name: string; url: string }>>([]);
|
||
|
||
useEffect(() => {
|
||
if (!dropboxAppKey) return;
|
||
if (typeof window === 'undefined') return;
|
||
if (window.Dropbox) return;
|
||
|
||
const existing = document.querySelector('script[data-dropbox-chooser="1"]');
|
||
if (existing) return;
|
||
|
||
const script = document.createElement('script');
|
||
script.src = 'https://www.dropbox.com/static/api/2/dropins.js';
|
||
script.id = 'dropboxjs';
|
||
script.type = 'text/javascript';
|
||
script.setAttribute('data-dropbox-chooser', '1');
|
||
script.setAttribute('data-app-key', dropboxAppKey);
|
||
document.body.appendChild(script);
|
||
}, [dropboxAppKey]);
|
||
|
||
const benefits = [
|
||
{ icon: Shield, title: 'Invaliditätsschutz', description: 'Sicherung bei dauerhaften Gesundheitsschäden' },
|
||
{ icon: Heart, title: 'Todesfallsumme', description: 'Absicherung für Hinterbliebene' },
|
||
{ icon: Calculator, title: 'Progressionsleistung', description: 'Steigende Leistungen bei schweren Unfällen' },
|
||
{ icon: CheckCircle, title: 'Unfallrente', description: 'Monatliche Zahlungen bei Erwerbsunfähigkeit' }
|
||
];
|
||
|
||
const searchItems = [
|
||
{ title: 'Unfallmitteilung', description: 'Checkliste, Angaben, nächste Schritte', tab: 'claims' },
|
||
{ title: 'Unfallmitteilung senden', description: 'Formular ausfüllen + Anhänge via Dropbox', tab: 'form' },
|
||
{ title: 'Entschädigung / Ansprüche', description: 'Schmerzensgeld, Verdienstausfall, Kosten', tab: 'claims' },
|
||
{ title: 'Unfall-Rechner', description: 'Grobe Beitragsschätzung zur Orientierung', tab: 'calculator' },
|
||
{ title: 'Infothek', description: 'Download, Druck, Hinweise', tab: 'catalog' },
|
||
];
|
||
|
||
const normalizedQuery = searchQuery.trim().toLowerCase();
|
||
const filteredSearchItems = normalizedQuery
|
||
? searchItems.filter((item) => {
|
||
const haystack = `${item.title} ${item.description}`.toLowerCase();
|
||
return haystack.includes(normalizedQuery);
|
||
})
|
||
: [];
|
||
|
||
const services = [
|
||
'Private Unfallversicherung',
|
||
'Berufsunfallversicherung',
|
||
'Kinder-Unfallversicherung',
|
||
'Studenten-Unfallversicherung',
|
||
'Senioren-Unfallversicherung',
|
||
'Sport-Unfallversicherung'
|
||
];
|
||
|
||
const handleFormChange = (
|
||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>
|
||
) => {
|
||
const { name, value } = e.target;
|
||
setFormData((prev) => ({
|
||
...prev,
|
||
[name]: value
|
||
}));
|
||
};
|
||
|
||
const handleCalculatorChange = (
|
||
e: React.ChangeEvent<HTMLSelectElement>
|
||
) => {
|
||
const { name, value } = e.target;
|
||
setCalculatorData((prev) => ({
|
||
...prev,
|
||
[name]: value,
|
||
}));
|
||
};
|
||
|
||
const handleSubmit = (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
alert('Vielen Dank! Wir melden uns kurzfristig bei dir.');
|
||
};
|
||
|
||
return (
|
||
<Layout>
|
||
<HeroSlider
|
||
slides={[
|
||
{
|
||
id: 'unfall-1',
|
||
kicker: 'Schutz bei Unfällen',
|
||
title: 'Unfallversicherung',
|
||
subtitle: 'Sicherheit bei Unfällen – Invaliditätsschutz, Todesfallsumme, Progressionsleistung und Unfallrente für Sie und Ihre Familie',
|
||
imageUrl: assetUrl('Fotolia_67327775_XS.jpg'),
|
||
imagePosition: 'center 35%',
|
||
ctas: [
|
||
{ label: 'Angebot anfordern', href: '#form' },
|
||
{ label: 'Beratung', href: '/contact' },
|
||
],
|
||
},
|
||
]}
|
||
/>
|
||
|
||
<div className="min-h-screen bg-gray-50">
|
||
<div className="container mx-auto px-4 md:px-6 py-8">
|
||
<div className="max-w-screen-2xl mx-auto">
|
||
<h2 className="text-2xl font-bold text-gray-900 mb-6 text-center">
|
||
Hilfe nach einem Unfall
|
||
</h2>
|
||
|
||
<div className="max-w-3xl mx-auto mb-6 relative z-50">
|
||
<div className="relative">
|
||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
|
||
<input
|
||
value={searchQuery}
|
||
onChange={(e) => setSearchQuery(e.target.value)}
|
||
className="w-full rounded-md border border-gray-300 bg-white pl-9 pr-3 py-2 text-sm"
|
||
placeholder="Suche (z. B. Unfallmitteilung, Ansprüche, Checkliste, Formular)"
|
||
/>
|
||
</div>
|
||
|
||
{filteredSearchItems.length > 0 && (
|
||
<div className="mt-2 rounded-md border border-gray-200 bg-white shadow-sm overflow-hidden relative z-50">
|
||
{filteredSearchItems.map((item) => (
|
||
<button
|
||
key={`${item.tab}-${item.title}`}
|
||
type="button"
|
||
className="w-full text-left px-4 py-3 hover:bg-gray-50 transition-colors"
|
||
onClick={() => {
|
||
setActiveTab(item.tab);
|
||
setSearchQuery('');
|
||
}}
|
||
>
|
||
<div className="text-sm font-semibold text-gray-900">{item.title}</div>
|
||
<div className="text-xs text-gray-600 mt-0.5">{item.description}</div>
|
||
</button>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<Tabs value={activeTab} onValueChange={(next) => setActiveTab(next)} className="w-full">
|
||
<div className="border-b border-gray-100 px-4 pt-6 pb-2 bg-gradient-to-r from-blue-50 to-white">
|
||
<TabsList className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-7 gap-2 w-full h-auto bg-transparent border-0 shadow-none">
|
||
<TabsTrigger
|
||
value="overview"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<Shield className="w-4 h-4 mr-1.5" />
|
||
Übersicht
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="details"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<FileText className="w-4 h-4 mr-1.5" />
|
||
Details
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="statistics"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<Calculator className="w-4 h-4 mr-1.5" />
|
||
Statistik
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="calculator"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<Gauge className="w-4 h-4 mr-1.5" />
|
||
Rechner
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="form"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<Phone className="w-4 h-4 mr-1.5" />
|
||
Anfrage
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="claims"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<AlertCircle className="w-4 h-4 mr-1.5" />
|
||
Mitteilung
|
||
</TabsTrigger>
|
||
<TabsTrigger
|
||
value="catalog"
|
||
className="relative px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 data-[state=active]:bg-blue-600 data-[state=active]:text-white data-[state=active]:shadow-md data-[state=inactive]:bg-white data-[state=inactive]:text-gray-600 data-[state=inactive]:hover:bg-gray-50 data-[state=inactive]:border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 !outline-none !ring-0"
|
||
>
|
||
<FileCheck className="w-4 h-4 mr-1.5" />
|
||
Infothek
|
||
</TabsTrigger>
|
||
</TabsList>
|
||
</div>
|
||
|
||
<div className="p-4 md:p-6">
|
||
<TabsContent value="overview" className="mt-0">
|
||
<TwoColumnTab
|
||
className="gap-8 items-center"
|
||
left={
|
||
<>
|
||
<div className="inline-flex items-center gap-2 rounded-full bg-blue-50 border border-blue-200 px-3 py-1 text-sm text-blue-800 mb-4">
|
||
<Star className="w-4 h-4" />
|
||
<span>Sicherheit für jede Lebenslage</span>
|
||
</div>
|
||
<h1 className="text-3xl md:text-4xl font-bold text-gray-900 leading-tight">
|
||
Hilfe nach einem Unfall
|
||
<span className="block text-blue-700">Schnelle Schritte, Unfallmitteilung & mögliche Ansprüche</span>
|
||
</h1>
|
||
<p className="mt-4 text-gray-600 text-lg">
|
||
Im Ernstfall zählt eine klare Reihenfolge: Sicherheit, Dokumentation, Meldung.
|
||
Hier findest du eine kompakte Anleitung, was du sofort tun solltest und welche Angaben
|
||
wir für eine schnelle Unfallmitteilung benötigen.
|
||
</p>
|
||
|
||
<div className="mt-6 flex flex-col sm:flex-row gap-3">
|
||
<Button onClick={() => setActiveTab('form')} className="bg-blue-700 hover:bg-blue-800">
|
||
Rückruf / Hilfe anfordern
|
||
</Button>
|
||
<Button variant="outline" onClick={() => navigate('/kontakt')} className="border-gray-300">
|
||
Kontakt
|
||
</Button>
|
||
</div>
|
||
|
||
<div className="mt-6 grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||
<div className="flex items-center gap-3 rounded-lg border border-gray-200 bg-white p-3">
|
||
<Shield className="w-5 h-5 text-blue-700" />
|
||
<div className="text-sm">
|
||
<div className="font-semibold text-gray-900">Invaliditätsschutz</div>
|
||
<div className="text-gray-600">bis 100% Invaliditätsgrad</div>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-3 rounded-lg border border-gray-200 bg-white p-3">
|
||
<Heart className="w-5 h-5 text-blue-700" />
|
||
<div className="text-sm">
|
||
<div className="font-semibold text-gray-900">Todesfallsumme</div>
|
||
<div className="text-gray-600">Absicherung für Familie</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</>
|
||
}
|
||
right={
|
||
(
|
||
<div className="relative">
|
||
<div className="absolute inset-0 bg-gradient-to-tr from-blue-100 to-white rounded-2xl" />
|
||
<div className="relative rounded-2xl border border-gray-200 bg-white shadow-sm overflow-hidden">
|
||
<img
|
||
src={assetUrl('iStock-523830845.jpg')}
|
||
alt="Unfallversicherung"
|
||
className="w-full h-[320px] object-cover"
|
||
onError={(e) => {
|
||
(e.currentTarget as HTMLImageElement).style.display = 'none';
|
||
}}
|
||
/>
|
||
<div className="p-5">
|
||
<div className="flex items-center gap-2 text-sm text-gray-600">
|
||
<Heart className="w-4 h-4" />
|
||
<span>Privat, Beruf, Kinder, Sport</span>
|
||
</div>
|
||
<div className="mt-2 text-sm text-gray-600">
|
||
Tarifcheck – schnell, fair und passend zu deinem Bedarf.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
/>
|
||
|
||
<div className="mt-10 bg-white rounded-xl border border-gray-200 p-6">
|
||
<h3 className="text-xl font-bold text-gray-900 mb-4">Kurz & klar</h3>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<CheckCircle className="w-4 h-4 text-blue-700" />
|
||
Wichtig
|
||
</CardTitle>
|
||
<CardDescription>Unfälle können jeden treffen.</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<Calculator className="w-4 h-4 text-blue-700" />
|
||
Günstig
|
||
</CardTitle>
|
||
<CardDescription>Bereits ab wenigen Euro pro Monat.</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<PhoneCall className="w-4 h-4 text-blue-700" />
|
||
Hilfe im Schadenfall
|
||
</CardTitle>
|
||
<CardDescription>Klare Schritte & Kontaktmöglichkeiten.</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="details" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Details & Vorteile</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Die Unfallversicherung sichert die finanziellen Folgen bei Unfällen ab.
|
||
Sie leistet bei Invalidität, Todesfall oder temporären Unfallfolgen.
|
||
Wir helfen Ihnen, die richtige Leistungssumme und Tarif zu finden.
|
||
</p>
|
||
|
||
<div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
{benefits.map((benefit, index) => {
|
||
const Icon = benefit.icon;
|
||
return (
|
||
<Card key={index} className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<Icon className="h-5 w-5 text-blue-700" />
|
||
{benefit.title}
|
||
</CardTitle>
|
||
<CardDescription className="text-gray-600">{benefit.description}</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
<div className="mt-8">
|
||
<h4 className="text-lg font-semibold text-gray-900 mb-3">Leistungen (Auszug)</h4>
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||
{services.map((service, index) => (
|
||
<div
|
||
key={index}
|
||
className="flex items-start gap-3 rounded-lg border border-gray-200 bg-white p-3"
|
||
>
|
||
<CheckCircle className="h-5 w-5 text-blue-700 mt-0.5 flex-shrink-0" />
|
||
<p className="text-gray-700">{service}</p>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Tipp</CardTitle>
|
||
<CardDescription>Leistungssumme prüfen.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="text-sm text-gray-700">
|
||
Mindestens 50.000 € Invaliditätssumme,
|
||
besser 100.000-250.000 € für optimalen Schutz.
|
||
</CardContent>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="statistics" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Unfallstatistik</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Unfälle gehören zu den häufigsten Ursachen für Invalidität und Todesfälle.
|
||
Eine gute Unfallversicherung schützt vor den finanziellen Folgen.
|
||
</p>
|
||
|
||
<div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<AlertTriangle className="w-5 h-5 text-blue-700" />
|
||
Häufige Unfallursachen
|
||
</CardTitle>
|
||
<CardDescription>
|
||
Stürze, Verkehrsunfälle, Sportunfälle.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-base flex items-center gap-2">
|
||
<Clock className="w-5 h-5 text-blue-700" />
|
||
Statistik
|
||
</CardTitle>
|
||
<CardDescription>
|
||
8 Mio. Unfälle/Jahr, 30.000 Todesfälle.
|
||
</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
</div>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Tipp</CardTitle>
|
||
<CardDescription>Vorsorge ist besser als Nachsorge.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="text-sm text-gray-700">
|
||
Unfallverhütung im Alltag und Sport kann viele Risiken reduzieren.
|
||
Eine gute Versicherung schützt vor den Rest.
|
||
</CardContent>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="calculator" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Unfall-Rechner</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Richtwert zur Orientierung. Für ein exaktes Angebot brauchen wir u. a.
|
||
Beruf, Risikogruppe und gewünschte Leistungssumme.
|
||
</p>
|
||
|
||
<Card className="mt-6 border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg flex items-center gap-2">
|
||
<Calculator className="w-5 h-5 text-blue-700" />
|
||
Grobe Beitragsschätzung
|
||
</CardTitle>
|
||
<CardDescription>Unverbindlich – wir kalkulieren danach exakt.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-4">
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Berufsgruppe</label>
|
||
<select
|
||
name="profession"
|
||
value={calculatorData.profession}
|
||
onChange={handleCalculatorChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm"
|
||
>
|
||
<option value="">Bitte wählen</option>
|
||
<option value="angestellt">Angestellt (Büro)</option>
|
||
<option value="handwerk">Handwerk/Produktion</option>
|
||
<option value="selbstständig">Selbstständig</option>
|
||
<option value="beamter">Beamter</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Versicherungstyp</label>
|
||
<select
|
||
name="coverageType"
|
||
value={calculatorData.coverageType}
|
||
onChange={handleCalculatorChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm"
|
||
>
|
||
<option value="">Bitte wählen</option>
|
||
<option value="privat">Privat</option>
|
||
<option value="beruf">Beruf</option>
|
||
<option value="kombi">Kombi</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
|
||
<div className="text-sm text-blue-900 font-semibold">Richtwert (Beispiel)</div>
|
||
<div className="mt-1 text-sm text-blue-900">
|
||
Ab <span className="font-bold">ca. 5 €</span>/Monat
|
||
</div>
|
||
<div className="text-xs text-blue-900/80 mt-2">
|
||
Abhängig von Berufsgruppe, Risikogruppe, Leistungssumme.
|
||
</div>
|
||
</div>
|
||
|
||
<Button onClick={() => setActiveTab('form')} className="w-full bg-blue-700 hover:bg-blue-800">
|
||
Jetzt konkretes Angebot anfordern
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Was wir fürs Angebot brauchen</CardTitle>
|
||
<CardDescription>Je genauer, desto besser.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-3 text-sm text-gray-700">
|
||
<div className="flex items-start gap-2">
|
||
<Heart className="w-4 h-4 text-blue-700 mt-0.5" />
|
||
<span>Berufliche Tätigkeit und Risiken</span>
|
||
</div>
|
||
<div className="flex items-start gap-2">
|
||
<Search className="w-4 h-4 text-blue-700 mt-0.5" />
|
||
<span>Gewünschte Leistungssumme</span>
|
||
</div>
|
||
<div className="flex items-start gap-2">
|
||
<AlertCircle className="w-4 h-4 text-blue-700 mt-0.5" />
|
||
<span>Vorversicherungen? Sportrisiken?</span>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="form" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Unfallmitteilung senden</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Fülle die wichtigsten Angaben aus. Anhänge (Fotos, Arztberichte, Belege) kannst du vorerst
|
||
über Dropbox hochladen oder aus Dropbox auswählen – Speicherung in der Datenbank folgt.
|
||
</p>
|
||
|
||
<Card className="mt-6 border-gray-200">
|
||
<CardContent className="p-6">
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Name</label>
|
||
<input
|
||
name="name"
|
||
value={formData.name}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
required
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Telefon</label>
|
||
<input
|
||
name="phone"
|
||
value={formData.phone}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">E-Mail</label>
|
||
<input
|
||
type="email"
|
||
name="email"
|
||
value={formData.email}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Datum & Uhrzeit</label>
|
||
<input
|
||
type="datetime-local"
|
||
name="accidentDateTime"
|
||
value={formData.accidentDateTime}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
required
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Unfallort</label>
|
||
<input
|
||
name="accidentLocation"
|
||
value={formData.accidentLocation}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
placeholder="Straße, PLZ/Ort"
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Art des Unfalls</label>
|
||
<select
|
||
name="accidentType"
|
||
value={formData.accidentType}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm"
|
||
required
|
||
>
|
||
<option value="">Bitte wählen</option>
|
||
<option value="verkehr">Verkehrsunfall</option>
|
||
<option value="arbeit">Arbeitsunfall</option>
|
||
<option value="sport">Sportunfall</option>
|
||
<option value="haushalt">Haushaltsunfall</option>
|
||
<option value="sonstiges">Sonstiges</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Unfallhergang (kurz)</label>
|
||
<textarea
|
||
name="accidentDescription"
|
||
value={formData.accidentDescription}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm min-h-[120px]"
|
||
placeholder="Wer/was/wie? Was ist passiert?"
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Verletzungen / Beschwerden</label>
|
||
<textarea
|
||
name="injuries"
|
||
value={formData.injuries}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm min-h-[90px]"
|
||
placeholder="z. B. Prellung, Fraktur, Schmerzen ..."
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Beteiligte (Namen/Kontakt)</label>
|
||
<textarea
|
||
name="otherParties"
|
||
value={formData.otherParties}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm min-h-[90px]"
|
||
placeholder="Gegner, Halter, Fahrer, Versicherung ..."
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Zeugen (Name/Telefon)</label>
|
||
<input
|
||
name="witnesses"
|
||
value={formData.witnesses}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
placeholder="z. B. Max Mustermann, 0171..."
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Polizei/Aktenzeichen (optional)</label>
|
||
<input
|
||
name="policeReport"
|
||
value={formData.policeReport}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
placeholder="Dienststelle / Aktenzeichen"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Versicherungsnummer (optional)</label>
|
||
<input
|
||
name="policyNumber"
|
||
value={formData.policyNumber}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
||
/>
|
||
</div>
|
||
|
||
<div>
|
||
<label className="text-sm font-medium text-gray-700">Zusätzliche Hinweise</label>
|
||
<textarea
|
||
name="message"
|
||
value={formData.message}
|
||
onChange={handleFormChange}
|
||
className="mt-1 w-full rounded-md border border-gray-300 px-3 py-2 text-sm min-h-[120px]"
|
||
placeholder="Weitere Infos, z. B. Behandlungen, Fristen, Rückrufzeiten ..."
|
||
/>
|
||
</div>
|
||
|
||
<div className="rounded-lg border border-gray-200 bg-white p-4">
|
||
<div className="text-sm font-semibold text-gray-900">Anhänge (Fotos / Dokumente)</div>
|
||
<div className="text-sm text-gray-600 mt-1">
|
||
Bitte lade Dateien vorerst über Dropbox hoch oder wähle sie aus Dropbox aus.
|
||
</div>
|
||
<div className="mt-3 flex flex-col sm:flex-row gap-3">
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
className="border-gray-300"
|
||
onClick={() => {
|
||
if (!dropboxFileRequestUrl) return;
|
||
window.open(dropboxFileRequestUrl, '_blank', 'noopener,noreferrer');
|
||
}}
|
||
disabled={!dropboxFileRequestUrl}
|
||
>
|
||
Dateien via Dropbox hochladen
|
||
</Button>
|
||
<Button
|
||
type="button"
|
||
variant="outline"
|
||
className="border-gray-300"
|
||
onClick={() => {
|
||
if (!window.Dropbox) return;
|
||
window.Dropbox.choose({
|
||
linkType: 'preview',
|
||
multiselect: true,
|
||
success: (files) => {
|
||
setAttachments((prev) => {
|
||
const next = [...prev];
|
||
files.forEach((f) => {
|
||
if (next.some((x) => x.url === f.link)) return;
|
||
next.push({ name: f.name, url: f.link });
|
||
});
|
||
return next;
|
||
});
|
||
},
|
||
});
|
||
}}
|
||
disabled={!dropboxAppKey}
|
||
>
|
||
Dateien aus Dropbox auswählen
|
||
</Button>
|
||
</div>
|
||
{attachments.length > 0 && (
|
||
<div className="mt-3 space-y-1 text-sm">
|
||
{attachments.map((a) => (
|
||
<a
|
||
key={a.url}
|
||
href={a.url}
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="block text-blue-700 hover:underline"
|
||
>
|
||
{a.name}
|
||
</a>
|
||
))}
|
||
</div>
|
||
)}
|
||
{!dropboxFileRequestUrl && (
|
||
<div className="mt-2 text-xs text-gray-600">
|
||
Hinweis: Setze <span className="font-mono">VITE_DROPBOX_FILE_REQUEST_URL</span>, um einen Dropbox-Upload-Link zu aktivieren.
|
||
</div>
|
||
)}
|
||
{!dropboxAppKey && (
|
||
<div className="mt-2 text-xs text-gray-600">
|
||
Hinweis: Setze <span className="font-mono">VITE_DROPBOX_APP_KEY</span>, um den Dropbox Chooser zu aktivieren.
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<Button type="submit" className="bg-blue-700 hover:bg-blue-800">
|
||
Unfallmitteilung senden
|
||
</Button>
|
||
</form>
|
||
</CardContent>
|
||
</Card>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Direktkontakt</CardTitle>
|
||
<CardDescription>Wenn es schnell gehen soll.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-3 text-sm text-gray-700">
|
||
<div className="flex items-center gap-2">
|
||
<Phone className="w-4 h-4 text-blue-700" />
|
||
<span>Handy: 0171 9864053</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<Mail className="w-4 h-4 text-blue-700" />
|
||
<span>E-Mail: info@finanzen-mizera.de</span>
|
||
</div>
|
||
<div className="pt-2">
|
||
<Button variant="outline" className="w-full" onClick={() => navigate('/kontakt')}>
|
||
Kontaktseite
|
||
</Button>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="claims" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Unfallmitteilung</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Damit wir dich schnell unterstützen können, brauchen wir eine kurze Unfallmitteilung.
|
||
Nutze die Checkliste und sammle die wichtigsten Angaben.
|
||
</p>
|
||
|
||
<div className="mt-6 space-y-6">
|
||
<div className="rounded-lg border border-gray-200 bg-white p-5">
|
||
<div className="flex items-start gap-3">
|
||
<AlertTriangle className="w-5 h-5 text-blue-700 mt-0.5" />
|
||
<div>
|
||
<div className="font-semibold text-gray-900">Sofortmaßnahmen</div>
|
||
<div className="text-gray-600 text-sm mt-1">
|
||
Eigenschutz, Verletzte versorgen, Unfallstelle sichern. Bei akuter Gefahr immer 112.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="rounded-lg border border-gray-200 bg-white p-5">
|
||
<div className="flex items-start gap-3">
|
||
<FileCheck className="w-5 h-5 text-blue-700 mt-0.5" />
|
||
<div>
|
||
<div className="font-semibold text-gray-900">Unfallmitteilung – diese Angaben helfen uns</div>
|
||
<div className="mt-3 grid grid-cols-1 md:grid-cols-2 gap-3 text-sm text-gray-700">
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Datum/Uhrzeit & Ort</div>
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Kurzer Hergang (wer/was/wie)</div>
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Beteiligte & Kontaktdaten</div>
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Zeugen (Name/Telefon)</div>
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Polizei/Aktenzeichen (falls vorhanden)</div>
|
||
<div className="rounded-md bg-gray-50 border border-gray-200 p-3">Fotos/Videos, Belege, Arztberichte</div>
|
||
</div>
|
||
<div className="mt-3 text-xs text-gray-600">
|
||
Hinweis: Bitte keine sensiblen Dokumente öffentlich teilen. Wir geben dir einen sicheren Weg zur Übermittlung.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="rounded-lg border border-gray-200 bg-white p-5">
|
||
<div className="flex items-start gap-3">
|
||
<PhoneCall className="w-5 h-5 text-blue-700 mt-0.5" />
|
||
<div>
|
||
<div className="font-semibold text-gray-900">Melden & weiter vorgehen</div>
|
||
<div className="text-gray-600 text-sm mt-1">
|
||
Melde dich möglichst zeitnah. Wir helfen bei den nächsten Schritten (z. B. Fristen, Unterlagen, Kommunikation).
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-5">
|
||
<div className="font-semibold text-blue-900">Mögliche Entschädigung / Ansprüche (je nach Situation)</div>
|
||
<div className="mt-2 grid grid-cols-1 md:grid-cols-2 gap-3 text-sm text-blue-900">
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Schmerzensgeld</div>
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Verdienstausfall</div>
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Heilbehandlungskosten / Zuzahlungen</div>
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Haushaltsführungsschaden</div>
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Sachschaden / Nutzungsausfall</div>
|
||
<div className="rounded-md bg-white/70 border border-blue-200 p-3">Invaliditätsleistung (bei bestehender Unfallversicherung)</div>
|
||
</div>
|
||
<div className="mt-3 text-xs text-blue-900/80">
|
||
Wir geben hier nur einen Überblick und keine Rechtsberatung. Welche Ansprüche bestehen, hängt vom konkreten Unfall ab.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-6 flex flex-col sm:flex-row gap-3">
|
||
<Button onClick={() => setActiveTab('form')} className="bg-blue-700 hover:bg-blue-800">
|
||
Unfallmitteilung senden
|
||
</Button>
|
||
<Link to="/kontakt" className="inline-flex">
|
||
<Button variant="outline">Kontakt</Button>
|
||
</Link>
|
||
</div>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Notfall-Info</CardTitle>
|
||
<CardDescription>Bei schweren Verletzungen immer 112 wählen.</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="text-sm text-gray-700 space-y-2">
|
||
<div className="flex items-start gap-2">
|
||
<PhoneCall className="w-4 h-4 text-blue-700 mt-0.5" />
|
||
<span>Rettung: 112</span>
|
||
</div>
|
||
<div className="flex items-start gap-2">
|
||
<PhoneCall className="w-4 h-4 text-blue-700 mt-0.5" />
|
||
<span>Polizei: 110</span>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<TabsContent value="catalog" className="mt-0">
|
||
<TwoColumnTab
|
||
left={
|
||
<>
|
||
<h3 className="text-2xl font-bold text-gray-900">Infothek</h3>
|
||
<p className="mt-2 text-gray-600">
|
||
Nützliche Informationen rund um die Unfallversicherung.
|
||
</p>
|
||
|
||
<div className="mt-4 space-y-3">
|
||
{(
|
||
normalizedQuery
|
||
? filteredSearchItems.filter((i) => i.tab === 'catalog')
|
||
: searchItems.filter((i) => i.tab === 'catalog')
|
||
).map((item) => (
|
||
<div key={`${item.tab}-${item.title}`} className="rounded-lg border border-gray-200 bg-white p-4">
|
||
<div className="font-semibold text-gray-900">{item.title}</div>
|
||
<div className="text-sm text-gray-600 mt-1">{item.description}</div>
|
||
</div>
|
||
))}
|
||
|
||
{normalizedQuery && filteredSearchItems.filter((i) => i.tab === 'catalog').length === 0 && (
|
||
<div className="text-sm text-gray-600">
|
||
Keine Treffer in der Infothek für „{searchQuery.trim()}“.
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
<div className="mt-4 flex flex-col sm:flex-row gap-3">
|
||
<Button className="bg-blue-700 hover:bg-blue-800">
|
||
Checkliste herunterladen
|
||
</Button>
|
||
<Button variant="outline" className="gap-2" onClick={() => window.print()}>
|
||
Seite drucken
|
||
</Button>
|
||
</div>
|
||
</>
|
||
}
|
||
right={
|
||
<Card className="border-gray-200">
|
||
<CardHeader>
|
||
<CardTitle className="text-lg">Hinweis</CardTitle>
|
||
<CardDescription>Informationen können sich ändern – bitte aktuelle Quellen prüfen.</CardDescription>
|
||
</CardHeader>
|
||
</Card>
|
||
}
|
||
/>
|
||
</TabsContent>
|
||
|
||
<GeneralNotice />
|
||
</div>
|
||
</Tabs>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Layout>
|
||
);
|
||
};
|
||
|
||
export default Unfall;
|