486555dbf2
- Shared SubpageShell (HeaderClient paper strip + ink footer) and SubpageIntro, btn/ghost/card helpers in app/_ui/subpage.tsx - Projects list: poster cards with hard ink shadows, filter pills, ink search field; no fake 800ms skeleton and no framer-motion opacity:0 in SSR - Project detail: poster hero, .plakat-prose markdown, links/stack aside, back link works without JS - Books: server-side fetch (visible without JS), cover + rating pills - Legal notice / privacy: moved to app/_ui/*Client.tsx, root routes removed (middleware always redirects to /[locale]), consent reset via useConsent - ProjectThumbnail rebuilt on Plakat tokens - Old Header.tsx + test removed; brown/cream/sand palettes and unused glass-panel/admin-glass(-light)/liquid-bg-blob/float CSS dropped (liquid palette, glass-card, admin-glass-card stay for admin + 404) - .plakat-prose replaces the missing typography plugin Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 lines
836 B
TypeScript
30 lines
836 B
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
/**
|
|
* Lädt eine Inhaltsseite (Impressum, Datenschutz) aus dem CMS nach.
|
|
* Bis dahin und ohne JavaScript bleibt der eingebaute Text stehen.
|
|
*/
|
|
export function useCmsPage(key: string, locale: string): string | null {
|
|
const [html, setHtml] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
(async () => {
|
|
try {
|
|
const res = await fetch(`/api/content/page?key=${encodeURIComponent(key)}&locale=${encodeURIComponent(locale)}`);
|
|
const data = await res.json();
|
|
if (!cancelled && data?.content?.html && data?.content?.locale === locale) {
|
|
setHtml(data.content.html as string);
|
|
}
|
|
} catch {}
|
|
})();
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [key, locale]);
|
|
|
|
return html;
|
|
}
|