import React, { useState, useEffect } from 'react'; import { Wrench, Lock, CheckCircle2, AlertTriangle, Clock, Calendar, FileText, Package, Send, Sparkles, ArrowRight, LogOut, ChevronRight, ShieldCheck, Check } from 'lucide-react'; import { portalService, PortalProjectDetails } from '../services/portalService'; interface CustomerPortalViewProps { initialCode?: string; initialPin?: string; } export const CustomerPortalView: React.FC = ({ initialCode, initialPin }) => { const [accessCode, setAccessCode] = useState(initialCode || ''); const [accessPin, setAccessPin] = useState(initialPin || ''); const [isLoading, setIsLoading] = useState(false); const [errorMsg, setErrorMsg] = useState(null); const [projectData, setProjectData] = useState(null); const [activeSubTab, setActiveSubTab] = useState<'progress' | 'booking' | 'parts' | 'docs'>('progress'); // Booking Form State const [selectedDate, setSelectedDate] = useState('2026-08-11'); const [selectedSlot, setSelectedSlot] = useState('10:00 - 11:30 Uhr'); const [bookingNote, setBookingNote] = useState(''); const [bookingSuccess, setBookingSuccess] = useState(false); const [isSubmittingBooking, setIsSubmittingBooking] = useState(false); useEffect(() => { if (initialCode && initialPin) { handleLogin(initialCode, initialPin); } }, [initialCode, initialPin]); const handleLogin = async (codeToUse?: string, pinToUse?: string) => { const code = codeToUse || accessCode; const pin = pinToUse || accessPin; if (!code.trim() || !pin.trim()) { setErrorMsg('Bitte gib den Projekt-Code und die PIN ein.'); return; } setIsLoading(true); setErrorMsg(null); const details = await portalService.verifyPortalAccess(code, pin); setIsLoading(false); if (details) { setProjectData(details); } else { setErrorMsg('Ungültige Projekt-ID oder PIN. Bitte überprüfe deine Eingabe.'); } }; const handleDemoLogin = (type: 'on_track' | 'delay') => { const code = type === 'on_track' ? 'PRJ-8392' : 'PRJ-DELAY'; const pin = '749201'; setAccessCode(code); setAccessPin(pin); handleLogin(code, pin); }; const handleBookAppointment = async (e: React.FormEvent) => { e.preventDefault(); if (!projectData) return; setIsSubmittingBooking(true); await portalService.bookAppointmentSlot( projectData.order.id, projectData.customer.id, selectedDate, selectedSlot, bookingNote ); setIsSubmittingBooking(false); setBookingSuccess(true); // Refresh project details to show new changelog const updated = await portalService.verifyPortalAccess(projectData.order.accessCode!, projectData.order.accessPin!); if (updated) setProjectData(updated); setTimeout(() => setBookingSuccess(false), 4000); }; // Render Login Screen if not logged into a project if (!projectData) { return (
{/* Header */}

Kundenportal

Echtzeit-Projektstatus & Terminbuchung

{errorMsg && (
{errorMsg}
)}
{ e.preventDefault(); handleLogin(); }} style={{ display: 'flex', flexDirection: 'column', gap: '18px' }}>
setAccessCode(e.target.value)} style={{ width: '100%', padding: '12px 14px 12px 42px', backgroundColor: '#0f172a', border: '1px solid #334155', borderRadius: '10px', color: '#ffffff', fontSize: '0.95rem', boxSizing: 'border-box', outline: 'none', fontWeight: 600 }} />
setAccessPin(e.target.value)} style={{ width: '100%', padding: '12px 14px 12px 42px', backgroundColor: '#0f172a', border: '1px solid #334155', borderRadius: '10px', color: '#ffffff', fontSize: '0.95rem', boxSizing: 'border-box', outline: 'none', letterSpacing: '2px', fontWeight: 600 }} />
{/* Quick Demo Section */}
⚡ Quick Demo-Zugänge zum Testen
); } // Active Project Dashboard View const { order, customer, changelogs, attachments, installedParts } = projectData; const isDelay = order.healthStatus === 'delay' || order.healthStatus === 'critical'; return (
{/* Top Navbar */}
Handwerksfreund Kundenportal
Projekt-Code: {order.accessCode}
{/* Health Status Banner */}
{isDelay ? : }
PROJEKT-STATUS STATUS-CHECK

{isDelay ? 'Verzögerung im Ablauf (Delay)' : '🟢 Projekt ist voll im Zeitplan (On Track)'}

Voraussichtliche Fertigstellung: {order.expectedCompletionDate || '12.08.2026'}
{/* Delay Explanation Notice */} {isDelay && order.delayReason && (
Transparenz-Hinweis von deinem Handwerker: {order.delayReason}
)} {/* Visual Progress Bar */}
Gesamter Baufortschritt {order.progressPercent || 75}% Abgeschlossen
{/* Navigation Tabs */}
{/* TAB 1: Bau-Verlauf & Updates */} {activeSubTab === 'progress' && (

Projekt-Changelog & Handwerker-Updates

{changelogs.length === 0 ? (
Noch keine Einträge vorhanden.
) : ( changelogs.map((item) => (
{item.authorName} {new Date(item.createdAt).toLocaleString('de-DE')}

{item.note}

)) )}
)} {/* TAB 2: Online-Terminbuchung */} {activeSubTab === 'booking' && (

Termin online vereinbaren

Wähle ein freies Zeitfenster für deine Wartung oder Abnahme

{bookingSuccess && (
Vielen Dank! Dein Termin wurde erfolgreich gebucht. Unser Team hat die Benachrichtigung erhalten.
)}
setSelectedDate(e.target.value)} style={{ width: '100%', padding: '10px 14px', backgroundColor: '#0f172a', border: '1px solid #334155', borderRadius: '8px', color: '#ffffff', fontSize: '0.9rem', boxSizing: 'border-box' }} />
{['08:30 - 10:00 Uhr', '10:00 - 11:30 Uhr', '13:00 - 14:30 Uhr', '15:00 - 16:30 Uhr'].map((slot) => ( ))}