Aggiunge menu lingua dropdown e base i18n IT/EN/TH.
Introduce routing multilingua con locale tailandese, selettore lingua a tendina con icone bandiera SVG e gestione chiusura click-outside/Esc, oltre a integrazione Turnstile lato form contatti. Made-with: Cursor
This commit is contained in:
5
src/pages/en/about.astro
Normal file
5
src/pages/en/about.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../about.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/codice-etico.astro
Normal file
5
src/pages/en/codice-etico.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../codice-etico.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/cookies.astro
Normal file
5
src/pages/en/cookies.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../cookies.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/dove-siamo.astro
Normal file
5
src/pages/en/dove-siamo.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../dove-siamo.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/gdpr.astro
Normal file
5
src/pages/en/gdpr.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../gdpr.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/index.astro
Normal file
5
src/pages/en/index.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../index.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/modello-organizzativo.astro
Normal file
5
src/pages/en/modello-organizzativo.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../modello-organizzativo.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/news.astro
Normal file
5
src/pages/en/news.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../news.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/newsletter/grazie.astro
Normal file
5
src/pages/en/newsletter/grazie.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../../newsletter/grazie.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/privacy.astro
Normal file
5
src/pages/en/privacy.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../privacy.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/en/terms.astro
Normal file
5
src/pages/en/terms.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../terms.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
@ -18,6 +18,24 @@ import {
|
||||
} from '../data/home';
|
||||
|
||||
const techSliderItems = stackSection.techSlider.items;
|
||||
const path = Astro.url.pathname;
|
||||
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
|
||||
const currentLocale = localeMatch?.[1] ?? 'it';
|
||||
const localize = (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;
|
||||
};
|
||||
const langItHref = '/';
|
||||
const langEnHref = '/en';
|
||||
const langThHref = '/th';
|
||||
const langMeta = {
|
||||
it: { code: 'IT', label: 'Italiano', flagSrc: '/images/flags/it.svg' },
|
||||
en: { code: 'EN', label: 'English', flagSrc: '/images/flags/en.svg' },
|
||||
th: { code: 'TH', label: 'ไทย', flagSrc: '/images/flags/th.svg' },
|
||||
} as const;
|
||||
---
|
||||
|
||||
<BaseLayout title={siteMeta.title} description={siteMeta.description}>
|
||||
@ -37,7 +55,7 @@ const techSliderItems = stackSection.techSlider.items;
|
||||
<div
|
||||
class="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-3 sm:px-6"
|
||||
>
|
||||
<a href="/" class="group no-underline">
|
||||
<a href={localize('/')} class="group no-underline">
|
||||
<span
|
||||
class="text-2xl font-semibold tracking-tight text-nx-fg group-hover:text-white sm:text-3xl"
|
||||
>{navigation.brandName}</span
|
||||
@ -55,7 +73,7 @@ const techSliderItems = stackSection.techSlider.items;
|
||||
return (
|
||||
<a
|
||||
class="nx-nav-link"
|
||||
href={item.href}
|
||||
href={localize(item.href)}
|
||||
data-section={sectionId}
|
||||
data-nav-active="false"
|
||||
>
|
||||
@ -66,6 +84,65 @@ const techSliderItems = stackSection.techSlider.items;
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-2 sm:gap-3">
|
||||
<details class="relative hidden sm:block" data-lang-dropdown>
|
||||
<summary
|
||||
class="inline-flex h-10 cursor-pointer list-none items-center gap-2 rounded-lg border border-nx-border/80 bg-nx-bg/50 px-3 text-xs font-medium text-nx-fg transition-colors hover:border-sky-500/35 hover:text-white"
|
||||
aria-label="Seleziona lingua"
|
||||
>
|
||||
<img src={langMeta[currentLocale].flagSrc} alt="" class="h-3.5 w-5 rounded-[2px] object-cover" loading="lazy" decoding="async" />
|
||||
<span>{langMeta[currentLocale].code}</span>
|
||||
<svg class="h-3.5 w-3.5 text-nx-muted" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.168l3.71-3.938a.75.75 0 1 1 1.08 1.04l-4.25 4.5a.75.75 0 0 1-1.08 0l-4.25-4.5a.75.75 0 0 1 .02-1.06Z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</summary>
|
||||
<div
|
||||
class="absolute right-0 top-12 z-50 min-w-44 overflow-hidden rounded-lg border border-nx-border bg-nx-elevated/95 p-1 shadow-xl backdrop-blur"
|
||||
role="menu"
|
||||
>
|
||||
<a
|
||||
href={langItHref}
|
||||
class:list={[
|
||||
'flex items-center justify-between rounded-md px-3 py-2 text-sm text-nx-muted transition-colors hover:bg-white/5 hover:text-nx-fg',
|
||||
currentLocale === 'it' && 'bg-white/5 text-nx-fg',
|
||||
]}
|
||||
aria-current={currentLocale === 'it' ? 'page' : undefined}
|
||||
>
|
||||
<span class="flex items-center gap-2">
|
||||
<img src={langMeta.it.flagSrc} alt="" class="h-3.5 w-5 rounded-[2px] object-cover" loading="lazy" decoding="async" />
|
||||
{langMeta.it.label}
|
||||
</span>
|
||||
<span class="text-xs">{langMeta.it.code}</span>
|
||||
</a>
|
||||
<a
|
||||
href={langEnHref}
|
||||
class:list={[
|
||||
'flex items-center justify-between rounded-md px-3 py-2 text-sm text-nx-muted transition-colors hover:bg-white/5 hover:text-nx-fg',
|
||||
currentLocale === 'en' && 'bg-white/5 text-nx-fg',
|
||||
]}
|
||||
aria-current={currentLocale === 'en' ? 'page' : undefined}
|
||||
>
|
||||
<span class="flex items-center gap-2">
|
||||
<img src={langMeta.en.flagSrc} alt="" class="h-3.5 w-5 rounded-[2px] object-cover" loading="lazy" decoding="async" />
|
||||
{langMeta.en.label}
|
||||
</span>
|
||||
<span class="text-xs">{langMeta.en.code}</span>
|
||||
</a>
|
||||
<a
|
||||
href={langThHref}
|
||||
class:list={[
|
||||
'flex items-center justify-between rounded-md px-3 py-2 text-sm text-nx-muted transition-colors hover:bg-white/5 hover:text-nx-fg',
|
||||
currentLocale === 'th' && 'bg-white/5 text-nx-fg',
|
||||
]}
|
||||
aria-current={currentLocale === 'th' ? 'page' : undefined}
|
||||
>
|
||||
<span class="flex items-center gap-2">
|
||||
<img src={langMeta.th.flagSrc} alt="" class="h-3.5 w-5 rounded-[2px] object-cover" loading="lazy" decoding="async" />
|
||||
{langMeta.th.label}
|
||||
</span>
|
||||
<span class="text-xs">{langMeta.th.code}</span>
|
||||
</a>
|
||||
</div>
|
||||
</details>
|
||||
<button
|
||||
type="button"
|
||||
data-nx-chat-open
|
||||
@ -122,7 +199,7 @@ const techSliderItems = stackSection.techSlider.items;
|
||||
return (
|
||||
<a
|
||||
class="nx-nav-link block py-1"
|
||||
href={item.href}
|
||||
href={localize(item.href)}
|
||||
data-section={sectionId}
|
||||
data-nav-active="false"
|
||||
@click="mobile = false"
|
||||
@ -663,5 +740,6 @@ const techSliderItems = stackSection.techSlider.items;
|
||||
</div>
|
||||
<script>
|
||||
import '../scripts/nx-nav-spy.ts';
|
||||
import '../scripts/nx-lang-dropdown.ts';
|
||||
</script>
|
||||
</BaseLayout>
|
||||
|
||||
5
src/pages/th/about.astro
Normal file
5
src/pages/th/about.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../about.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/codice-etico.astro
Normal file
5
src/pages/th/codice-etico.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../codice-etico.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/cookies.astro
Normal file
5
src/pages/th/cookies.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../cookies.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/dove-siamo.astro
Normal file
5
src/pages/th/dove-siamo.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../dove-siamo.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/gdpr.astro
Normal file
5
src/pages/th/gdpr.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../gdpr.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/index.astro
Normal file
5
src/pages/th/index.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../index.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/modello-organizzativo.astro
Normal file
5
src/pages/th/modello-organizzativo.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../modello-organizzativo.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/news.astro
Normal file
5
src/pages/th/news.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../news.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/newsletter/grazie.astro
Normal file
5
src/pages/th/newsletter/grazie.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../../newsletter/grazie.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/privacy.astro
Normal file
5
src/pages/th/privacy.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../privacy.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
5
src/pages/th/terms.astro
Normal file
5
src/pages/th/terms.astro
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
import Page from '../terms.astro';
|
||||
---
|
||||
|
||||
<Page />
|
||||
Reference in New Issue
Block a user