diff --git a/frontend/src/components/layout/PortalLayout.vue b/frontend/src/components/layout/PortalLayout.vue new file mode 100644 index 00000000..4fec3b6b --- /dev/null +++ b/frontend/src/components/layout/PortalLayout.vue @@ -0,0 +1,129 @@ + + + + + + + + + + + + PURO AI + + + {{ $t('portal.nav.products') }} + {{ $t('portal.nav.pricing') }} + {{ $t('portal.nav.docs') }} + + + + {{ $t('portal.nav.login') }} + {{ $t('portal.nav.signup') }} + + + + + + + + + + + + + diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index 63c08fca..dd8d412e 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -5630,7 +5630,7 @@ export default { }, }, - landing: { + portal: { nav: { products: 'Products', pricing: 'Pricing', @@ -5638,6 +5638,9 @@ export default { login: 'Sign in', signup: 'Free trial →', }, + }, + + landing: { hero: { badgeNew: 'NEW', eyebrow: 'Unified access to multiple AI platforms · Zero code change', @@ -5714,13 +5717,6 @@ export default { }, pricing: { - nav: { - products: 'Products', - pricing: 'Pricing', - docs: 'Docs', - login: 'Sign in', - signup: 'Free trial →', - }, hero: { kicker: '// pricing · top up · pay as you go · never expires', previewPill: '// preview · final pricing TBD at launch', @@ -5917,13 +5913,6 @@ export default { }, docs: { - nav: { - products: 'Products', - pricing: 'Pricing', - docs: 'Docs', - login: 'Sign in', - signup: 'Free trial →', - }, hero: { title: 'Quickstart — PURO AI', subtitle: 'Three steps: get a key → set base_url → send a request', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index d08a64ab..167675c4 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -5823,7 +5823,7 @@ export default { }, }, - landing: { + portal: { nav: { products: '产品', pricing: '定价', @@ -5831,6 +5831,9 @@ export default { login: '登录', signup: '免费试用 →', }, + }, + + landing: { hero: { badgeNew: 'NEW', eyebrow: '统一接入多个 AI 平台 · 零改动切换', @@ -5907,13 +5910,6 @@ export default { }, pricing: { - nav: { - products: '产品', - pricing: '定价', - docs: '文档', - login: '登录', - signup: '免费试用 →', - }, hero: { kicker: '// pricing · 充多少 · 用多少 · 永不过期', previewPill: '// preview · 最终定价以开售为准', @@ -6110,13 +6106,6 @@ export default { }, docs: { - nav: { - products: '产品', - pricing: '定价', - docs: '文档', - login: '登录', - signup: '免费试用 →', - }, hero: { title: '快速接入 PURO AI', subtitle: '三步走:拿 key → 配 base_url → 发请求', diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index eec5b81a..6688990d 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -120,32 +120,38 @@ const routes: RouteRecordRaw[] = [ title: 'Key Usage', } }, - { - path: '/docs', - name: 'Docs', - component: () => import('@/views/docs/DocsView.vue'), - meta: { - requiresAuth: false, - title: 'PURO AI · 文档' - } - }, - { - path: '/pricing', - name: 'pricing', - component: () => import('@/views/pricing/PricingView.vue'), - meta: { requiresAuth: false, title: 'Pricing · PURO AI' } - }, - // ==================== User Routes ==================== + // ==================== Portal Routes (shared PortalLayout) ==================== { path: '/', - name: 'Landing', - component: () => import('@/views/landing/LandingView.vue'), - meta: { - requiresAuth: false, - title: 'PURO AI — 你的 AI 订阅,已经付过钱了', - redirectIfAuth: '/dashboard' - } + component: () => import('@/components/layout/PortalLayout.vue'), + children: [ + { + path: '', + name: 'Landing', + component: () => import('@/views/landing/LandingView.vue'), + meta: { + requiresAuth: false, + title: 'PURO AI — 你的 AI 订阅,已经付过钱了', + redirectIfAuth: '/dashboard' + } + }, + { + path: 'docs', + name: 'Docs', + component: () => import('@/views/docs/DocsView.vue'), + meta: { + requiresAuth: false, + title: 'PURO AI · 文档' + } + }, + { + path: 'pricing', + name: 'pricing', + component: () => import('@/views/pricing/PricingView.vue'), + meta: { requiresAuth: false, title: 'Pricing · PURO AI' } + }, + ] }, { path: '/dashboard', @@ -521,11 +527,15 @@ const routes: RouteRecordRaw[] = [ const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes, - scrollBehavior(_to, _from, savedPosition) { + scrollBehavior(to, _from, savedPosition) { // Scroll to saved position when using browser back/forward if (savedPosition) { return savedPosition } + // Scroll to hash target (anchor link) — offset by sticky nav height + if (to.hash) { + return { el: to.hash, behavior: 'smooth', top: 80 } + } // Scroll to top for new routes return { top: 0 } } diff --git a/frontend/src/views/docs/DocsView.vue b/frontend/src/views/docs/DocsView.vue index 7a5e2f49..615db066 100644 --- a/frontend/src/views/docs/DocsView.vue +++ b/frontend/src/views/docs/DocsView.vue @@ -1,28 +1,5 @@ - - - - - - - - - - PURO AI - - - {{ $t('docs.nav.products') }} - {{ $t('docs.nav.pricing') }} - {{ $t('docs.nav.docs') }} - - - - {{ $t('docs.nav.login') }} - {{ $t('docs.nav.signup') }} - - - - + {{ $t('docs.hero.title') }} {{ $t('docs.hero.subtitle') }} @@ -256,7 +233,6 @@ requires_openai_auth = true
{{ $t('docs.hero.subtitle') }}