@ -1,6 +1,6 @@
|
||||
---
|
||||
import { getI18n } from '@/i18n/utils'
|
||||
import { href, PATH } from '@/lib/routes'
|
||||
import { href, ROUTES } from '@/lib/routes'
|
||||
|
||||
interface Props {
|
||||
module?: string
|
||||
@ -22,8 +22,8 @@ const { locale } = getI18n(Astro)
|
||||
{note || "该模块正在筹备中,尚未对外开放。站点正按模块逐个完善,你可以先浏览已上线的走秀档案。"}
|
||||
</p>
|
||||
<div class="cs-actions">
|
||||
<a class="cs-btn" href={href(locale, PATH.articles)}>浏览走秀档案 →</a>
|
||||
<a class="cs-btn-ghost" href={href(locale, PATH.home)}>返回首页</a>
|
||||
<a class="cs-btn" href={href(locale, ROUTES.articles)}>浏览走秀档案 →</a>
|
||||
<a class="cs-btn-ghost" href={href(locale, ROUTES.home)}>返回首页</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import ComingSoon from "@/components/ComingSoon.astro"
|
||||
import { toAbs } from "@/lib/api"
|
||||
import { getI18n } from "@/i18n/utils"
|
||||
import { href, PATH } from '@/lib/routes'
|
||||
import { href, ROUTES } from '@/lib/routes'
|
||||
import { getSsgPopularBrands } from "@/lib/api"
|
||||
|
||||
// 国际化:一行取当前语言 + 翻译函数
|
||||
@ -39,34 +39,31 @@ const galleryItems: GalleryItem[] = popular
|
||||
:class="{ 'is-active': activeTab === 'backstage' }"
|
||||
@click="activeTab = 'backstage'"
|
||||
>
|
||||
A
|
||||
<span class="text-xs uppercase tracking-widest bg-black text-white px-2 py-0.5 rounded-full font-mono font-bold align-super">Live</span>
|
||||
Runway
|
||||
<!-- <span class="text-xs uppercase tracking-widest bg-black text-white px-2 py-0.5 rounded-full font-mono font-bold align-super">Live</span> -->
|
||||
</li>
|
||||
<li
|
||||
class="tab text-[42px] font-extrabold cursor-pointer whitespace-nowrap"
|
||||
:class="{ 'is-active': activeTab === 'shows' }"
|
||||
@click="activeTab = 'shows'"
|
||||
>
|
||||
B
|
||||
<span class="text-xs uppercase tracking-widest bg-zinc-200 text-zinc-600 px-2 py-0.5 rounded-full font-mono font-bold align-super">Soon</span>
|
||||
Street Style
|
||||
</li>
|
||||
<li
|
||||
class="tab text-[42px] font-extrabold cursor-pointer whitespace-nowrap"
|
||||
:class="{ 'is-active': activeTab === 'events' }"
|
||||
@click="activeTab = 'events'"
|
||||
>
|
||||
C
|
||||
<span class="text-xs uppercase tracking-widest bg-zinc-200 text-zinc-600 px-2 py-0.5 rounded-full font-mono font-bold align-super">Soon</span>
|
||||
Social Media
|
||||
</li>
|
||||
<li
|
||||
<!-- <li
|
||||
class="tab text-[42px] font-extrabold cursor-pointer whitespace-nowrap"
|
||||
:class="{ 'is-active': activeTab === 'street' }"
|
||||
@click="activeTab = 'street'"
|
||||
>
|
||||
D
|
||||
<span class="text-xs uppercase tracking-widest bg-zinc-200 text-zinc-600 px-2 py-0.5 rounded-full font-mono font-bold align-super">Soon</span>
|
||||
</li>
|
||||
<a href={href(locale, PATH.brands)} class="tab text-[42px] font-extrabold cursor-pointer whitespace-nowrap hover:opacity-80">E</a>
|
||||
</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -86,7 +83,7 @@ const galleryItems: GalleryItem[] = popular
|
||||
{
|
||||
galleryItems.map((g, i) => (
|
||||
<div class="swiper-slide hs-slide">
|
||||
<a class="hs-item" href={href(locale, PATH.item(g.articleId))} data-idx={i}>
|
||||
<a class="hs-item" href={href(locale, ROUTES.item(g.articleId))} data-idx={i}>
|
||||
<!-- Alpine 管理单张图片的加载/失败状态 -->
|
||||
<div
|
||||
class="hs-img-box"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import type { RawArticle } from "@/lib/data"
|
||||
import Breadcrumb from "@/components/Breadcrumb.astro"
|
||||
import { getI18n } from "@/i18n/utils"
|
||||
import { href, PATH } from '@/lib/routes'
|
||||
import { href, ROUTES } from '@/lib/routes'
|
||||
import { ssrBase } from "@/lib/api"
|
||||
|
||||
interface Props {
|
||||
@ -32,8 +32,8 @@ const descParas = (article?.description || "")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean)
|
||||
|
||||
const homeHref = href(locale, PATH.home)
|
||||
const archiveHref = href(locale, PATH.shows)
|
||||
const homeHref = href(locale, ROUTES.home)
|
||||
const archiveHref = href(locale, ROUTES.shows)
|
||||
|
||||
const crumbs: { label: string; href: string }[] = [
|
||||
// {
|
||||
@ -58,11 +58,11 @@ if (article?.brand_id) {
|
||||
{
|
||||
article ? (
|
||||
<article class="mx-auto max-w-[1600px] px-5 md:px-10 py-12 md:py-16">
|
||||
<Breadcrumb items={crumbs}>
|
||||
{/* <Breadcrumb items={crumbs}>
|
||||
<span slot="current" class="max-w-[60vw] truncate">
|
||||
{article.title}
|
||||
</span>
|
||||
</Breadcrumb>
|
||||
</Breadcrumb> */}
|
||||
|
||||
<h1 class="font-black leading-[0.95] tracking-tight text-[10vw] md:text-[4.5rem] mt-8">
|
||||
{article.title}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
---
|
||||
import Breadcrumb from "@/components/Breadcrumb.astro"
|
||||
import { getBrands, getYears, type BrandEntry } from "@/lib/api"
|
||||
import { clientHref, PATH } from '@/lib/routes'
|
||||
import { clientHref, ROUTES } from '@/lib/routes'
|
||||
import { getI18n } from '@/i18n/utils'
|
||||
|
||||
|
||||
@ -33,7 +33,8 @@ if (!yearChips.length) yearChips = yearSeed
|
||||
<Breadcrumb>
|
||||
<span slot="current">{t('Runway looks')}</span>
|
||||
</Breadcrumb>
|
||||
<h1 class="showsh1">All Shows</h1>
|
||||
|
||||
<h1 class="showsh1">全部的 runway</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@ -479,57 +480,91 @@ if (!yearChips.length) yearChips = yearSeed
|
||||
|
||||
@keyframes hbxProg { 0% { left: -38%; } 100% { left: 100%; } }
|
||||
@keyframes hbxShim { 0%, 100% { opacity: .85; } 50% { opacity: .55; } }
|
||||
/* ===== 品牌筛选弹窗 ===== */
|
||||
/* ===== 品牌筛选弹窗(语言切换器风格:无 mask、顶部小箭头、干净白底列表) ===== */
|
||||
.showsmodal {
|
||||
@apply fixed inset-0 z-[60] flex items-center justify-center p-[16px];
|
||||
@apply fixed inset-0 z-[60] flex items-start justify-center pt-[14vh] pointer-events-none;
|
||||
}
|
||||
.showsmodal-mask {
|
||||
@apply absolute inset-0 bg-black/45;
|
||||
@apply absolute inset-0 pointer-events-auto cursor-default;
|
||||
background: transparent;
|
||||
}
|
||||
.showsmodal-panel {
|
||||
@apply relative w-full max-w-[680px] max-h-[86vh] bg-white flex flex-col border border-black;
|
||||
@apply relative w-full max-w-[460px] max-h-[72vh] bg-white flex flex-col border border-black/10 pointer-events-auto;
|
||||
box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
/* 顶部小三角箭头(语言切换器同款:白底 + 浅边框) */
|
||||
.showsmodal-panel::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: white;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
}
|
||||
.showsmodal-head {
|
||||
@apply flex items-center justify-between px-[16px] py-[13px] border-b border-black shrink-0;
|
||||
@apply flex items-center justify-between px-4 pt-4 pb-2 shrink-0;
|
||||
}
|
||||
.showsmodal-head h3 {
|
||||
@apply m-0 text-[13px] tracking-[0.2em] uppercase font-bold;
|
||||
@apply m-0 text-[12px] tracking-[0.22em] uppercase font-bold;
|
||||
}
|
||||
.showsmodal-x {
|
||||
@apply appearance-none bg-white border border-black w-[24px] h-[24px] inline-flex items-center justify-center cursor-pointer text-[12px] leading-none;
|
||||
@apply appearance-none bg-transparent border-0 w-6 h-6 inline-flex items-center justify-center cursor-pointer text-[14px] leading-none text-[#999] transition-colors hover:text-black;
|
||||
}
|
||||
.showsmodal-search {
|
||||
@apply px-4 pt-1 pb-3 shrink-0;
|
||||
}
|
||||
.showsmodal-x:hover { @apply bg-black text-white; }
|
||||
.showsmodal-search { @apply px-[16px] pt-[12px] pb-[8px] shrink-0; }
|
||||
.showsmodal-input {
|
||||
@apply w-full border border-black px-[10px] py-[8px] text-[13px] outline-none;
|
||||
@apply w-full border border-black/15 px-3 py-2 text-[13px] outline-none bg-[#fafafa] focus:bg-white focus:border-black;
|
||||
}
|
||||
.showsmodal-input:focus { @apply ring-1 ring-black; }
|
||||
.showsmodal-az {
|
||||
@apply flex flex-wrap gap-[4px] px-[16px] pb-[10px] border-b border-[#e6e6e6] shrink-0;
|
||||
@apply flex flex-wrap gap-1 px-4 pb-3 shrink-0;
|
||||
}
|
||||
.showsmodal-az .az {
|
||||
@apply appearance-none bg-white border border-[#ccc] w-[22px] h-[22px] text-[11px] cursor-pointer leading-none;
|
||||
@apply appearance-none bg-white border border-black/10 w-6 h-6 text-[10px] cursor-pointer leading-none font-mono transition-colors hover:bg-black/5;
|
||||
}
|
||||
.showsmodal-az .az.active {
|
||||
@apply bg-black text-white border-black;
|
||||
}
|
||||
.showsmodal-body {
|
||||
@apply flex-1 min-h-0 overflow-y-auto px-2 py-1;
|
||||
}
|
||||
.showsmodal-az .az.active { @apply bg-black text-white border-black; }
|
||||
.showsmodal-body { @apply flex-1 min-h-0 overflow-y-auto px-[16px] py-[8px]; }
|
||||
.showsmodal-hint {
|
||||
@apply text-[11px] tracking-[0.2em] uppercase text-[#888] py-[6px] pb-[8px];
|
||||
@apply text-[10px] tracking-[0.22em] uppercase text-[#999] px-3 py-2;
|
||||
}
|
||||
.showsmodal-loading {
|
||||
@apply flex justify-center py-6 text-[#bdbdbd];
|
||||
}
|
||||
.showsmodal-list {
|
||||
@apply list-none m-0 p-0;
|
||||
}
|
||||
.showsmodal-loading { @apply flex justify-center py-[28px] text-[#bdbdbd]; }
|
||||
.showsmodal-list { @apply list-none m-0 p-0; }
|
||||
.showsmodal-row {
|
||||
@apply flex items-center gap-[8px] w-full cursor-pointer py-[7px] border-b border-[#f0f0f0] text-[13px];
|
||||
@apply flex items-center gap-2 w-full cursor-pointer px-3 py-2 text-[13px] transition-colors hover:bg-black/5;
|
||||
}
|
||||
.showsmodal-name {
|
||||
@apply flex-1 truncate;
|
||||
}
|
||||
.showsmodal-ct {
|
||||
@apply text-[#999] text-[10px] ml-auto;
|
||||
}
|
||||
.showsmodal-empty {
|
||||
@apply py-6 text-center text-[#999] text-[13px];
|
||||
}
|
||||
.showsmodal-name { @apply flex-1 truncate; }
|
||||
.showsmodal-ct { @apply text-[#999] text-[11px] ml-auto; }
|
||||
.showsmodal-empty { @apply py-[28px] text-center text-[#999] text-[13px]; }
|
||||
.showsmodal-foot {
|
||||
@apply flex items-center justify-between px-[16px] py-[12px] border-t border-black shrink-0 text-[12px];
|
||||
@apply flex items-center justify-between px-4 py-3 border-t border-black/5 shrink-0 text-[11px] text-[#888];
|
||||
}
|
||||
.showsmodal-counter {
|
||||
@apply tracking-[0.06em];
|
||||
}
|
||||
.showsmodal-ok {
|
||||
@apply appearance-none bg-black text-white border border-black px-[22px] py-[8px] cursor-pointer text-[12px] tracking-[0.1em];
|
||||
@apply appearance-none bg-black text-white border border-black px-4 py-1.5 cursor-pointer text-[12px] tracking-[0.1em] transition-colors hover:bg-black/85;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -809,7 +844,7 @@ if (!yearChips.length) yearChips = yearSeed
|
||||
|
||||
// 辅助辅助工具函数
|
||||
toAbsUrl(url: string) { return toAbs(url) },
|
||||
itemHref(it: { id: string | number }) { return clientHref(this.locale, PATH.runwayLooks(it.id)) },
|
||||
itemHref(it: { id: string | number }) { return clientHref(this.locale, ROUTES.runwayLooks(it.id)) },
|
||||
ctLabel(ct?: string) {
|
||||
const map: Record<string, string> = { rtw: "Ready-to-Wear", menswear: "Menswear", couture: "Couture", resort: "Resort", pre_fall: "Pre-Fall" }
|
||||
return ct && map[ct] ? map[ct] : (ct || "")
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import { getReports, fmtDate } from "@/lib/data"
|
||||
import { href, PATH } from '@/lib/routes'
|
||||
import { href, ROUTES } from '@/lib/routes'
|
||||
import { getI18n } from "@/i18n/utils"
|
||||
|
||||
// 文章展示创意布局页:复用你现有的 Layout 外壳。
|
||||
@ -25,7 +25,7 @@ const itemBase = href(locale, "/items")
|
||||
<p>
|
||||
走秀趋势报告档案库。支持网格 / 杂志 / 时间轴三种创意视图自由切换,彩色配图由后端接口动态渲染。
|
||||
</p>
|
||||
<a href={href(locale, PATH.home)} class="archive-back">← Index</a>
|
||||
<a href={href(locale, ROUTES.home)} class="archive-back">← Index</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@ -69,7 +69,7 @@ const itemBase = href(locale, "/items")
|
||||
style={`--ratio:${s.ratio}`}
|
||||
>
|
||||
<div class="card-datecol"><span class="card-date">{fmt(s.created_at)}</span></div>
|
||||
<a class="card-media" href={href(locale, PATH.item(s.id))} aria-label={s.title}>
|
||||
<a class="card-media" href={href(locale, ROUTES.item(s.id))} aria-label={s.title}>
|
||||
<img src={s.cover} alt={s.title} loading="lazy" />
|
||||
{s.featured && <span class="card-flag">Featured</span>}
|
||||
</a>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
---
|
||||
import { getSsgBrands, type SsgBrand } from "@/lib/api"
|
||||
import { getI18n } from "@/i18n/utils"
|
||||
import { href, PATH } from "@/lib/routes"
|
||||
import { href, ROUTES } from "@/lib/routes"
|
||||
|
||||
type Brand = SsgBrand
|
||||
|
||||
@ -95,7 +95,7 @@ const total = orderedColumns.reduce((s, c) => s + c.items.length, 0)
|
||||
<ul class="brow-items">
|
||||
{col.items.map((b) => (
|
||||
<li>
|
||||
<a href={href(locale, PATH.articlesByBrand(b.id))}>{primaryName(b)}</a>
|
||||
<a href={href(locale, ROUTES.articlesByBrand(b.id))}>{primaryName(b)}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user