@ -37,9 +37,9 @@ try {
|
|||||||
if (!hotBrands.length) hotBrands = FAKE_HOT_BRANDS
|
if (!hotBrands.length) hotBrands = FAKE_HOT_BRANDS
|
||||||
|
|
||||||
// 年份筛选:写死,按需增删(数据最早约 2005 年,如需更老年份往数组里加即可)
|
// 年份筛选:写死,按需增删(数据最早约 2005 年,如需更老年份往数组里加即可)
|
||||||
// 年份:从当今年份往前推 15 年(含),末项加"X年前"兜底
|
// 年份:近 10 年(含当年),末项加"X年前"兜底
|
||||||
const currentYear = new Date().getFullYear()
|
const currentYear = new Date().getFullYear()
|
||||||
const yearFloor = currentYear - 15
|
const yearFloor = currentYear - 9
|
||||||
const yearOptions: { value: number | string; label: string }[] = []
|
const yearOptions: { value: number | string; label: string }[] = []
|
||||||
for (let y = currentYear; y >= yearFloor; y--) {
|
for (let y = currentYear; y >= yearFloor; y--) {
|
||||||
yearOptions.push({ value: y, label: String(y) })
|
yearOptions.push({ value: y, label: String(y) })
|
||||||
@ -110,27 +110,18 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="showsg-b" x-show="!collapsedGroups.designers">
|
<div class="showsg-b" x-show="!collapsedGroups.designers">
|
||||||
<ul class="showschecks">
|
<ul class="showschecks">
|
||||||
<!-- <li>
|
<template x-for="b in hotBrands.slice(0, 10)" :key="b.id">
|
||||||
<template x-if="item.type === 'letter'">
|
<li>
|
||||||
<div class="letter-head" x-text="item.letter"></div>
|
<label class="flex items-center gap-2 w-full cursor-pointer">
|
||||||
</template>
|
<input type="checkbox" :value="b.id" :checked="selectedBrands.includes(b.id)" @change="toggleBrand(b.id)" />
|
||||||
|
<span x-text="b.name"></span>
|
||||||
<template x-if="item.type === 'brand'">
|
<span class="ct" x-text="b.article_count ? b.article_count : ''"></span>
|
||||||
<label class="flex items-center gap-2 w-full cursor-pointer">
|
</label>
|
||||||
<input
|
</li>
|
||||||
type="checkbox"
|
</template>
|
||||||
:value="item.id"
|
</ul>
|
||||||
:checked="selectedBrands.includes(item.id)"
|
<a class="showsmore" @click="openBrandModal()" x-text="'ALL BRANDS +'" role="button" tabindex="0"></a>
|
||||||
@change="toggleBrand(item.id)"
|
|
||||||
>
|
|
||||||
<span x-text="item.name"></span>
|
|
||||||
<span class="ct" x-text="item.count ? item.count : ''"></span>
|
|
||||||
</label>
|
|
||||||
</template>
|
|
||||||
</li> -->
|
|
||||||
</ul>
|
|
||||||
<a class="showsmore" @click="openBrandModal()" x-text="'浏览全部品牌 +'"></a>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -185,7 +176,7 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<button class="showsclear" type="button" @click="clearAll()">Clear all ×</button>
|
<button class="showsclear" type="button" @click="clearAll()" x-show="pills.length > 0" x-cloak>Clear all ×</button>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
@ -320,6 +311,7 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
[x-cloak] { display: none !important; }
|
[x-cloak] { display: none !important; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 使用 @apply 精简并重构样式 */
|
/* 使用 @apply 精简并重构样式 */
|
||||||
.showsroot {
|
.showsroot {
|
||||||
@apply m-auto max-w-[1600px] pt-7 text-[#0a0a0a];
|
@apply m-auto max-w-[1600px] pt-7 text-[#0a0a0a];
|
||||||
@ -410,10 +402,10 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
.showsmore {
|
.showsmore {
|
||||||
@apply inline-block mt-[10px] text-[10.5px] uppercase tracking-[0.16em] text-[#555] cursor-pointer hover:text-black;
|
@apply block w-full mt-[12px] text-center text-[11px] uppercase tracking-[0.22em] text-black font-bold cursor-pointer;
|
||||||
}
|
}
|
||||||
.showsclear {
|
.showsclear {
|
||||||
@apply mt-[18px] w-full border-[1.5px] border-black bg-white text-black p-[11px_12px] text-[11px] uppercase tracking-[0.22em] font-bold cursor-pointer rounded-none transition-all duration-150 hover:bg-black hover:text-white;
|
@apply mt-[22px] block w-full text-left pt-[16px] border-t border-black/10 text-[11px] uppercase tracking-[0.18em] text-[#666] cursor-pointer hover:text-black transition-colors duration-150;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showsmain {
|
.showsmain {
|
||||||
@ -527,7 +519,7 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
}
|
}
|
||||||
.showsmodal-mask {
|
.showsmodal-mask {
|
||||||
@apply absolute inset-0 pointer-events-auto cursor-default;
|
@apply absolute inset-0 pointer-events-auto cursor-default;
|
||||||
background: transparent;
|
background: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
.showsmodal-panel {
|
.showsmodal-panel {
|
||||||
@apply relative w-full max-w-[680px] max-h-[72vh] bg-white flex flex-col border border-black/10 pointer-events-auto;
|
@apply relative w-full max-w-[680px] max-h-[72vh] bg-white flex flex-col border border-black/10 pointer-events-auto;
|
||||||
@ -763,12 +755,16 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
this.modalKeyword = ""
|
this.modalKeyword = ""
|
||||||
this.modalLetter = "HOT"
|
this.modalLetter = "HOT"
|
||||||
this.modalOpen = true
|
this.modalOpen = true
|
||||||
document.body.style.overflow = "hidden"
|
// 锁根滚动并补偿滚动条宽度,避免背景页面横向偏移
|
||||||
|
const sbw = window.innerWidth - document.documentElement.clientWidth
|
||||||
|
document.documentElement.style.overflow = "hidden"
|
||||||
|
if (sbw > 0) document.documentElement.style.paddingRight = sbw + "px"
|
||||||
await this.modalLoadHot()
|
await this.modalLoadHot()
|
||||||
},
|
},
|
||||||
closeBrandModal() {
|
closeBrandModal() {
|
||||||
this.modalOpen = false
|
this.modalOpen = false
|
||||||
document.body.style.overflow = ""
|
document.documentElement.style.overflow = ""
|
||||||
|
document.documentElement.style.paddingRight = ""
|
||||||
},
|
},
|
||||||
async modalLoadHot() {
|
async modalLoadHot() {
|
||||||
this.modalLetter = "HOT"
|
this.modalLetter = "HOT"
|
||||||
@ -830,7 +826,8 @@ const seasonOptions: { value: string; label: string }[] = [
|
|||||||
confirmBrandModal() {
|
confirmBrandModal() {
|
||||||
this.selectedBrands = [...this.modalSelected]
|
this.selectedBrands = [...this.modalSelected]
|
||||||
this.modalOpen = false
|
this.modalOpen = false
|
||||||
document.body.style.overflow = ""
|
document.documentElement.style.overflow = ""
|
||||||
|
document.documentElement.style.paddingRight = ""
|
||||||
this.refreshFilter()
|
this.refreshFilter()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import LanguageDetector from '@/components/LanguageDetector.astro'
|
|||||||
|
|
||||||
const { locale, t, getRelativeLocaleUrl } = getI18n(Astro)
|
const { locale, t, getRelativeLocaleUrl } = getI18n(Astro)
|
||||||
|
|
||||||
// 脚本内(打包型 <script>)无法用 {t()} 插值,需经 define:vars 把已翻译字符串传入
|
// 经 data-* 属性把已翻译字符串传入打包型 <script>;define:vars 会让脚本变内联 classic,导致 import 报错,故改用 data 属性
|
||||||
const hiLabel = t('Hi')
|
const hiLabel = t('Hi')
|
||||||
const logoutLabel = t('Logout')
|
const logoutLabel = t('Logout')
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ const headers = {
|
|||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2" id="auth-slot">
|
<div class="flex items-center gap-2" id="auth-slot" data-hi-label={hiLabel} data-logout-label={logoutLabel}>
|
||||||
<a href={href(locale, ROUTES.login)} class="hover:opacity-60 transition-opacity duration-200">{t('Login')}</a>
|
<a href={href(locale, ROUTES.login)} class="hover:opacity-60 transition-opacity duration-200">{t('Login')}</a>
|
||||||
<a href={href(locale, ROUTES.register)} class="hover:opacity-60 transition-opacity duration-200">{t('Signup')}</a>
|
<a href={href(locale, ROUTES.register)} class="hover:opacity-60 transition-opacity duration-200">{t('Signup')}</a>
|
||||||
</div>
|
</div>
|
||||||
@ -126,9 +126,11 @@ const headers = {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="relative z-[1] bg-white mt-20 pt-10 border-t-2 border-black text-black w-full font-sans">
|
<footer class="relative z-[1] bg-white mt-20 pt-10 border-t-2 border-black text-black w-full font-sans">
|
||||||
<script define:vars={{ hiLabel, logoutLabel }}>
|
<script>
|
||||||
import { getUser, fetchMe, clearSession } from "@/lib/api"
|
import { getUser, fetchMe, clearSession } from "@/lib/api"
|
||||||
const slot = document.getElementById("auth-slot")
|
const slot = document.getElementById("auth-slot")
|
||||||
|
const hiLabel = slot?.dataset.hiLabel ?? "Hi"
|
||||||
|
const logoutLabel = slot?.dataset.logoutLabel ?? "Logout"
|
||||||
function render(user) {
|
function render(user) {
|
||||||
if (!user) return // 未登录:保留 SSR 渲染的 Login/Signup(已带语言前缀,无需重写)
|
if (!user) return // 未登录:保留 SSR 渲染的 Login/Signup(已带语言前缀,无需重写)
|
||||||
slot.innerHTML = `<span class="opacity-70">${hiLabel}, ${user.username}</span><button id="logout-btn" class="hover:opacity-60 transition-opacity cursor-pointer bg-transparent border-0 p-0 font-bold text-[13px] uppercase tracking-[0.5px]">${logoutLabel}</button>`
|
slot.innerHTML = `<span class="opacity-70">${hiLabel}, ${user.username}</span><button id="logout-btn" class="hover:opacity-60 transition-opacity cursor-pointer bg-transparent border-0 p-0 font-bold text-[13px] uppercase tracking-[0.5px]">${logoutLabel}</button>`
|
||||||
|
|||||||
Reference in New Issue
Block a user