Files
NexStudio/src/components/SiteFooter.astro
Javaxman 0714ec1335 Avvia i18n reale della home su IT EN TH.
Introduco contenuti localizzati per menu, footer e principali sezioni della homepage, includendo il form contatti e i messaggi client per mantenere coerenza UX tra le tre lingue.

Made-with: Cursor
2026-04-27 09:12:00 +02:00

232 lines
8.4 KiB
Plaintext

---
import { getFooter } from '../data/home';
const path = Astro.url.pathname;
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
const footer = getFooter(currentLocale);
const hasNewsletterAction =
typeof footer.newsletter.actionUrl === 'string' &&
footer.newsletter.actionUrl.length > 0;
const nl = footer.newsletter;
const nextUrl =
typeof nl.successRedirect === 'string' && nl.successRedirect.length > 0
? nl.successRedirect
: '';
const notifySubject =
typeof nl.notifySubject === 'string' && nl.notifySubject.length > 0
? nl.notifySubject
: '';
const linkClass =
'text-sm text-sky-400/90 transition-colors hover:text-sky-300';
const withLocale = (href: string) => {
if (currentLocale === 'it') return href;
if (href.startsWith(`/${currentLocale}`)) return href;
if (href.startsWith('/#')) return `/${currentLocale}${href}`;
if (href.startsWith('/')) return `/${currentLocale}${href}`;
return href;
};
---
<footer id="site-footer" class="relative z-[1] border-t border-nx-border px-4 py-12 sm:px-6">
<div class="mx-auto max-w-6xl">
<!-- Griglia link; brand + slogan spostati in fondo a fianco al copyright -->
<div class="border-b border-nx-border py-10">
<div
class="grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-4 lg:items-start lg:gap-x-10 xl:gap-x-12"
>
<div class="min-w-0">
<p
class="mb-4 text-xs font-semibold uppercase tracking-wider text-nx-fg"
>
{footer.columnTitles.sections}
</p>
<ul class="space-y-2.5">
{footer.homeNav.map((link) => (
<li>
<a class={linkClass} href={withLocale(link.href)}>
{link.label}
</a>
</li>
))}
</ul>
</div>
<div class="min-w-0">
<p
class="mb-4 text-xs font-semibold uppercase tracking-wider text-nx-fg"
>
{footer.columnTitles.legal}
</p>
<ul class="space-y-2.5">
{footer.legalColumnNav.map((link) => (
<li>
<a class={linkClass} href={withLocale(link.href)}>
{link.label}
</a>
</li>
))}
</ul>
</div>
<div class="min-w-0">
<p
class="mb-4 text-xs font-semibold uppercase tracking-wider text-nx-fg"
>
{footer.columnTitles.social}
</p>
<ul class="space-y-2.5 text-sm">
{footer.socialLinks.map((item) => (
<li>
{item.href ? (
<a
class={linkClass}
href={item.href}
target="_blank"
rel="noopener noreferrer"
>
{item.label}
</a>
) : (
<span
class="cursor-not-allowed text-nx-muted opacity-50"
title={footer.labels.socialPlaceholderTitle}
>
{item.label}
</span>
)}
</li>
))}
</ul>
</div>
<div class="min-w-0">
<p
class="mb-4 text-xs font-semibold uppercase tracking-wider text-nx-fg"
>
{footer.columnTitles.company}
</p>
<ul class="space-y-2.5">
{footer.companyNav.map((link) => (
<li>
{link.href ? (
<a class={linkClass} href={withLocale(link.href)}>
{link.label}
</a>
) : (
<span class="text-sm text-nx-muted" title={footer.labels.companyPlaceholderTitle}>
{link.label}
</span>
)}
</li>
))}
</ul>
</div>
</div>
<div
class="relative mt-10 grid gap-8 pt-8 before:pointer-events-none before:absolute before:left-1/2 before:top-0 before:h-px before:w-screen before:-translate-x-1/2 before:bg-nx-border/70 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)] lg:items-start lg:gap-10"
data-nx-footer-print-collapsible
>
<div class="min-w-0">
<p class="text-xs font-semibold uppercase tracking-wider text-nx-fg">
{footer.labels.cookieTitle}
</p>
<p class="mt-1.5 max-w-xl text-xs leading-relaxed text-nx-muted">
{footer.cookiePreferences.hint}
</p>
<button
type="button"
class="mt-3 inline-flex h-10 shrink-0 items-center justify-center self-start rounded-lg border border-nx-border bg-nx-bg/50 px-4 text-sm font-medium text-sky-400/90 transition-colors hover:border-sky-500/35 hover:bg-sky-500/5 hover:text-sky-300"
data-nx-cc-open
>
{footer.cookiePreferences.label}
</button>
</div>
<div class="min-w-0">
<p class="text-xs font-semibold uppercase tracking-wider text-nx-fg">
{footer.newsletter.title}
</p>
<p class="mt-1.5 text-xs leading-relaxed text-nx-muted">
{footer.newsletter.description}
</p>
{
hasNewsletterAction ? (
<form
class="relative mt-3 flex flex-col gap-2 sm:flex-row sm:items-stretch"
action={nl.actionUrl}
method="post"
accept-charset="UTF-8"
>
{nextUrl ? <input type="hidden" name="_next" value={nextUrl} /> : null}
{notifySubject ? (
<input type="hidden" name="_subject" value={notifySubject} />
) : null}
<input
type="text"
name="_gotcha"
tabindex="-1"
autocomplete="off"
aria-hidden="true"
class="pointer-events-none absolute -left-[9999px] h-0 w-0 opacity-0"
/>
<input
type="email"
name={nl.fieldName}
required
autocomplete="email"
placeholder={nl.placeholder}
class="min-h-10 w-full rounded-lg border border-nx-border bg-nx-bg/80 px-3 text-sm text-nx-fg placeholder:text-nx-muted/70 outline-none ring-sky-500/30 focus:border-sky-500/40 focus:ring-2"
/>
<button
type="submit"
class="inline-flex h-10 shrink-0 items-center justify-center rounded-lg bg-nx-fg px-4 text-sm font-semibold text-nx-bg hover:bg-white sm:px-5"
>
{nl.buttonLabel}
</button>
</form>
) : (
<div class="mt-3 space-y-2">
<input
type="email"
disabled
placeholder={nl.placeholder}
class="min-h-10 w-full cursor-not-allowed rounded-lg border border-nx-border bg-nx-bg/40 px-3 text-sm text-nx-muted opacity-60"
aria-describedby="nx-newsletter-hint"
/>
<button
type="button"
disabled
class="inline-flex h-10 w-full cursor-not-allowed items-center justify-center rounded-lg border border-nx-border bg-nx-elevated/50 text-sm font-medium text-nx-muted opacity-70 sm:w-auto sm:px-5"
>
{nl.buttonLabel}
</button>
<p id="nx-newsletter-hint" class="text-xs leading-relaxed text-nx-muted">
{footer.labels.newsletterComingSoon}
</p>
</div>
)
}
</div>
</div>
</div>
<div
class="relative mt-0 flex flex-col gap-3 pt-8 before:pointer-events-none before:absolute before:left-1/2 before:top-0 before:h-px before:w-screen before:-translate-x-1/2 before:bg-nx-border sm:flex-row sm:items-end sm:justify-between sm:gap-6"
>
<p class="min-w-0 text-xs leading-relaxed text-nx-muted sm:text-sm">
© {new Date().getFullYear()} NexStudio. {footer.legalLine}
</p>
<p
class="max-w-md shrink-0 text-xs leading-relaxed text-nx-muted sm:max-w-lg sm:text-right sm:text-sm"
>
{footer.tagline}
</p>
</div>
</div>
</footer>