@ -1,16 +1,27 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
import alpinejs from '@astrojs/alpinejs';
|
import alpinejs from '@astrojs/alpinejs';
|
||||||
|
|
||||||
|
|
||||||
|
import node from '@astrojs/node';
|
||||||
|
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()]
|
plugins: [tailwindcss()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
// 路径别名:@ -> 项目 src 目录(与 tsconfig paths 一致)
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
locales: ['en', 'cn'],
|
locales: ['en', 'cn'],
|
||||||
@ -18,9 +29,15 @@ export default defineConfig({
|
|||||||
prefixDefaultLocale: true, // 英文在根路径 /shows,中文在 /cn/shows
|
prefixDefaultLocale: true, // 英文在根路径 /shows,中文在 /cn/shows
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
// 示例:在构建过程中生 成`page.html` 而不是 `page/index.html`。
|
// 示例:在构建过程中生 成`page.html` 而不是 `page/index.html`。
|
||||||
// format: 'file'
|
// format: 'file'
|
||||||
},
|
},
|
||||||
integrations: [alpinejs()]
|
|
||||||
|
integrations: [alpinejs()],
|
||||||
|
|
||||||
|
adapter: node({
|
||||||
|
mode: 'standalone'
|
||||||
|
})
|
||||||
});
|
});
|
||||||
234
package-lock.json
generated
234
package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/alpinejs": "^1.0.0",
|
"@astrojs/alpinejs": "^1.0.0",
|
||||||
|
"@astrojs/node": "^11.1.2",
|
||||||
"@tailwindcss/vite": "^4.3.3",
|
"@tailwindcss/vite": "^4.3.3",
|
||||||
"@types/alpinejs": "^3.13.11",
|
"@types/alpinejs": "^3.13.11",
|
||||||
"alpinejs": "^3.16.1",
|
"alpinejs": "^3.16.1",
|
||||||
@ -235,6 +236,20 @@
|
|||||||
"satteri": "^0.9.1"
|
"satteri": "^0.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@astrojs/node": {
|
||||||
|
"version": "11.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@astrojs/node/-/node-11.1.2.tgz",
|
||||||
|
"integrity": "sha512-lbOjylG18s8wURjT9teqa/SPXVtVpBgm9vccEg/BXlrW3ktqqgFv23vtOswEfluDmx2Z74ngyGE6hrGC14qWow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/internal-helpers": "0.10.2",
|
||||||
|
"send": "^1.2.1",
|
||||||
|
"server-destroy": "^1.0.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"astro": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@astrojs/prism": {
|
"node_modules/@astrojs/prism": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/@astrojs/prism/-/prism-4.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/@astrojs/prism/-/prism-4.0.2.tgz",
|
||||||
@ -522,6 +537,16 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@emnapi/runtime": {
|
||||||
|
"version": "1.11.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
|
||||||
|
"integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@emnapi/wasi-threads": {
|
"node_modules/@emnapi/wasi-threads": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz",
|
||||||
@ -2447,8 +2472,7 @@
|
|||||||
"version": "3.13.11",
|
"version": "3.13.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/alpinejs/-/alpinejs-3.13.11.tgz",
|
||||||
"integrity": "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA==",
|
"integrity": "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.9",
|
"version": "1.0.9",
|
||||||
@ -2524,7 +2548,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.16.1.tgz",
|
||||||
"integrity": "sha512-QXcW8MK9JoG8GZ7vCt2cXJlcEPIA7Xk/7IQ1+L2iLp7sXcIxct0PrgidmHzK97gD9QlfUjHXPxujdZ1mC2PYVg==",
|
"integrity": "sha512-QXcW8MK9JoG8GZ7vCt2cXJlcEPIA7Xk/7IQ1+L2iLp7sXcIxct0PrgidmHzK97gD9QlfUjHXPxujdZ1mC2PYVg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "~3.1.1"
|
"@vue/reactivity": "~3.1.1"
|
||||||
}
|
}
|
||||||
@ -2889,12 +2912,38 @@
|
|||||||
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
|
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
|
||||||
"license": "CC0-1.0"
|
"license": "CC0-1.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/defu": {
|
"node_modules/defu": {
|
||||||
"version": "6.1.7",
|
"version": "6.1.7",
|
||||||
"resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.7.tgz",
|
"resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.7.tgz",
|
||||||
"integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
|
"integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/depd": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dequal": {
|
"node_modules/dequal": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz",
|
||||||
@ -3023,6 +3072,21 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/encodeurl": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.24.5",
|
"version": "5.24.5",
|
||||||
"resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
|
"resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz",
|
||||||
@ -3060,7 +3124,6 @@
|
|||||||
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
|
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"esbuild": "bin/esbuild"
|
"esbuild": "bin/esbuild"
|
||||||
},
|
},
|
||||||
@ -3096,12 +3159,27 @@
|
|||||||
"@esbuild/win32-x64": "0.28.1"
|
"@esbuild/win32-x64": "0.28.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/estree-walker": {
|
"node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eventemitter3": {
|
"node_modules/eventemitter3": {
|
||||||
"version": "5.0.4",
|
"version": "5.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
||||||
@ -3185,6 +3263,15 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fresh": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@ -3369,6 +3456,32 @@
|
|||||||
"integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
|
"integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
|
||||||
"license": "BSD-2-Clause"
|
"license": "BSD-2-Clause"
|
||||||
},
|
},
|
||||||
|
"node_modules/http-errors": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"depd": "~2.0.0",
|
||||||
|
"inherits": "~2.0.4",
|
||||||
|
"setprototypeof": "~1.2.0",
|
||||||
|
"statuses": "~2.0.2",
|
||||||
|
"toidentifier": "~1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/iron-webcrypto": {
|
"node_modules/iron-webcrypto": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmmirror.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
|
"resolved": "https://registry.npmmirror.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz",
|
||||||
@ -3836,6 +3949,31 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.54.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
|
||||||
|
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "^1.54.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mrmime": {
|
"node_modules/mrmime": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz",
|
||||||
@ -3845,6 +3983,12 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.16",
|
"version": "3.3.16",
|
||||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.16.tgz",
|
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.16.tgz",
|
||||||
@ -3948,6 +4092,18 @@
|
|||||||
"integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
|
"integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/on-finished": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/oniguruma-parser": {
|
"node_modules/oniguruma-parser": {
|
||||||
"version": "0.12.2",
|
"version": "0.12.2",
|
||||||
"resolved": "https://registry.npmmirror.com/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
|
"resolved": "https://registry.npmmirror.com/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
|
||||||
@ -4112,6 +4268,19 @@
|
|||||||
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
|
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/range-parser": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readdirp": {
|
"node_modules/readdirp": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-5.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-5.0.0.tgz",
|
||||||
@ -4250,6 +4419,44 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/send": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"encodeurl": "^2.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"etag": "^1.8.1",
|
||||||
|
"fresh": "^2.0.0",
|
||||||
|
"http-errors": "^2.0.1",
|
||||||
|
"mime-types": "^3.0.2",
|
||||||
|
"ms": "^2.1.3",
|
||||||
|
"on-finished": "^2.4.1",
|
||||||
|
"range-parser": "^1.2.1",
|
||||||
|
"statuses": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/server-destroy": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/setprototypeof": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/sharp": {
|
"node_modules/sharp": {
|
||||||
"version": "0.35.3",
|
"version": "0.35.3",
|
||||||
"resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.35.3.tgz",
|
"resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.35.3.tgz",
|
||||||
@ -4356,6 +4563,15 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/statuses": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/stringify-entities": {
|
"node_modules/stringify-entities": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
"resolved": "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
||||||
@ -4473,6 +4689,15 @@
|
|||||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toidentifier": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/trim-lines": {
|
"node_modules/trim-lines": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz",
|
||||||
@ -4759,7 +4984,6 @@
|
|||||||
"resolved": "https://registry.npmmirror.com/vite/-/vite-8.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/vite/-/vite-8.2.0.tgz",
|
||||||
"integrity": "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==",
|
"integrity": "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.33.0",
|
"lightningcss": "^1.33.0",
|
||||||
"picomatch": "^4.0.5",
|
"picomatch": "^4.0.5",
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/alpinejs": "^1.0.0",
|
"@astrojs/alpinejs": "^1.0.0",
|
||||||
|
"@astrojs/node": "^11.1.2",
|
||||||
"@tailwindcss/vite": "^4.3.3",
|
"@tailwindcss/vite": "^4.3.3",
|
||||||
"@types/alpinejs": "^3.13.11",
|
"@types/alpinejs": "^3.13.11",
|
||||||
"alpinejs": "^3.16.1",
|
"alpinejs": "^3.16.1",
|
||||||
|
|||||||
51
src/components/Breadcrumb.astro
Normal file
51
src/components/Breadcrumb.astro
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
import { useTranslations, DEFAULT_LOCALE, type Locale } from "@/i18n/utils";
|
||||||
|
|
||||||
|
interface Crumb {
|
||||||
|
/** i18n key:英文原文,如 'Home' / 'Runway Archive';中文环境自动取字典翻译 */
|
||||||
|
label: string;
|
||||||
|
href: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** 中间层级的面包屑项(不含末项)。末项由 <slot name="current"> 提供(如动态年份) */
|
||||||
|
items?: Crumb[];
|
||||||
|
/** 可选:显式指定语言;缺省时跟随当前页面语言(Astro.currentLocale) */
|
||||||
|
locale?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { items = [], locale } = Astro.props;
|
||||||
|
const currentLocale = (locale ?? Astro.currentLocale ?? DEFAULT_LOCALE) as Locale;
|
||||||
|
const { t } = useTranslations(currentLocale);
|
||||||
|
---
|
||||||
|
|
||||||
|
<nav class="crumb" aria-label="Breadcrumb">
|
||||||
|
{
|
||||||
|
items.map((it) => (
|
||||||
|
<Fragment>
|
||||||
|
<a href={it.href} class="crumb-link">{t(it.label)}</a>
|
||||||
|
<span class="crumb-sep" aria-hidden="true">/</span>
|
||||||
|
</Fragment>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
<span class="crumb-cur" aria-current="page">
|
||||||
|
<slot name="current" />
|
||||||
|
</span>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@reference "tailwindcss";
|
||||||
|
|
||||||
|
.crumb {
|
||||||
|
@apply inline-flex items-center gap-[10px] mb-[10px] text-[11px] tracking-[0.18em] uppercase text-[#999] no-underline;
|
||||||
|
}
|
||||||
|
.crumb-link {
|
||||||
|
@apply text-black no-underline transition-colors duration-150 hover:text-[#888];
|
||||||
|
}
|
||||||
|
.crumb-sep {
|
||||||
|
@apply text-[#cfcfcf] select-none;
|
||||||
|
}
|
||||||
|
.crumb-cur {
|
||||||
|
@apply text-[#999];
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,15 +1,14 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
import ComingSoon from "./ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
import { getShows, seriesLabel } from "../lib/data"
|
import { getShows, seriesLabel } from "@/lib/data"
|
||||||
import { useTranslations, DEFAULT_LOCALE, type Locale } from "../i18n/utils"
|
import { getI18n } from "@/i18n/utils"
|
||||||
|
|
||||||
// SSR 预取走秀数据
|
// SSR 预取走秀数据
|
||||||
const shows = await getShows(20)
|
const shows = await getShows(20)
|
||||||
|
|
||||||
// 国际化:取当前页面语言(Astro 路由解析)与翻译函数
|
// 国际化:一行取当前语言 + 翻译函数
|
||||||
const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE
|
const { locale, t } = getI18n(Astro)
|
||||||
const { t } = useTranslations(locale)
|
|
||||||
|
|
||||||
type GalleryItem = {
|
type GalleryItem = {
|
||||||
src: string;
|
src: string;
|
||||||
|
|||||||
0
src/components/RunwayLooks.astro
Normal file
0
src/components/RunwayLooks.astro
Normal file
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import astroLogo from '../assets/astro.svg';
|
import astroLogo from '@/assets/astro.svg';
|
||||||
import background from '../assets/background.svg';
|
import background from '@/assets/background.svg';
|
||||||
---
|
---
|
||||||
|
|
||||||
<div id="container">
|
<div id="container">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="About" moduleZh="关于" />
|
<ComingSoon module="About" moduleZh="关于" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="Contact" moduleZh="联系" />
|
<ComingSoon module="Contact" moduleZh="联系" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="Latest Projects" moduleZh="最新项目" />
|
<ComingSoon module="Latest Projects" moduleZh="最新项目" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="Sign In" moduleZh="登录" note="账户系统正在筹备中,暂未开放注册与登录。" />
|
<ComingSoon module="Sign In" moduleZh="登录" note="账户系统正在筹备中,暂未开放注册与登录。" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="Portfolio" moduleZh="作品集" />
|
<ComingSoon module="Portfolio" moduleZh="作品集" />
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
// 页面主体(与语言无关的内容),由根页面与 [locale] 页面共用
|
||||||
import ComingSoon from "../../components/ComingSoon.astro"
|
import ComingSoon from "@/components/ComingSoon.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<ComingSoon module="Create Account" moduleZh="注册" note="账户系统正在筹备中,暂未开放注册与登录。" />
|
<ComingSoon module="Create Account" moduleZh="注册" note="账户系统正在筹备中,暂未开放注册与登录。" />
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<h1 class="font-serif font-black leading-[0.95] tracking-tight text-[10vw] md:text-[4.5rem] mt-8" x-text="article?.title"></h1>
|
<h1 class="font-black leading-[0.95] tracking-tight text-[10vw] md:text-[4.5rem] mt-8" x-text="article?.title"></h1>
|
||||||
|
|
||||||
<!-- 元信息 -->
|
<!-- 元信息 -->
|
||||||
<div class="mt-6 flex flex-wrap items-center gap-x-6 gap-y-2 text-[12px] font-mono uppercase tracking-widest text-[#666]">
|
<div class="mt-6 flex flex-wrap items-center gap-x-6 gap-y-2 text-[12px] font-mono uppercase tracking-widest text-[#666]">
|
||||||
@ -42,32 +42,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 正文 -->
|
|
||||||
<div class="mt-12 grid md:grid-cols-12 gap-8">
|
|
||||||
<div class="md:col-span-2 text-[11px] font-mono uppercase tracking-widest text-[#999] pt-1">
|
|
||||||
Report
|
|
||||||
</div>
|
|
||||||
<div class="md:col-span-10 max-w-[68ch] space-y-5 text-[16px] leading-[1.9] text-[#222]">
|
|
||||||
<template x-for="(paragraph, idx) in bodyParagraphs" :key="idx">
|
|
||||||
<p x-text="paragraph"></p>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图片集 -->
|
<!-- 图片集 -->
|
||||||
<section class="mt-16" x-show="article?.images && article.images.length > 0">
|
<section class="mt-16" x-show="article?.images && article.images.length > 0">
|
||||||
<div class="flex items-end justify-between border-b border-[#eee] pb-3 mb-6">
|
|
||||||
<div class="text-[11px] font-mono uppercase tracking-[0.25em] text-[#999]">
|
|
||||||
Gallery <span class="ml-2 text-black" x-text="`· 共 ${article?.images?.length || 0} 张`"></span>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="openLb(0)"
|
|
||||||
class="text-[11px] font-mono uppercase tracking-widest border border-black px-3 py-1.5 hover:bg-black hover:text-white transition-colors cursor-pointer"
|
|
||||||
>
|
|
||||||
⤢ 全屏查看
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 图片网格 -->
|
<!-- 图片网格 -->
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import { getReports, fmtDate } from "../../lib/data"
|
import { getReports, fmtDate } from "@/lib/data"
|
||||||
|
|
||||||
// 文章展示创意布局页:复用你现有的 Layout 外壳。
|
// 文章展示创意布局页:复用你现有的 Layout 外壳。
|
||||||
// 数据由数据层 getReports() 统一从后端公开接口拉取(见 src/lib/data.ts);
|
// 数据由数据层 getReports() 统一从后端公开接口拉取(见 src/lib/data.ts);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { DEFAULT_LOCALE, type Locale } from './config';
|
import { DEFAULT_LOCALE, type Locale } from '@/i18n/config';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单文件翻译字典。
|
* 单文件翻译字典。
|
||||||
@ -18,18 +18,25 @@ type OtherLocale = Exclude<Locale, typeof DEFAULT_LOCALE>;
|
|||||||
type TranslationEntry = Partial<Record<OtherLocale, string>>;
|
type TranslationEntry = Partial<Record<OtherLocale, string>>;
|
||||||
|
|
||||||
export const dict: Record<string, TranslationEntry> = {
|
export const dict: Record<string, TranslationEntry> = {
|
||||||
Portfolio: { cn: '作品集' },
|
// ── 导航 / Navigation ──
|
||||||
'All Shows': { cn: '全部走秀' },
|
'About': { cn: '关于' },
|
||||||
|
'All Shows': { cn: '全部走秀' },
|
||||||
|
'Contact': { cn: '联系' },
|
||||||
|
'Contact Us': { cn: '联系我们' },
|
||||||
|
'Home': { cn: '首页' },
|
||||||
'Latest Projects': { cn: '最新项目' },
|
'Latest Projects': { cn: '最新项目' },
|
||||||
About: { cn: '关于' },
|
'Login': { cn: '登录' },
|
||||||
'Contact Us': { cn: '联系我们' },
|
'Portfolio': { cn: '作品集' },
|
||||||
Login: { cn: '登录' },
|
'Runway Archive': { cn: '走秀档案' },
|
||||||
Signup: { cn: '注册' },
|
'Signup': { cn: '注册' },
|
||||||
Contact: { cn: '联系' },
|
|
||||||
'Back to top': { cn: '回到顶部' },
|
// ── 控件 / Controls ──
|
||||||
|
'Back to top': { cn: '回到顶部' },
|
||||||
|
'Next': { cn: '下一组' },
|
||||||
|
'Previous': { cn: '上一组' },
|
||||||
|
|
||||||
|
// ── 页脚 / Footer ──
|
||||||
'© 2026 PORTFOLIO STUDIO. ALL RIGHTS RESERVED.': { cn: '© 2026 PORTFOLIO STUDIO. 保留所有权利。' },
|
'© 2026 PORTFOLIO STUDIO. ALL RIGHTS RESERVED.': { cn: '© 2026 PORTFOLIO STUDIO. 保留所有权利。' },
|
||||||
Previous: { cn: '上一组' },
|
|
||||||
Next: { cn: '下一组' },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 把 {name} 形式的占位符替换成参数值。 */
|
/** 把 {name} 形式的占位符替换成参数值。 */
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { getLocaleByPath } from 'astro:i18n';
|
import { getLocaleByPath } from 'astro:i18n';
|
||||||
import { DEFAULT_LOCALE, LOCALES, type Locale } from './config';
|
import { DEFAULT_LOCALE, LOCALES, type Locale } from '@/i18n/config';
|
||||||
import { translate } from './dictionary';
|
import { translate } from '@/i18n/dictionary';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 URL 解析语言,委托 Astro 内置的 astro:i18n.getLocaleByPath。
|
* 从 URL 解析语言,委托 Astro 内置的 astro:i18n.getLocaleByPath。
|
||||||
@ -29,5 +29,17 @@ export function useTranslations(locale: Locale) {
|
|||||||
return { t, locale };
|
return { t, locale };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一行取「当前语言 + 翻译函数」,干掉每个页面重复的样板:
|
||||||
|
* const { locale, t } = getI18n(Astro)
|
||||||
|
* 内部用 Astro.currentLocale(与 Layout 判断语言的方式一致),
|
||||||
|
* 取不到时回退默认语言。参数只要求含 currentLocale 字段,避免耦合 Astro 全局类型。
|
||||||
|
*/
|
||||||
|
export function getI18n(Astro: { currentLocale?: string | undefined }) {
|
||||||
|
const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE;
|
||||||
|
const { t } = useTranslations(locale);
|
||||||
|
return { locale, t };
|
||||||
|
}
|
||||||
|
|
||||||
export { LOCALES, DEFAULT_LOCALE };
|
export { LOCALES, DEFAULT_LOCALE };
|
||||||
export type { Locale };
|
export type { Locale };
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
import '../styles/global.css'
|
import '@/styles/global.css'
|
||||||
import { getRelativeLocaleUrl } from 'astro:i18n'
|
import { getRelativeLocaleUrl } from 'astro:i18n'
|
||||||
import { useTranslations, DEFAULT_LOCALE, type Locale } from '../i18n/utils'
|
import { getI18n } from '@/i18n/utils'
|
||||||
import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '../i18n/config'
|
import { LOCALES, LOCALE_NAMES, isLocaleSegment } from '@/i18n/config'
|
||||||
import LanguageDetector from '../components/LanguageDetector.astro'
|
import LanguageDetector from '@/components/LanguageDetector.astro'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
title = 'Portfolio Studio',
|
title = 'Portfolio Studio',
|
||||||
@ -12,14 +12,21 @@ const {
|
|||||||
activeThemePalette = null,
|
activeThemePalette = null,
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE
|
const { locale, t } = getI18n(Astro)
|
||||||
const { t } = useTranslations(locale)
|
|
||||||
|
// 当前路径(去掉语言前缀),供语言切换器「换前缀、留路径」用,例如 /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>
|
<!doctype html>
|
||||||
<html lang={locale === 'cn' ? 'zh-CN' : 'en'}>
|
<html lang={locale === 'cn' ? 'zh-CN' : 'en'}>
|
||||||
<head>
|
<head>
|
||||||
<!-- <LanguageDetector /> -->
|
<!-- TODO <LanguageDetector /> -->
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
@ -80,9 +87,9 @@ const { t } = useTranslations(locale)
|
|||||||
>
|
>
|
||||||
{LOCALES.map((l) => (
|
{LOCALES.map((l) => (
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href={getRelativeLocaleUrl(l)}
|
href={getRelativeLocaleUrl(l, currentPath) + queryString}
|
||||||
@click="open = false"
|
@click="open = false"
|
||||||
class:list={[
|
class:list={[
|
||||||
'block px-4 py-1.5 text-[12px] uppercase tracking-[0.5px] hover:bg-black/5 transition-colors',
|
'block px-4 py-1.5 text-[12px] uppercase tracking-[0.5px] hover:bg-black/5 transition-colors',
|
||||||
l === locale ? 'font-bold' : 'opacity-60',
|
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">
|
<footer class="relative z-[1] bg-white mt-20 pt-10 border-t-2 border-black text-black w-full font-sans">
|
||||||
<script>
|
<script>
|
||||||
import { getUser, fetchMe, clearSession } from "../lib/auth.ts"
|
import { getUser, fetchMe, clearSession } from "@/lib/auth.ts"
|
||||||
const slot = document.getElementById("auth-slot")
|
const slot = document.getElementById("auth-slot")
|
||||||
function render(user) {
|
function render(user) {
|
||||||
if (!user) return // 未登录:保留 SSR 渲染的 Login/Signup(已带语言前缀,无需重写)
|
if (!user) return // 未登录:保留 SSR 渲染的 Login/Signup(已带语言前缀,无需重写)
|
||||||
@ -193,27 +200,6 @@ const { t } = useTranslations(locale)
|
|||||||
|
|
||||||
</div>
|
</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 */}
|
{/* 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 class="flex flex-col sm:flex-row justify-between items-center text-[12px] font-mono text-zinc-500 gap-4">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Article from "../components/pages/article.astro"
|
import Article from "@/components/pages/article.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
import Layout from "../layouts/Layout.astro"
|
|
||||||
import Articles from "../components/pages/articles.astro"
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<Articles />
|
|
||||||
</Layout>
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Brands from "../components/pages/brands.astro"
|
import Brands from "@/components/pages/brands.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import About from "../../components/pages/About.astro"
|
import About from "@/components/pages/About.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="About — 暂未上线">
|
<Layout title="About — 暂未上线">
|
||||||
|
|||||||
8
src/pages/cn/article.astro
Normal file
8
src/pages/cn/article.astro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
import Layout from "@/layouts/Layout.astro"
|
||||||
|
import Article from "@/components/pages/article.astro"
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<Article />
|
||||||
|
</Layout>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from '../../layouts/Layout.astro'
|
import Layout from '@/layouts/Layout.astro'
|
||||||
import Index from '../../components/Index.astro'
|
import Index from '@/components/Index.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import { getBrands, getYears, type BrandEntry } from "../lib/api"
|
import Breadcrumb from "@/components/Breadcrumb.astro"
|
||||||
|
import { getBrands, getYears, type BrandEntry } from "@/lib/api"
|
||||||
|
|
||||||
let sidebarBrands: BrandEntry[] = []
|
let sidebarBrands: BrandEntry[] = []
|
||||||
let yearChips: number[] = []
|
let yearChips: number[] = []
|
||||||
@ -24,13 +25,14 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
<!-- 顶部:极简眉头 -->
|
<!-- 顶部:极简眉头 -->
|
||||||
<header class="showshead">
|
<header class="showshead">
|
||||||
<div>
|
<div>
|
||||||
<nav class="showscrumb" aria-label="Breadcrumb">
|
<Breadcrumb
|
||||||
<a href="/">Home</a>
|
items={[
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
{ label: 'Home', href: '/' },
|
||||||
<a href="/shows">All Shows</a>
|
{ label: 'Runway Archive', href: '/shows' },
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
]}
|
||||||
<span class="cur" aria-current="page" x-text="crumbYear"></span>
|
>
|
||||||
</nav>
|
<span slot="current" x-text="crumbYear">2026 Edition</span>
|
||||||
|
</Breadcrumb>
|
||||||
<h1 class="showsh1">All Shows</h1>
|
<h1 class="showsh1">All Shows</h1>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@ -292,18 +294,6 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
.showshead {
|
.showshead {
|
||||||
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
||||||
}
|
}
|
||||||
.showscrumb {
|
|
||||||
@apply inline-flex items-center gap-[10px] mb-[10px] text-[11px] tracking-[0.18em] uppercase text-[#999] no-underline;
|
|
||||||
}
|
|
||||||
.showscrumb a {
|
|
||||||
@apply text-black no-underline transition-colors duration-150 hover:text-[#888];
|
|
||||||
}
|
|
||||||
.showscrumb .sep {
|
|
||||||
@apply text-[#cfcfcf] select-none;
|
|
||||||
}
|
|
||||||
.showscrumb .cur {
|
|
||||||
@apply text-[#999];
|
|
||||||
}
|
|
||||||
.showsh1 {
|
.showsh1 {
|
||||||
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
||||||
}
|
}
|
||||||
@ -554,7 +544,7 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Alpine from "alpinejs"
|
import Alpine from "alpinejs"
|
||||||
import { getArticles, getBrands, toAbs, type ArticleItem, type BrandEntry } from "../lib/api"
|
import { getArticles, getBrands, toAbs, type ArticleItem, type BrandEntry } from "@/lib/api"
|
||||||
|
|
||||||
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Contact from "../components/pages/Contact.astro"
|
import Contact from "@/components/pages/Contact.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Contact — 暂未上线">
|
<Layout title="Contact — 暂未上线">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import About from "../../components/pages/About.astro"
|
import About from "@/components/pages/About.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="About — 暂未上线">
|
<Layout title="About — 暂未上线">
|
||||||
|
|||||||
8
src/pages/en/article.astro
Normal file
8
src/pages/en/article.astro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
import Layout from "@/layouts/Layout.astro"
|
||||||
|
import Article from "@/components/pages/article.astro"
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<Article />
|
||||||
|
</Layout>
|
||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from '../../layouts/Layout.astro'
|
import Layout from '@/layouts/Layout.astro'
|
||||||
import Index from '../../components/Index.astro'
|
import Index from '@/components/Index.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
5
src/pages/en/runway-looks/[id].astro
Normal file
5
src/pages/en/runway-looks/[id].astro
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
export const prerender = false;
|
||||||
|
---
|
||||||
|
|
||||||
|
123123123
|
||||||
7
src/pages/en/runway-looks/index.astro
Normal file
7
src/pages/en/runway-looks/index.astro
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Layout from '@/layouts/Layout.astro'
|
||||||
|
import RunwayLooks from '@/components/RunwayLooks.astro'
|
||||||
|
---
|
||||||
|
<Layout>
|
||||||
|
|
||||||
|
</Layout>
|
||||||
@ -1,6 +1,10 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import { getBrands, getYears, type BrandEntry } from "../../lib/api"
|
import Breadcrumb from "@/components/Breadcrumb.astro"
|
||||||
|
import { getBrands, getYears, type BrandEntry } from "@/lib/api"
|
||||||
|
import { getI18n } from '@/i18n/utils'
|
||||||
|
const { locale, t } = getI18n(Astro)
|
||||||
|
|
||||||
|
|
||||||
let sidebarBrands: BrandEntry[] = []
|
let sidebarBrands: BrandEntry[] = []
|
||||||
let yearChips: number[] = []
|
let yearChips: number[] = []
|
||||||
@ -24,13 +28,14 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
<!-- 顶部:极简眉头 -->
|
<!-- 顶部:极简眉头 -->
|
||||||
<header class="showshead">
|
<header class="showshead">
|
||||||
<div>
|
<div>
|
||||||
<nav class="showscrumb" aria-label="Breadcrumb">
|
<Breadcrumb
|
||||||
<a href="/">Home</a>
|
items={[
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
{ label: t('Home'), href: '/' },
|
||||||
<a href="/shows">All Shows</a>
|
{ label: 'Runway Archive', href: '/shows' },
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
]}
|
||||||
<span class="cur" aria-current="page" x-text="crumbYear"></span>
|
>
|
||||||
</nav>
|
<span slot="current" x-text="crumbYear">All shows</span>
|
||||||
|
</Breadcrumb>
|
||||||
<h1 class="showsh1">All Shows</h1>
|
<h1 class="showsh1">All Shows</h1>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@ -292,18 +297,6 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
.showshead {
|
.showshead {
|
||||||
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
||||||
}
|
}
|
||||||
.showscrumb {
|
|
||||||
@apply inline-flex items-center gap-[10px] mb-[10px] text-[11px] tracking-[0.18em] uppercase text-[#999] no-underline;
|
|
||||||
}
|
|
||||||
.showscrumb a {
|
|
||||||
@apply text-black no-underline transition-colors duration-150 hover:text-[#888];
|
|
||||||
}
|
|
||||||
.showscrumb .sep {
|
|
||||||
@apply text-[#cfcfcf] select-none;
|
|
||||||
}
|
|
||||||
.showscrumb .cur {
|
|
||||||
@apply text-[#999];
|
|
||||||
}
|
|
||||||
.showsh1 {
|
.showsh1 {
|
||||||
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
||||||
}
|
}
|
||||||
@ -554,7 +547,7 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Alpine from "alpinejs"
|
import Alpine from "alpinejs"
|
||||||
import { getArticles, getBrands, toAbs, type ArticleItem, type BrandEntry } from "../lib/api"
|
import { getArticles, getBrands, toAbs, type ArticleItem, type BrandEntry } from "@/lib/api"
|
||||||
|
|
||||||
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
// 应该跳转到 /en
|
// 应该跳转到 /en
|
||||||
|
|
||||||
import Layout from '../layouts/Layout.astro'
|
import Layout from '@/layouts/Layout.astro'
|
||||||
import Index from '../components/Index.astro'
|
import Index from '@/components/Index.astro'
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import LatestProjects from "../components/pages/LatestProjects.astro"
|
import LatestProjects from "@/components/pages/LatestProjects.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Latest Projects — 暂未上线">
|
<Layout title="Latest Projects — 暂未上线">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Login from "../components/pages/Login.astro"
|
import Login from "@/components/pages/Login.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Sign In — 暂未上线">
|
<Layout title="Sign In — 暂未上线">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Portfolio from "../components/pages/Portfolio.astro"
|
import Portfolio from "@/components/pages/Portfolio.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Portfolio — 暂未上线">
|
<Layout title="Portfolio — 暂未上线">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import Register from "../components/pages/Register.astro"
|
import Register from "@/components/pages/Register.astro"
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Create Account — 暂未上线">
|
<Layout title="Create Account — 暂未上线">
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Layout from "../layouts/Layout.astro"
|
import Layout from "@/layouts/Layout.astro"
|
||||||
import { getBrands, getYears, type BrandEntry } from "../lib/api"
|
import Breadcrumb from "@/components/Breadcrumb.astro"
|
||||||
|
import { getBrands, getYears, type BrandEntry } from "@/lib/api"
|
||||||
|
|
||||||
let sidebarBrands: BrandEntry[] = []
|
let sidebarBrands: BrandEntry[] = []
|
||||||
let yearChips: number[] = []
|
let yearChips: number[] = []
|
||||||
@ -33,13 +34,14 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
<!-- 顶部:极简眉头 -->
|
<!-- 顶部:极简眉头 -->
|
||||||
<header class="showshead">
|
<header class="showshead">
|
||||||
<div>
|
<div>
|
||||||
<nav class="showscrumb" aria-label="Breadcrumb">
|
<Breadcrumb
|
||||||
<a href="/">Home</a>
|
items={[
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
{ label: 'Home', href: '/' },
|
||||||
<a href="/shows">Runway Archive</a>
|
{ label: 'Runway Archive', href: '/shows' },
|
||||||
<span class="sep" aria-hidden="true">/</span>
|
]}
|
||||||
<span class="cur" aria-current="page" x-text="crumbYear"></span>
|
>
|
||||||
</nav>
|
<span slot="current" x-text="crumbYear">2026 Edition</span>
|
||||||
|
</Breadcrumb>
|
||||||
<h1 class="showsh1">All Shows</h1>
|
<h1 class="showsh1">All Shows</h1>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@ -253,18 +255,6 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
.showshead {
|
.showshead {
|
||||||
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
@apply flex justify-between items-end gap-6 py-5 pb-[26px] ;
|
||||||
}
|
}
|
||||||
.showscrumb {
|
|
||||||
@apply inline-flex items-center gap-[10px] mb-[10px] text-[11px] tracking-[0.18em] uppercase text-[#999] no-underline;
|
|
||||||
}
|
|
||||||
.showscrumb a {
|
|
||||||
@apply text-black no-underline transition-colors duration-150 hover:text-[#888];
|
|
||||||
}
|
|
||||||
.showscrumb .sep {
|
|
||||||
@apply text-[#cfcfcf] select-none;
|
|
||||||
}
|
|
||||||
.showscrumb .cur {
|
|
||||||
@apply text-[#999];
|
|
||||||
}
|
|
||||||
.showsh1 {
|
.showsh1 {
|
||||||
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
@apply text-[clamp(40px,6vw,72px)] leading-[0.9] font-black tracking-[-0.02em] my-0 mb-[10px];
|
||||||
}
|
}
|
||||||
@ -483,7 +473,7 @@ if (!yearChips.length) yearChips = yearSeed
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Alpine from "alpinejs"
|
import Alpine from "alpinejs"
|
||||||
import { getArticles, toAbs, type ArticleItem, type BrandEntry } from "../lib/api"
|
import { getArticles, toAbs, type ArticleItem, type BrandEntry } from "@/lib/api"
|
||||||
|
|
||||||
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
const ICON_DATE = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><rect x="2" y="3" width="8" height="7" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 6h8M4 2v2M8 2v2" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
"include": [".astro/types.d.ts", "**/*"],
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
"exclude": ["dist"]
|
"exclude": ["dist"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user