import { lazy, Suspense, useState, useEffect } from "react"; import { AuthorData } from "./types"; import { Lock, RefreshCw } from "lucide-react"; const SciFiPortfolio = lazy(() => import("./components/SciFiPortfolio")); const EroticaPortfolio = lazy(() => import("./components/EroticaPortfolio")); const ClaraPortfolio = lazy(() => import("./components/ClaraPortfolio")); const ReneePortfolio = lazy(() => import("./components/ReneePortfolio")); const AdminPanel = lazy(() => import("./components/AdminPanel")); function LoadingScreen() { return (

Autoren-Portfolio wird geladen...

); } export default function App() { const [authorData, setAuthorData] = useState(null); const [loading, setLoading] = useState(true); const [currentPath, setCurrentPath] = useState(window.location.pathname); // Monitor location changes for custom routing useEffect(() => { const handleLocationChange = () => { setCurrentPath(window.location.pathname); }; // Listen to popstate for navigation back/forward support window.addEventListener("popstate", handleLocationChange); return () => { window.removeEventListener("popstate", handleLocationChange); }; }, []); // Fetch profiles configuration from server useEffect(() => { fetch("/api/author-data") .then((res) => res.json()) .then((data) => { setAuthorData(data); setLoading(false); }) .catch((err) => { console.error("Fehler beim Abrufen der Autoren-Informationen:", err); setLoading(false); }); }, []); // Ermittelt die aktive Suite basierend auf Pfad-Überschreibungen oder dem Domainnamen (Hostname) const getActiveSuite = (): "erotica" | "clara" | "scifi" | "renee" => { const hostname = window.location.hostname.toLowerCase(); const profileKeys: ("erotica" | "clara" | "renee" | "scifi")[] = ["erotica", "clara", "renee", "scifi"]; // 1. Pfad-basierte Routen (haben Vorrang, z.B. für Vorschau & Direktlinks) for (const key of profileKeys) { const p = authorData?.[key]; const customPaths: string[] = p?.customPath ? p.customPath.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean) : []; // Statische Standard-Fallbacks if (key === "erotica") customPaths.push("/sensual-moments", "/annie-slone", "/marc-velvet"); if (key === "clara") customPaths.push("/clara-finch", "/clara"); if (key === "renee") customPaths.push("/renee-heart", "/renee"); if (key === "scifi") customPaths.push("/sci-fi", "/daniel-hesse"); for (const prefix of customPaths) { if (prefix) { const formattedPrefix = prefix.startsWith("/") ? prefix : "/" + prefix; if (currentPath === formattedPrefix || currentPath.startsWith(formattedPrefix + "/")) { return key; } } } } // 2. Dynamische Domain-basierte Routen (für Live-Domains) for (const key of profileKeys) { const p = authorData?.[key]; const customDomains: string[] = p?.customDomain ? p.customDomain.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean) : []; // Statische Standard-Fallbacks if (key === "erotica") customDomains.push("annieslone.de", "marcvelvet.de"); if (key === "clara") customDomains.push("clarafinch.de", "clara-finch.de"); if (key === "renee") customDomains.push("reneeheart.de", "renee-heart.de"); if (key === "scifi") customDomains.push("hesse-sf.de", "danielhesse.de"); for (const domain of customDomains) { // Entferne evtl. eingegebene Protokolle (http://, https://) oder führendes "www." const cleanDomain = domain.replace(/^https?:\/\//, "").replace(/^www\./, "").trim(); if (cleanDomain && (hostname === cleanDomain || hostname === `www.${cleanDomain}`)) { return key; } } } // Standard-Fallback (Daniel Hesse SciFi) return "scifi"; }; // Dynamisch den Dokumententitel (Browsertab-Titel) basierend auf Suite und Autorendaten anpassen useEffect(() => { if (!authorData) { document.title = "Lade Autoren-Portfolio..."; return; } if (currentPath === "/admin" || currentPath.startsWith("/admin/")) { document.title = "Admin-Zentrale | Autor-Suiten"; return; } const activeSuite = getActiveSuite(); if (activeSuite === "erotica") { document.title = authorData.erotica.name || "Annie Slone"; } else if (activeSuite === "clara") { document.title = authorData.clara.name || "Clara Finch"; } else if (activeSuite === "renee") { document.title = authorData.renee.name || "Renee Heart"; } else { document.title = authorData.scifi.name || "Daniel Hesse"; } }, [currentPath, authorData]); const handleAdminLogout = () => { // Relocate to landing site after administration work window.history.pushState({}, "", "/"); setCurrentPath("/"); }; if (loading) { return ; } if (!authorData) { return (

Verbindungsfehler

Die Verbindung zum lokalen Datenspeicher-Server konnte nicht hergestellt werden. Bitte vergewissern Sie sich, dass Ihr Express API-Server ordnungsgemäß läuft.

); } // Purely route-based render isolation structure // 1. Administration panel if (currentPath === "/admin" || currentPath.startsWith("/admin/")) { return }>; } // Render active portfolio const renderActivePortfolio = () => { const activeSuite = getActiveSuite(); const legalDocs = authorData.legalDocuments || []; if (activeSuite === "erotica") { return ; } if (activeSuite === "clara") { return ; } if (activeSuite === "renee") { return ; } return ; }; return ( }> {renderActivePortfolio()} {/* Absolute floating administration bypass link hidden on the bottom left (hover to show) */} ); }