Add Drupal headless stack with Next.js frontend
- Add Next.js frontend service (nextjs) with Dockerfile and source - Update docker-compose.yml: image names, Drupal 11.3.3, nextjs service - Add docker-compose.override.yml.disabled for dev hot-reload - Add install-headless-modules.sh for OAuth/JSON:API module setup - Add README.md with full setup and configuration guide - Update nginx/Dockerfile and nginx.conf.template for cms. subdomain - Update drupal/Dockerfile PHP-FPM build args - Gitignore **/.vscode/ to prevent IDE workspace files from being tracked
This commit is contained in:
parent
71a8dac389
commit
f8b8f53d54
85 changed files with 7802 additions and 17 deletions
62
drupal/nextjs/components/cookie-banner.tsx
Normal file
62
drupal/nextjs/components/cookie-banner.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"use client"
|
||||
|
||||
import { useState, useEffect } from "react"
|
||||
import Link from "next/link"
|
||||
|
||||
const CONSENT_COOKIE = "cookie-consent"
|
||||
const CONSENT_MAX_AGE = 365 * 24 * 60 * 60 // 1 year in seconds
|
||||
|
||||
function setConsentCookie() {
|
||||
document.cookie = `${CONSENT_COOKIE}=accepted; path=/; max-age=${CONSENT_MAX_AGE}; SameSite=Lax`
|
||||
}
|
||||
|
||||
function hasConsent(): boolean {
|
||||
if (typeof document === "undefined") return false
|
||||
return document.cookie.includes(`${CONSENT_COOKIE}=accepted`)
|
||||
}
|
||||
|
||||
export function CookieBanner() {
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasConsent()) {
|
||||
setIsVisible(true)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleAccept = () => {
|
||||
setConsentCookie()
|
||||
setIsVisible(false)
|
||||
}
|
||||
|
||||
if (!isVisible) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
role="dialog"
|
||||
aria-label="Cookie notice"
|
||||
className="fixed bottom-0 left-0 right-0 z-50 border-t border-slate-200 bg-white/95 p-4 shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.1)] backdrop-blur-sm sm:p-6"
|
||||
>
|
||||
<div className="mx-auto flex max-w-7xl flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<p className="text-sm text-slate-600">
|
||||
This site uses a single cookie to store your consent preference. No
|
||||
tracking or analytics cookies are used.{" "}
|
||||
<Link
|
||||
href="/imprint"
|
||||
className="font-medium text-emerald-600 underline-offset-2 hover:text-emerald-500 hover:underline"
|
||||
>
|
||||
Learn more
|
||||
</Link>
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAccept}
|
||||
className="shrink-0 rounded-lg px-5 py-2.5 text-sm font-medium text-white outline-none transition-colors hover:opacity-90 focus-visible:ring-2 focus-visible:ring-emerald-500 focus-visible:ring-offset-2"
|
||||
style={{ backgroundColor: "var(--accent-hex)" }}
|
||||
>
|
||||
Accept
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue