// Main App — hash-based routing across the 5 pages
function App() {
const validPages = ["start", "leistungen", "referenzen", "ueber", "kontakt", "impressum"];
const parseHash = () => {
const raw = window.location.hash.replace("#", "");
const [p, s] = raw.split("/");
return {
page: validPages.includes(p) ? p : "start",
section: s || null
};
};
const [{ page, section }, setRoute] = useState(parseHash);
const [toast, setToast] = useState({ show: false, message: "" });
useEffect(() => {
const onHash = () => setRoute(parseHash());
window.addEventListener("hashchange", onHash);
return () => window.removeEventListener("hashchange", onHash);
}, []);
// After render, handle scroll target
useEffect(() => {
if (section) {
// Allow the new page to render first
const t = setTimeout(() => {
const el = document.getElementById(section);
if (el) {
const top = el.getBoundingClientRect().top + window.scrollY - 90;
window.scrollTo({ top, behavior: "smooth" });
} else {
window.scrollTo({ top: 0, behavior: "smooth" });
}
}, 80);
return () => clearTimeout(t);
} else {
window.scrollTo({ top: 0, behavior: "smooth" });
}
}, [page, section]);
const navigate = (target, sectionId) => {
const newHash = sectionId ? `${target}/${sectionId}` : target;
if (window.location.hash.replace("#", "") === newHash) {
// same hash – still trigger scroll
setRoute({ page: target, section: sectionId || null });
} else {
window.location.hash = newHash;
}
};
const showToast = (message) => {
setToast({ show: true, message });
setTimeout(() => setToast({ show: false, message: "" }), 3600);
};
let pageEl = null;
switch (page) {
case "leistungen":pageEl =