This commit is contained in:
toom1996
2026-09-22 21:39:45 +08:00
parent 9473f00c98
commit a8fcafac10
15 changed files with 816 additions and 716 deletions

View File

@ -1,19 +1,12 @@
---
import CollectionListView from "@/components/CollectionListView.astro"
import { getI18n } from '@/lib/i18n'
import CollectionCard from "@/components/CollectionCard.astro"
import RefineSidebar from "@/components/RefineSidebar.astro"
import "@/styles/look-grid.css"
import { buildYearOptions } from "@/lib/filters"
const { locale, t } = getI18n(Astro)
const { t } = getI18n(Astro)
// 年份筛选:近 10 年(含当年),末项兜底
const currentYear = new Date().getFullYear()
const yearFloor = currentYear - 9
const yearOptions: { value: number | string; label: string }[] = []
for (let y = currentYear; y >= yearFloor; y--) {
yearOptions.push({ value: y, label: String(y) })
}
yearOptions.push({ value: `before${yearFloor}`, label: `${yearFloor}年前` })
// 年份筛选:近 10 年(含当年),末项兜底(与走秀共用 lib/filters.ts)
const yearOptions = buildYearOptions()
// 排序选项:image_count 默认(按图片数降序)/ year_desc / year_asc
const sortOptions: { value: string; label: string }[] = [
@ -53,95 +46,14 @@ const streetGroups = [
]
---
<div class="snapsroot w-full" x-data="streetSnapsPage()" data-locale={locale}>
<!-- 顶部:极简眉头 -->
<header class="snapshead">
<div>
<h1 class="snapsh1">{t('All Street Snaps')}</h1>
</div>
</header>
<!-- 已激活筛选 pills -->
<div class="snapspills" x-show="pills.length > 0" x-cloak>
<template x-for="(p, i) in pills" :key="i">
<span class="snapspill">
<span x-text="p.label"></span>
<button class="x" type="button" @click="p.clear()">×</button>
</span>
</template>
</div>
<!-- 主体:左 sidebar(REFINE 筛选) + 右卡片网格 -->
<div class="snapsbody">
<!-- LEFT SIDEBAR -->
<aside class="snapsaside">
<div class="snapsaside-head">
<!-- <h2 class="snapsaside-h">REFINE</h2> -->
</div>
<div class="snapsaside-body">
<RefineSidebar groups={streetGroups} />
</div>
</aside>
<!-- MAIN:卡片网格(左封面 + 右标题 + 缩略图条带) -->
<main class="snapsmain">
<div class="snapscontent" :class="{ 'is-loading': loading }">
<!-- 骨架屏:结构与真实卡片完全一致,loading 期间占位,杜绝尺寸抖动 -->
<template x-if="loading && items.length === 0">
<div class="snapsgrid" aria-hidden="true">
<template x-for="i in skeletonCount" :key="'skel-'+i">
<div class="snapscard snapscard--skel">
<div class="snapscard-left">
<div class="snapscard-img"></div>
</div>
<div class="snapscard-right">
<div class="snapscard-info">
<div class="snapsline h-[41px] mb-[10px] rounded-[2px]"></div>
<div class="snapsline h-[29px] mb-[14px] rounded-[2px]"></div>
</div>
<div class="snapscard-strip">
<div class="snapscard-thumb"></div>
<div class="snapscard-thumb"></div>
<div class="snapscard-thumb"></div>
<div class="snapscard-thumb"></div>
<div class="snapscard-thumb"></div>
</div>
</div>
</div>
</template>
</div>
</template>
<!-- Empty -->
<template x-if="!loading && items.length === 0">
<div class="snapsempty">No street snaps match the current filters</div>
</template>
<!-- Card List -->
<template x-if="!loading && items.length > 0">
<div class="snapsgrid">
<template x-for="it in items" :key="it.id">
<CollectionCard />
</template>
</div>
</template>
</div>
<nav class="snappager" x-show="lastPage > 1" aria-label="Pagination">
<button login-required class="pg pg-prev" type="button" :disabled="page <= 1 || loading" @click="prevPage()">‹ Prev</button>
<template x-for="(p, i) in pageList" :key="i">
<span class="pg-wrap">
<span class="pg-ellipsis" x-show="p === '...'" x-text="'…'"></span>
<button login-required class="pg" type="button" x-show="p !== '...'" :class="{ 'is-current': p === page }" :disabled="p === page" @click="goPage(p)" x-text="p"></button>
</span>
</template>
<button login-required class="pg pg-next" type="button" :disabled="page >= lastPage || loading" @click="nextPage()">Next ›</button>
</nav>
</main>
</div>
</div>
<CollectionListView
prefix="snaps"
alpineName="streetSnapsPage"
title={t('All Street Snaps')}
groups={streetGroups}
skeletonLines={2}
emptyText="No street snaps match the current filters"
/>
<script>
@ -188,7 +100,8 @@ const streetGroups = [
},
// 已激活筛选 chips(顶部 pills + 侧栏 Clear all 的可见性都依赖它)
get pills() {
// 必须是方法:createCollectionPage 用对象展开返回,getter 会在展开时被求值冻结成静态值,模板里写 pills()
pills() {
const out: { label: string; clear: () => void }[] = []
if (this.selectedYear) {
const hit = this.yearOptions.find((o: any) => String(o.value) === String(this.selectedYear))