Files
portfolio/app/components/Footer.tsx
denshooter 6c2da49bfa feat: plakat redesign phase 4 (chat window, contact, footer, cleanup)
- AI chat moves into a window/sheet, opened from a new speech-bubble card on
  the desk; it now respects the chatbot consent and asks before sending
  anything to n8n (previously it ignored the consent)
- Contact as red poster section with big mail address and the form on a paper
  card; validation errors are finally shown inline (aria-invalid, role=alert)
- Footer as ink strip with dk0 wordmark, legal links and a button to reopen
  the privacy settings
- "About me" in the header opens the about window on the home page
- Remove the old About section and its parts (BentoChat, ActivityFeed,
  CurrentlyReading, ReadBooks), the unused ChatWidget, Projects and BentoGrid,
  their tests, wrappers, loaders, types and texts
- scripts/directus-cleanup-redesign.mjs: dry run by default, --apply archives
  hobbies, tech stack categories and old content pages and deletes four
  unused message overrides after a full JSON backup; run only after the
  redesign is live on production

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:49:43 +02:00

62 lines
2.2 KiB
TypeScript

"use client";
import React from "react";
import Link from "next/link";
import { useLocale, useTranslations } from "next-intl";
import { useConsent } from "./ConsentProvider";
const pill =
"inline-flex items-center rounded-full px-4 py-2 text-sm font-medium shadow-[inset_0_0_0_1.5px_rgb(var(--plakat-paper)/0.5)] transition-[background-color,color,transform] duration-150 ease-out hover:bg-paper hover:text-ink active:scale-[0.97]";
const Footer = () => {
const locale = useLocale();
const t = useTranslations("footer");
const { resetConsent } = useConsent();
const year = new Date().getFullYear();
return (
<footer className="bg-ink px-4 pb-10 pt-12 text-paper sm:px-6 lg:px-10">
<div className="flex flex-wrap items-end justify-between gap-6">
<Link
href={`/${locale}`}
className="font-display text-[clamp(4rem,14vw,9rem)] font-extrabold leading-[0.8] tracking-[-0.05em]"
aria-label="dk0"
>
dk<span className="text-signal">0</span>
</Link>
<a href="#top" className={pill}>
{t("backToTop")} <span aria-hidden="true" className="ml-1.5">↑</span>
</a>
</div>
<nav className="mt-8 flex flex-wrap gap-2 border-t-2 border-paper/20 pt-6" aria-label={t("legalNotice")}>
<Link href={`/${locale}/legal-notice`} className={pill}>
{t("legalNotice")}
</Link>
<Link href={`/${locale}/privacy-policy`} className={pill}>
{t("privacyPolicy")}
</Link>
<button type="button" onClick={resetConsent} className={pill} title={t("privacySettingsTitle")}>
{t("privacySettings")}
</button>
<a href="https://github.com/Denshooter" target="_blank" rel="noopener noreferrer" className={pill}>
GitHub
</a>
<a href="https://linkedin.com/in/dkonkol" target="_blank" rel="noopener noreferrer" className={pill}>
LinkedIn
</a>
</nav>
<div className="mt-8 grid gap-1.5 font-mono text-xs text-paper/70">
<p>
© {year} Dennis Konkol · {t("role")} · {t("madeIn")}
</p>
<p>{t("builtWith")}</p>
<p>{t("aiDisclaimer")}</p>
</div>
</footer>
);
};
export default Footer;