Files
tootaio.com/app/pages/index.vue
xiaomai 5c8baf14c3 feat(ui): rebuild homepage with new sections and i18n
This commit introduces a complete overhaul of the homepage, rebuilding it from the ground up with Nuxt UI and full
internationalization support. The new design better showcases the studio's capabilities and projects.

- Re-architected the index page with multiple new sections: Capabilities, Featured Projects, Tech Stack, and Why Choose Us.
- Implemented full i18n for English (en-US) and Chinese (zh-CN) across all new content.
- Centralized the page structure into a `default.vue` layout with a global header (including color mode and locale selectors) and
footer.
- Replaced placeholder logos with a dynamic `UMarquee` of technology icons using Iconify.
2025-11-04 17:53:14 +08:00

238 lines
7.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<!-- 全幅 Hero - Page 布局之外 -->
<UPageHero
title="Tootaio Studio"
:description="$t('index.heroDescription')"
/>
<UPageSection
:title="$t('index.capabilities.title')"
:features="capabilitiesFeatures"
/>
<UPageSection :title="$t('index.featuredProjects.title')">
<UCarousel
v-slot="{ item }"
:items="featuredProjects"
:ui="{ item: 'basis-full sm:basis-1/2 lg:basis-1/3' }"
>
<UCard class="my-2">
<template #header>
<h3 class="text-2xl font-bold">{{ item.title }}</h3>
</template>
<template #default>
<img :src="item.image" :alt="item.title" />
<p class="mt-2 line-clamp-3">{{ item.description }}</p>
</template>
<template #footer>
<UButton
v-if="item.demoLink"
:href="item.demoLink"
target="_blank"
rel="noopener"
size="sm"
>
{{ $t("index.featuredProjects.viewDemo") }}
</UButton>
</template>
</UCard>
</UCarousel>
</UPageSection>
<UPageSection :title="$t('index.techStack.title')">
<UMarquee>
<UIcon
v-for="icon in techIcons"
:key="icon"
:name="icon"
class="size-16"
/>
</UMarquee>
<UMarquee reverse>
<UIcon
v-for="icon in toolsIcons"
:key="icon"
:name="icon"
class="size-16"
/>
</UMarquee>
</UPageSection>
<UPageSection
:title="$t('index.whyChooseUs.title')"
:features="whyChooseUsFeatures"
/>
</div>
</template>
<script lang="ts" setup>
import type { PageFeatureProps } from "@nuxt/ui";
useSeoMeta({
title: $t("index.seo.title"),
});
const colorMode = useColorMode();
const capabilitiesFeatures = computed<PageFeatureProps[]>(() => [
{
title: $t("index.capabilities.features[0].title"),
description: $t("index.capabilities.features[0].description"),
icon: "mdi:web",
},
{
title: $t("index.capabilities.features[1].title"),
description: $t("index.capabilities.features[1].description"),
icon: "mdi:cog-outline",
},
{
title: $t("index.capabilities.features[2].title"),
description: $t("index.capabilities.features[2].description"),
icon: "mdi:gamepad-variant-outline",
},
{
title: $t("index.capabilities.features[3].title"),
description: $t("index.capabilities.features[3].description"),
icon: "mdi:monitor-dashboard",
},
{
title: $t("index.capabilities.features[4].title"),
description: $t("index.capabilities.features[4].description"),
icon: "mdi:flask-outline",
},
{
title: $t("index.capabilities.features[5].title"),
description: $t("index.capabilities.features[5].description"),
icon: "mdi:lightbulb-outline",
},
]);
const featuredProjects = ref([
{
title: "永中校友会官方网站",
description:
"永平中学校友会官方网站的设计与开发项目,整体价值 RM28,000由本工作室创办人无偿捐赠予校友会永久使用。",
image: "/images/project-showcases/yphs-alumni-website.png",
demoLink: "https://yphsalumni.org",
},
{
title: "留华生来华资料汇总",
description:
"2022 年疫情期间,为马来西亚留学生开发的返校攻略网站。帮助 5000+ 名留学生顺利返校。并获得马来西亚外交部推荐。",
image: "/images/project-showcases/malaysia-student-return.png",
demoLink: "https://tootaio.github.io",
},
{
title: "光追",
description: "基于 Godot 引擎的 2023 年吉比特高校挑战赛参赛作品。",
image: "https://img.tootaio.com/i/2025/09/26/j2swgq.png",
// demoLink: "https://tootaio.com/projects/ray-tracing",
},
]);
const techIcons = computed(() => [
"skill-icons:html",
"skill-icons:css",
"skill-icons:javascript",
"skill-icons:typescript",
"skill-icons:docker",
colorMode.value === "dark"
? "skill-icons:vuejs-dark"
: "skill-icons:vuejs-light",
colorMode.value === "dark"
? "skill-icons:nuxtjs-dark"
: "skill-icons:nuxtjs-light",
colorMode.value === "dark"
? "skill-icons:tailwindcss-dark"
: "skill-icons:tailwindcss-light",
colorMode.value === "dark"
? "skill-icons:nodejs-dark"
: "skill-icons:nodejs-light",
"skill-icons:cs",
colorMode.value === "dark"
? "skill-icons:python-dark"
: "skill-icons:python-light",
]);
const toolsIcons = ref([
"skill-icons:photoshop",
"skill-icons:illustrator",
"skill-icons:git",
colorMode.value === "dark"
? "skill-icons:vscode-dark"
: "skill-icons:vscode-light",
colorMode.value === "dark"
? "skill-icons:visualstudio-dark"
: "skill-icons:visualstudio-light",
colorMode.value === "dark"
? "skill-icons:github-dark"
: "skill-icons:github-light",
colorMode.value === "dark"
? "skill-icons:godot-dark"
: "skill-icons:godot-light",
colorMode.value === "dark"
? "skill-icons:unity-dark"
: "skill-icons:unity-light",
colorMode.value === "dark"
? "skill-icons:blender-dark"
: "skill-icons:blender-light",
colorMode.value === "dark"
? "skill-icons:androidstudio-dark"
: "skill-icons:androidstudio-light",
colorMode.value === "dark"
? "skill-icons:windows-dark"
: "skill-icons:windows-light",
colorMode.value === "dark"
? "skill-icons:linux-dark"
: "skill-icons:linux-light",
colorMode.value === "dark"
? "skill-icons:apple-dark"
: "skill-icons:apple-light",
colorMode.value === "dark"
? "skill-icons:idea-dark"
: "skill-icons:idea-light",
colorMode.value === "dark"
? "skill-icons:pycharm-dark"
: "skill-icons:pycharm-light",
colorMode.value === "dark"
? "skill-icons:rider-dark"
: "skill-icons:rider-light",
]);
const whyChooseUsFeatures = computed<PageFeatureProps[]>(() => [
{
title: $t("index.whyChooseUs.features[0].title"),
description: $t("index.whyChooseUs.features[0].description"),
icon: "mdi:brush-variant", // Fully Custom-Built
},
{
title: $t("index.whyChooseUs.features[1].title"),
description: $t("index.whyChooseUs.features[1].description"),
icon: "mdi:cog-sync-outline", // Tech-Driven
},
{
title: $t("index.whyChooseUs.features[2].title"),
description: $t("index.whyChooseUs.features[2].description"),
icon: "mdi:gamepad-variant-outline", // Cross-Domain
},
{
title: $t("index.whyChooseUs.features[3].title"),
description: $t("index.whyChooseUs.features[3].description"),
icon: "mdi:rocket-launch-outline", // End-to-End Service
},
{
title: $t("index.whyChooseUs.features[4].title"),
description: $t("index.whyChooseUs.features[4].description"),
icon: "mdi:chart-timeline-variant", // Proven Project Value
},
{
title: $t("index.whyChooseUs.features[5].title"),
description: $t("index.whyChooseUs.features[5].description"),
icon: "mdi:lightbulb-on-outline", // Future-Oriented
},
]);
</script>
<style></style>