@ -1,9 +1,9 @@
|
||||
---
|
||||
import '../styles/global.css'
|
||||
import '@/styles/global.css'
|
||||
import { getRelativeLocaleUrl } from 'astro:i18n'
|
||||
import { useTranslations, DEFAULT_LOCALE, type Locale } from '../i18n/utils'
|
||||
import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '../i18n/config'
|
||||
import LanguageDetector from '../components/LanguageDetector.astro'
|
||||
import { getI18n } from '@/i18n/utils'
|
||||
import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '@/i18n/config'
|
||||
import LanguageDetector from '@/components/LanguageDetector.astro'
|
||||
|
||||
const {
|
||||
title = 'Portfolio Studio',
|
||||
@ -12,14 +12,21 @@ const {
|
||||
activeThemePalette = null,
|
||||
} = Astro.props;
|
||||
|
||||
const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE
|
||||
const { t } = useTranslations(locale)
|
||||
const { locale, t } = getI18n(Astro)
|
||||
|
||||
// 当前路径(去掉语言前缀),供语言切换器「换前缀、留路径」用,例如 /cn/women → /women
|
||||
const pathSegments = Astro.url.pathname.split('/');
|
||||
const firstSegment = pathSegments[1] || '';
|
||||
const currentPath = (LOCALES as readonly string[]).includes(firstSegment)
|
||||
? '/' + pathSegments.slice(2).filter(Boolean).join('/') || '/'
|
||||
: Astro.url.pathname;
|
||||
const queryString = Astro.url.search;
|
||||
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang={locale === 'cn' ? 'zh-CN' : 'en'}>
|
||||
<head>
|
||||
<!-- <LanguageDetector /> -->
|
||||
<!-- TODO <LanguageDetector /> -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
@ -80,9 +87,9 @@ const { t } = useTranslations(locale)
|
||||
>
|
||||
{LOCALES.map((l) => (
|
||||
<li>
|
||||
<a
|
||||
href={getRelativeLocaleUrl(l)}
|
||||
@click="open = false"
|
||||
<a
|
||||
href={getRelativeLocaleUrl(l, currentPath) + queryString}
|
||||
@click="open = false"
|
||||
class:list={[
|
||||
'block px-4 py-1.5 text-[12px] uppercase tracking-[0.5px] hover:bg-black/5 transition-colors',
|
||||
l === locale ? 'font-bold' : 'opacity-60',
|
||||
@ -105,7 +112,7 @@ const { t } = useTranslations(locale)
|
||||
|
||||
<footer class="relative z-[1] bg-white mt-20 pt-10 border-t-2 border-black text-black w-full font-sans">
|
||||
<script>
|
||||
import { getUser, fetchMe, clearSession } from "../lib/auth.ts"
|
||||
import { getUser, fetchMe, clearSession } from "@/lib/auth.ts"
|
||||
const slot = document.getElementById("auth-slot")
|
||||
function render(user) {
|
||||
if (!user) return // 未登录:保留 SSR 渲染的 Login/Signup(已带语言前缀,无需重写)
|
||||
@ -193,27 +200,6 @@ const { t } = useTranslations(locale)
|
||||
|
||||
</div>
|
||||
|
||||
{/* Active Theme Strip */}
|
||||
{activeThemePalette && (
|
||||
<div class="mb-6 p-4 bg-zinc-50 border border-zinc-200 flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3">
|
||||
<div class="flex items-center gap-2 text-xs font-mono">
|
||||
<span class="w-2.5 h-2.5 rounded-full bg-emerald-500 animate-pulse"></span>
|
||||
<span class="font-bold uppercase">Active Site Theme:</span>
|
||||
<span class="text-zinc-600">{activeThemePalette.name}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 h-6 w-48 border border-zinc-300 overflow-hidden">
|
||||
{activeThemePalette.colors.map((c) => (
|
||||
<div
|
||||
style={`background-color: ${c.hex}`}
|
||||
class="h-full flex-1"
|
||||
title={`${c.name} (${c.hex})`}
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Bottom Legal & Back To Top */}
|
||||
<div class="flex flex-col sm:flex-row justify-between items-center text-[12px] font-mono text-zinc-500 gap-4">
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user