feat(app): restructure to multi-page layout and add content pages
Converts the website from a single-page design with anchor links to a full multi-page application. This change improves site organization, navigation, and scalability. - Adds new top-level pages: `/news`, `/events`, and `/about`. - Introduces a new section for the 40th Anniversary at `/40th-anniversary`, including a proposal sub-page. - Updates the default layout with a new navigation menu, a promotional banner, social links, and page transitions.
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 关于我们 -->
|
||||
<section id="about" class="max-w-6xl mx-auto py-16 px-4">
|
||||
<h3 class="text-2xl font-bold text-gray-900 mb-4">关于校友会</h3>
|
||||
<p class="text-gray-700 leading-relaxed">
|
||||
永平中学校友会成立的宗旨是连接全球校友,传承母校精神,支持在校学生成长。我们定期举办活动,推动交流与合作,并积极回馈母校。
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,12 +1,18 @@
|
||||
<template>
|
||||
<UPage>
|
||||
<UBanner
|
||||
title="永中校友会 40 周年庆典活动火热筹募中!"
|
||||
icon="hugeicons:party"
|
||||
close
|
||||
:actions="bannerActions"
|
||||
/>
|
||||
<UHeader>
|
||||
<template #left>
|
||||
<NuxtLink to="/">
|
||||
<div class="flex gap-4 items-center">
|
||||
<img class="inline h-12 w-auto" src="/Logo.svg" alt="YPHS Alumni" />
|
||||
<h1
|
||||
class="inline text-xl font-bold text-gray-900 hover:text-primary"
|
||||
class="text-xl font-bold text-gray-900 hover:text-primary hidden md:inline"
|
||||
>
|
||||
永平中学校友会
|
||||
</h1>
|
||||
@@ -14,17 +20,25 @@
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
<UNavigationMenu :items="items" content-orientation="vertical" />
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
<nav class="space-x-6 hidden md:flex items-center">
|
||||
<UNavigationMenu :items="items" />
|
||||
<a
|
||||
href="/join-us"
|
||||
class="inline-flex items-center gap-2 bg-primary text-white px-4 py-2 rounded-xl shadow hover:opacity-90"
|
||||
>
|
||||
加入
|
||||
<Icon name="mdi:account-plus" class="w-5 h-5" />
|
||||
</a>
|
||||
</nav>
|
||||
<UColorModeButton />
|
||||
<UButton
|
||||
v-for="link in socialLinks"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
v-bind="link"
|
||||
/>
|
||||
<UButton
|
||||
icon="line-md:account-add"
|
||||
to="/join-us"
|
||||
color="primary"
|
||||
variant="solid"
|
||||
label="加入"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
@@ -37,7 +51,9 @@
|
||||
</UHeader>
|
||||
|
||||
<UMain>
|
||||
<slot />
|
||||
<Transition name="page" mode="out-in">
|
||||
<NuxtPage />
|
||||
</Transition>
|
||||
</UMain>
|
||||
|
||||
<UFooter>
|
||||
@@ -61,29 +77,104 @@
|
||||
</template>
|
||||
|
||||
<template #right>
|
||||
<a href="#">
|
||||
<Icon name="mdi-facebook" />
|
||||
</a>
|
||||
<a href="#">
|
||||
<Icon name="mdi-instagram" />
|
||||
</a>
|
||||
<a href="#">
|
||||
<Icon name="mdi-gmail" />
|
||||
</a>
|
||||
<UButton
|
||||
v-for="link in socialLinks"
|
||||
color="neutral"
|
||||
variant="ghost"
|
||||
v-bind="link"
|
||||
/>
|
||||
</template>
|
||||
</UFooter>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { NavigationMenuItem } from "@nuxt/ui";
|
||||
import type { NavigationMenuItem, ButtonProps } from "@nuxt/ui";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const bannerActions = ref<ButtonProps[]>([
|
||||
{
|
||||
label: "查看策划书",
|
||||
variant: "outline",
|
||||
icon: "lucide:arrow-right",
|
||||
to: "/40th-anniversary/proposal",
|
||||
},
|
||||
]);
|
||||
|
||||
const items = computed<NavigationMenuItem[]>(() => [
|
||||
{ label: "新闻", to: "#news", active: route.path.startsWith("#news") },
|
||||
{ label: "活动", to: "#events", active: route.path.startsWith("#events") },
|
||||
{ label: "捐赠", to: "#donate", active: route.path.startsWith("#donate") },
|
||||
{ label: "关于", to: "#about", active: route.path.startsWith("#about") },
|
||||
{ label: "首页", to: "/" },
|
||||
{ label: "新闻", to: "/news", active: route.path.startsWith("/news") },
|
||||
{
|
||||
label: "活动",
|
||||
to: "/events",
|
||||
active: route.path.startsWith("/events"),
|
||||
children: [
|
||||
{
|
||||
label: "40 周年庆",
|
||||
to: "/40th-anniversary",
|
||||
active: route.path.startsWith("/40th-anniversary"),
|
||||
badge: {
|
||||
label: "Hot",
|
||||
color: "error",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "关于校友会",
|
||||
to: "/about",
|
||||
active: route.path.startsWith("/about"),
|
||||
},
|
||||
{
|
||||
label: "友情链接",
|
||||
children: [
|
||||
{
|
||||
label: "永平中学官网",
|
||||
icon: "mdi:book-education",
|
||||
to: "https://yphs.edu.my/",
|
||||
target: "_blank",
|
||||
},
|
||||
{
|
||||
label: "桃李教育网",
|
||||
icon: "mdi:web",
|
||||
to: "https://efuxi.vtour.my/",
|
||||
target: "_blank",
|
||||
},
|
||||
{
|
||||
label: "董总 Dong Zong",
|
||||
icon: "mdi:web",
|
||||
to: "https://www.dongzong.my/",
|
||||
target: "_blank",
|
||||
},
|
||||
],
|
||||
},
|
||||
// { label: "捐赠", to: "#donate", active: route.path.startsWith("#donate") },
|
||||
// { label: "关于", to: "#about", active: route.path.startsWith("#about") },
|
||||
]);
|
||||
|
||||
const socialLinks = ref<ButtonProps[]>([
|
||||
{
|
||||
icon: "line-md:tiktok",
|
||||
to: "https://www.tiktok.com/@yphs.alumni",
|
||||
target: "_blank",
|
||||
},
|
||||
{
|
||||
icon: "line-md:facebook",
|
||||
to: "https://www.facebook.com/YPHS.Alumni/",
|
||||
target: "_blank",
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.page-enter-active,
|
||||
.page-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.page-enter-from,
|
||||
.page-leave-to {
|
||||
opacity: 0;
|
||||
filter: blur(1rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
19
app/pages/40th-anniversary.vue
Normal file
19
app/pages/40th-anniversary.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<UContainer>
|
||||
<UDashboardToolbar>
|
||||
<UNavigationMenu :items="subPages" />
|
||||
</UDashboardToolbar>
|
||||
<NuxtPage />
|
||||
</UContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { NavigationMenuItem } from "@nuxt/ui";
|
||||
|
||||
const subPages = ref<NavigationMenuItem[]>([
|
||||
{ label: "庆祝四十载", to: "/40th-anniversary", exact: true },
|
||||
{ label: "策划案", to: "/40th-anniversary/proposal" },
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
13
app/pages/40th-anniversary/index.vue
Normal file
13
app/pages/40th-anniversary/index.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
40 周年庆纪念页
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
58
app/pages/40th-anniversary/proposal.vue
Normal file
58
app/pages/40th-anniversary/proposal.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<UPage>
|
||||
<UPageBody>
|
||||
<UContainer>
|
||||
<UPage>
|
||||
<template #default>
|
||||
<UStepper :items="proposalSteps" size="xs" disabled/>
|
||||
<UPageHeader
|
||||
title="永平中学校友会 40 周年纪念册筹划"
|
||||
description="四十载薪火相传,情系永平,共创未来"
|
||||
/>
|
||||
|
||||
<UPageSection title="纪念册定位">
|
||||
<h3>目标受众</h3>
|
||||
<ul>
|
||||
<li>各届校友(老中青三代)</li>
|
||||
<li>教职员工与校董会</li>
|
||||
<li>在校学生与家长</li>
|
||||
<li>地区社会贤达 / 赞助商 / 友校代表</li>
|
||||
</ul>
|
||||
<h3>风格方向</h3>
|
||||
<p>庄重 × 情感 × 历史厚度 × 现代视觉感</p>
|
||||
<p>
|
||||
→ 类似大学纪念刊风格,不是单纯的活动册,而是一部
|
||||
*时代见证作品*。
|
||||
</p>
|
||||
</UPageSection>
|
||||
|
||||
<UPageSection
|
||||
title="总体结构规划"
|
||||
description="建议页数:120~160 页"
|
||||
>
|
||||
</UPageSection>
|
||||
</template>
|
||||
</UPage>
|
||||
</UContainer>
|
||||
</UPageBody>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { StepperItem } from "@nuxt/ui";
|
||||
|
||||
useSeoMeta({
|
||||
title: "40 周年纪念册筹划",
|
||||
});
|
||||
|
||||
const proposalSteps = ref<StepperItem[]>([
|
||||
{ title: "筹划期", description: "成立编辑组,确定风格、预算、印刷规格" },
|
||||
{ title: "资料收集期", description: "访谈、征文、收照片、整理档案" },
|
||||
{ title: "撰写与设计期", description: "文稿成稿、图片修复、初稿排版" },
|
||||
{ title: "审校与赞助期", description: "校对、内容确认、广告页洽谈" },
|
||||
{ title: "印刷准备期", description: "定稿送印、样书确认" },
|
||||
{ title: "发布期", description: "校庆活动同步发行、媒体推广、线上版本上线" },
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
61
app/pages/about.vue
Normal file
61
app/pages/about.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<UPage>
|
||||
<UPageBody>
|
||||
<UContainer>
|
||||
<UPageHeader
|
||||
title="关于校友会"
|
||||
description="永平中学校友会成立的宗旨是连接全球校友,传承母校精神,支持在校学生成长。我们定期举办活动,推动交流与合作,并积极回馈母校。"
|
||||
/>
|
||||
|
||||
<UPageSection
|
||||
title="会徽"
|
||||
description="你了解校友会会徽的含义吗"
|
||||
:features="logoFeatures"
|
||||
orientation="horizontal"
|
||||
>
|
||||
<img class="size-88" src="/Logo.svg" alt="YPHS Alumni" />
|
||||
</UPageSection>
|
||||
|
||||
<UPageSection
|
||||
title="永平中学校歌"
|
||||
description="这首伴随着我们整个中学生涯的曲子,想必能勾起您不少的青春回忆吧!"
|
||||
orientation="horizontal"
|
||||
reverse
|
||||
>
|
||||
<div class="flex flex-col gap-y-8">
|
||||
<img class="w-full" src="/about/校歌.webp" alt="YPHS Alumni" />
|
||||
<div class="flex items-center gap-x-8">
|
||||
<p>伴奏版</p>
|
||||
<audio
|
||||
controls
|
||||
class="flex-1"
|
||||
src="/about/永平中学校歌.mp3"
|
||||
></audio>
|
||||
</div>
|
||||
<div class="flex items-center gap-x-8">
|
||||
<p>咏唱版</p>
|
||||
<audio
|
||||
controls
|
||||
class="flex-1"
|
||||
src="/about/YongPing_SchoolSong_V2.mp3"
|
||||
></audio>
|
||||
</div>
|
||||
</div>
|
||||
</UPageSection>
|
||||
</UContainer>
|
||||
</UPageBody>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { PageFeatureProps } from "@nuxt/ui";
|
||||
|
||||
const logoFeatures = ref<PageFeatureProps[]>([
|
||||
{ title: "九轮", description: "永久随时代齿轮前进" },
|
||||
{ title: "太阳九条线", description: "久久发出光芒照耀华友" },
|
||||
{ title: "三个菱形", description: "代表校友、董事会及社会人士团结一致" },
|
||||
{ title: "两道绿叶", description: "代表组织团结、不断茁壮成长" },
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
30
app/pages/events/index.vue
Normal file
30
app/pages/events/index.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<UPage>
|
||||
<UPageBody>
|
||||
<UContainer>
|
||||
<UChangelogVersions :versions="newsPost" />
|
||||
</UContainer>
|
||||
</UPageBody>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ChangelogVersionProps } from "@nuxt/ui";
|
||||
|
||||
const { data: events } = await useAsyncData("events", () =>
|
||||
queryCollection("events").order("date", "DESC").limit(3).all()
|
||||
);
|
||||
|
||||
// 将 news 数据转换成 UBlogPosts 可用格式
|
||||
const newsPost = computed<ChangelogVersionProps[]>(() =>
|
||||
(events.value || []).map((evt: any) => ({
|
||||
title: evt.title,
|
||||
description: evt.description,
|
||||
image: evt.cover,
|
||||
date: evt.date,
|
||||
to: evt.path, // ✅ 建议加路由跳转
|
||||
}))
|
||||
);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<UPage>
|
||||
<!-- Hero Banner -->
|
||||
<UPageHero
|
||||
class="bg-cover bg-center"
|
||||
@@ -28,9 +28,7 @@
|
||||
description="您的捐赠将用于奖学金、校园建设及校友活动发展。感谢您对母校的支持!"
|
||||
:links="donationLinks"
|
||||
/>
|
||||
|
||||
<IndexAbout />
|
||||
</div>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
30
app/pages/news/index.vue
Normal file
30
app/pages/news/index.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<UPage>
|
||||
<UPageBody>
|
||||
<UContainer>
|
||||
<UChangelogVersions :versions="newsPost" />
|
||||
</UContainer>
|
||||
</UPageBody>
|
||||
</UPage>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ChangelogVersionProps } from "@nuxt/ui";
|
||||
|
||||
const { data: news } = await useAsyncData("news", () =>
|
||||
queryCollection("news").order("date", "DESC").all()
|
||||
);
|
||||
|
||||
// 将 news 数据转换成 UBlogPosts 可用格式
|
||||
const newsPost = computed<ChangelogVersionProps[]>(() =>
|
||||
(news.value || []).map((n: any) => ({
|
||||
title: n.title,
|
||||
description: n.description,
|
||||
image: n.cover,
|
||||
date: n.date,
|
||||
to: n.path, // ✅ 建议加路由跳转
|
||||
}))
|
||||
);
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
Reference in New Issue
Block a user