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) */}
);
}