Globalization

This commit is contained in:
2025-11-30 15:24:31 +08:00
parent 83b16b1cf4
commit 16ece63ae2
9 changed files with 2162 additions and 108 deletions

4
app/components.d.ts vendored
View File

@@ -15,9 +15,7 @@ declare module 'vue' {
NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NDropdown: typeof import('naive-ui')['NDropdown']
NIcon: typeof import('naive-ui')['NIcon']
NMenu: typeof import('naive-ui')['NMenu']
NPopover: typeof import('naive-ui')['NPopover']
NTag: typeof import('naive-ui')['NTag']
RouterLink: typeof import('vue-router')['RouterLink']
@@ -30,9 +28,7 @@ declare global {
const NAvatar: typeof import('naive-ui')['NAvatar']
const NButton: typeof import('naive-ui')['NButton']
const NCard: typeof import('naive-ui')['NCard']
const NDropdown: typeof import('naive-ui')['NDropdown']
const NIcon: typeof import('naive-ui')['NIcon']
const NMenu: typeof import('naive-ui')['NMenu']
const NPopover: typeof import('naive-ui')['NPopover']
const NTag: typeof import('naive-ui')['NTag']
const RouterLink: typeof import('vue-router')['RouterLink']

View File

@@ -32,7 +32,16 @@
/>
</n-popover>
<naive-color-mode-switch />
<div class="flex gap-4">
<naive-color-mode-switch />
<n-dropdown
trigger="hover"
:options="localeDropdownOptions"
@select="handleLocaleSelect"
>
<n-button text>{{ locale.toUpperCase().split("-")[0] }}</n-button>
</n-dropdown>
</div>
</div>
</header>
@@ -46,39 +55,45 @@
<aside>
<nuxt-img src="/favicon.png" alt="Solsynth" class="w-12 h-12" />
<div>
<h3 class="text-lg font-bold">Solsynth</h3>
Making software, hardware and experiences since 2024
<h3 class="text-lg font-bold">{{ t("common.solsynth") }}</h3>
{{ t("layout.default.footer.tagline") }}
</div>
</aside>
<nav>
<h6 class="footer-title">Products</h6>
<a href="https://solian.app" target="_blank" class="link link-hover"
>Solar Network</a
>
<nuxt-link to="/products" class="link link-hover">Catalog</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.products") }}</h6>
<a href="https://solian.app" target="_blank" class="link link-hover">{{
t("layout.default.footer.solarNetwork")
}}</a>
<nuxt-link to="/products" class="link link-hover">{{
t("layout.default.footer.catalog")
}}</nuxt-link>
</nav>
<nav>
<h6 class="footer-title">Company</h6>
<nuxt-link to="/about" class="link link-hover">About us</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.company") }}</h6>
<nuxt-link to="/about" class="link link-hover">{{
t("layout.default.footer.about")
}}</nuxt-link>
<a
href="https://github.com/Solsynth"
target="_blank"
class="link link-hover"
>GitHub</a
>{{ t("layout.default.footer.github") }}</a
>
</nav>
<nav>
<h6 class="footer-title">Legal</h6>
<nuxt-link to="/terms/user-agreement" class="link link-hover"
>Terms of Service</nuxt-link
>
<nuxt-link to="/terms/privacy-policy" class="link link-hover"
>Privacy Policy</nuxt-link
>
<nuxt-link to="/terms/refund-policy" class="link link-hover"
>Refund Policy</nuxt-link
>
<nuxt-link to="/terms" class="link link-hover">All Documents</nuxt-link>
<h6 class="footer-title">{{ t("layout.default.footer.legal") }}</h6>
<nuxt-link to="/terms/user-agreement" class="link link-hover">{{
t("layout.default.footer.tos")
}}</nuxt-link>
<nuxt-link to="/terms/privacy-policy" class="link link-hover">{{
t("layout.default.footer.privacy")
}}</nuxt-link>
<nuxt-link to="/terms/refund-policy" class="link link-hover">{{
t("layout.default.footer.refund")
}}</nuxt-link>
<nuxt-link to="/terms" class="link link-hover">{{
t("layout.default.footer.allDocs")
}}</nuxt-link>
</nav>
</footer>
</div>
@@ -86,9 +101,10 @@
<script lang="ts" setup>
import type { MenuOption } from "naive-ui";
import { NIcon, NAvatar, NMenu } from "naive-ui";
import { NIcon, NAvatar, NMenu, NDropdown, NButton } from "naive-ui";
import { computed, h } from "vue";
import { useRoute, RouterLink } from "vue-router";
import { useRoute, useRouter, RouterLink } from "vue-router";
import { useI18n } from "vue-i18n";
import {
ExploreOutlined,
CategoryOutlined,
@@ -96,11 +112,26 @@ import {
} from "@vicons/material";
import { breakpointsTailwind } from "@vueuse/core";
const router = useRouter();
const switchLocalePath = useSwitchLocalePath();
const { t, locale, locales } = useI18n();
const localeDropdownOptions = computed(() => {
return locales.value?.map((l: any) => ({
label: l.name,
key: l.code,
}));
});
const handleLocaleSelect = (key: string) => {
router.push(switchLocalePath(key));
};
const route = useRoute();
const breakpoints = useBreakpoints(breakpointsTailwind);
const { data: recentProducts } = await useAsyncData("recent-products", () =>
queryCollection("products").order("updatedDate", "DESC").limit(5).all()
queryCollection("products").order("updatedDate", "DESC").limit(5).all(),
);
const activeKey = computed(() => {
@@ -148,12 +179,12 @@ const menuOptions = computed<MenuOption[]>(() => {
return [
{
label: renderLabel("Explore", "/"),
label: renderLabel(t("layout.default.menu.explore"), "/"),
key: "explore",
icon: renderIcon(ExploreOutlined),
},
{
label: renderLabel("Products", "/products"),
label: renderLabel(t("layout.default.menu.products"), "/products"),
key: "products",
icon: renderIcon(CategoryOutlined),
children: productChildren,

View File

@@ -11,11 +11,10 @@
<nuxt-img src="/favicon.png" class="w-32 h-32 mb-8 animate-float" />
<h1 class="text-6xl font-extrabold mb-6 tracking-tight">
We <span ref="typedElement" class="text-primary" />
{{ t('page.index.hero.we') }} <span ref="typedElement" class="text-primary" />
</h1>
<p class="text-2xl mb-10 opacity-80 max-w-2xl">
We are a group of friends that make software, hardware and any stuff
that is interesting.
{{ t('page.index.hero.subtitle') }}
</p>
<n-space justify="center" size="large">
<n-button
@@ -26,10 +25,10 @@
href="#products"
class="px-8 text-lg font-bold shadow-lg shadow-primary/30 hover:shadow-primary/50 transition-shadow"
>
Explore Products
{{ t('page.index.hero.explore') }}
</n-button>
<n-button size="large" round tag="a" href="/about" class="px-8 text-lg">
About Us
{{ t('page.index.hero.about') }}
</n-button>
</n-space>
@@ -45,10 +44,9 @@
<!-- Products Section -->
<div id="products" class="scroll-mt-24">
<div class="text-center mb-16">
<h2 class="text-4xl font-bold mb-4">Our Creations</h2>
<h2 class="text-4xl font-bold mb-4">{{ t('page.index.creations.title') }}</h2>
<p class="text-xl opacity-70 max-w-2xl mx-auto">
From social networks to cloud drives, we build tools that empower and
connect.
{{ t('page.index.creations.subtitle') }}
</p>
</div>
@@ -134,14 +132,12 @@
class="flex flex-col md:flex-row items-center gap-12 relative z-10 p-8"
>
<div class="flex-1">
<h2 class="text-3xl font-bold mb-4">More Than Just Code</h2>
<h2 class="text-3xl font-bold mb-4">{{ t('page.index.about.title') }}</h2>
<p class="text-lg opacity-80 mb-6 leading-relaxed">
We are a community-driven team focused on creating meaningful
experiences. Our mission goes beyond softwareit's about
connection, innovation, and fun.
{{ t('page.index.about.subtitle') }}
</p>
<n-button type="primary" ghost size="large" tag="a" href="/about">
Read Our Story
{{ t('page.index.about.readStory') }}
<template #icon>
<n-icon :component="ChevronRightOutlined"></n-icon>
</template>
@@ -180,13 +176,16 @@ import {
InfoRound,
} from "@vicons/material";
import Typed from "typed.js";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const route = useRoute();
const typedElement = ref(null);
const typed = shallowRef(null);
useHead({
title: "We are Solsynth",
title: t('page.index.title'),
titleTemplate: "%s",
});
@@ -197,11 +196,11 @@ onMounted(() => {
}
typed.value = new Typed(typedElement.value, {
strings: [
"make software",
"make hardware",
"craft experiences",
"write stories",
"are Solsynth",
t("page.index.hero.typed.makeSoftware"),
t("page.index.hero.typed.makeHardware"),
t("page.index.hero.typed.craftExperiences"),
t("page.index.hero.typed.writeStories"),
t("page.index.hero.typed.areSolsynth"),
],
typeSpeed: 50,
backDelay: 1500,

View File

@@ -27,14 +27,11 @@
</div>
<h1 class="text-6xl md:text-7xl font-extrabold mb-6 tracking-tight">
Solar Network
{{ t('page.product.solarNetwork.hero.title') }}
</h1>
<p class="text-xl md:text-2xl mb-10 max-w-2xl mx-auto leading-relaxed">
The next-generation social network designed for
<span class="text-primary font-semibold">technology enthusiasts</span
>, <span class="text-secondary font-semibold">developers</span>, and
<span class="text-info font-semibold">ACG culture</span>.
{{ t('page.product.solarNetwork.hero.subtitle', [t('page.product.solarNetwork.hero.subtitle.enthusiasts'), t('page.product.solarNetwork.hero.subtitle.developers'), t('page.product.solarNetwork.hero.subtitle.acg')]) }}
</p>
<n-space justify="center" size="large" class="mb-16">
@@ -46,7 +43,7 @@
href="#download"
class="px-8 py-6 text-lg font-bold shadow-lg shadow-primary/25 hover:shadow-primary/40 transition-all download-button"
>
Get Started
{{ t('page.product.solarNetwork.hero.getStarted') }}
<template #icon>
<n-icon :component="ArrowDownwardRound" />
</template>
@@ -59,7 +56,7 @@
href="#features"
class="px-8 py-6 text-lg hover:bg-gray-100 dark:hover:bg-white/10 transition-all"
>
Learn More
{{ t('page.product.solarNetwork.hero.learnMore') }}
</n-button>
</n-space>
</div>
@@ -77,11 +74,10 @@
<div class="container mx-auto max-w-6xl">
<div class="text-center mb-20">
<h2 class="text-4xl md:text-5xl font-bold mb-6">
Why Solar Network?
{{ t('page.product.solarNetwork.features.title') }}
</h2>
<p class="text-xl max-w-2xl mx-auto">
Built for those who create, code, and connect. Experience a platform
that understands your passions.
{{ t('page.product.solarNetwork.features.subtitle') }}
</p>
</div>
@@ -94,10 +90,11 @@
>
<n-icon size="32" :component="CodeRound" />
</div>
<h3 class="text-2xl font-bold mb-4">Developer First</h3>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.devFirst.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
Native syntax highlighting, code snippet sharing, and seamless
integration with your favorite dev tools.
{{ t('page.product.solarNetwork.features.devFirst.content') }}
</p>
</div>
</div>
@@ -110,11 +107,11 @@
>
<n-icon size="32" :component="ApiRound" />
</div>
<h3 class="text-2xl font-bold mb-4">OpenAPI</h3>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.openapi.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
Fully documented API, transparent rate limiting and risk
control. Great start for developing your own app with the
Solar Network!
{{ t('page.product.solarNetwork.features.openapi.content') }}
</p>
</div>
</div>
@@ -127,10 +124,11 @@
>
<n-icon size="32" :component="AutoAwesomeRound" />
</div>
<h3 class="text-2xl font-bold mb-4">ACG Culture</h3>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.acg.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
A dedicated space for Anime, Comic, and Game enthusiasts.
Share your art, reviews, and passion.
{{ t('page.product.solarNetwork.features.acg.content') }}
</p>
</div>
</div>
@@ -143,10 +141,11 @@
>
<n-icon size="32" :component="FavoriteRound" />
</div>
<h3 class="text-2xl font-bold mb-4">Friendly Community</h3>
<h3 class="text-2xl font-bold mb-4">
{{ t('page.product.solarNetwork.features.community.title') }}
</h3>
<p class="opacity-80 leading-relaxed">
Join a vibrant community of like-minded individuals. Share
your knowledge, ask questions, and connect with others.
{{ t('page.product.solarNetwork.features.community.content') }}
</p>
</div>
</div>
@@ -159,18 +158,18 @@
>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-0">
<div class="p-12 flex flex-col justify-center">
<h3 class="text-3xl font-bold mb-6">Experience the Future</h3>
<h3 class="text-3xl font-bold mb-6">
{{ t('page.product.solarNetwork.experience.title') }}
</h3>
<p class="text-lg mb-8">
Watch our promotional video to see Solar Network in action.
Discover a fluid, responsive, and beautiful interface designed
for modern interactions.
{{ t('page.product.solarNetwork.experience.content') }}
</p>
<div class="flex gap-4">
<n-tag type="warning" round :bordered="false">
<template #icon
><n-icon :component="ConstructionRound"
/></template>
Under Construction
{{ t('page.product.solarNetwork.experience.wip') }}
</n-tag>
</div>
</div>
@@ -207,10 +206,10 @@
<div class="container mx-auto max-w-5xl">
<div class="text-center mb-20">
<h2 class="text-2xl md:text-3xl font-bold mb-2">
Start Your Journey
{{ t('page.product.solarNetwork.download.title') }}
</h2>
<p class="text-xl">
Available on iOS, Android, macOS, Windows, and Linux.
{{ t('page.product.solarNetwork.download.subtitle') }}
</p>
</div>
@@ -227,7 +226,7 @@
class="shadow-lg shadow-success/20"
>
<template #icon><n-icon :component="StarRound" /></template>
Recommended
{{ t('page.product.solarNetwork.download.faster.recommended') }}
</n-tag>
</div>
@@ -237,9 +236,11 @@
>
<n-icon size="36" color="white" :component="IosShareRound" />
</div>
<h3 class="text-2xl font-bold mb-2">Faster Release</h3>
<h3 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.download.faster.title') }}
</h3>
<p class="opacity-80 mb-8 grow">
Get early access to the latest features on all platforms.
{{ t('page.product.solarNetwork.download.faster.content') }}
<br />
<span class="text-xs opacity-70 mt-2 block">
<n-space size="small" align="center">
@@ -261,7 +262,7 @@
target="_blank"
class="py-6 font-bold"
>
Join TestFlight (iOS, macOS)
{{ t('page.product.solarNetwork.download.faster.testflight') }}
<template #icon><n-icon :component="LaunchRound" /></template>
</n-button>
<n-button
@@ -274,7 +275,7 @@
target="_blank"
class="py-6 font-bold"
>
Direct Download
{{ t('page.product.solarNetwork.download.faster.direct') }}
<template #icon
><n-icon :component="CloudDownloadRound"
/></template>
@@ -289,7 +290,7 @@
target="_blank"
class="py-2 font-bold text-primary hover:underline"
>
Open in your Browser
{{ t('page.product.solarNetwork.download.faster.browser') }}
<template #icon><n-icon :component="WebRound" /></template>
</n-button>
</div>
@@ -309,9 +310,11 @@
>
<n-icon size="36" color="white" :component="LogoApple" />
</div>
<h3 class="text-2xl font-bold mb-2">App Store</h3>
<h3 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.download.appstore.title') }}
</h3>
<p class="opacity-80 mb-8 grow">
Stable release for general users. Leave a review to support us!
{{ t('page.product.solarNetwork.download.appstore.content') }}
</p>
<n-button
secondary
@@ -323,7 +326,7 @@
target="_blank"
class="py-6 font-bold"
>
Visit Store Page
{{ t('page.product.solarNetwork.download.appstore.visit') }}
<template #icon><n-icon :component="LaunchRound" /></template>
</n-button>
</div>
@@ -345,7 +348,7 @@
<div
class="text-xs opacity-80 uppercase tracking-wider font-bold mb-1"
>
Latest Release
{{ t('page.product.solarNetwork.download.latest.title') }}
</div>
<div class="font-mono text-primary font-bold">
{{ latestRelease.data.value?.tag_name }}
@@ -358,7 +361,7 @@
:href="latestRelease.data.value?.html_url"
target="_blank"
>
View on GitHub
{{ t('page.product.solarNetwork.download.latest.view') }}
<template #icon
><n-icon :component="ArrowForwardRound"
/></template>
@@ -371,10 +374,11 @@
<!-- Footer / Support -->
<div class="py-24 bg-primary/5">
<div class="container mx-auto px-4 text-center">
<h2 class="text-2xl font-bold mb-2">Need Help?</h2>
<h2 class="text-2xl font-bold mb-2">
{{ t('page.product.solarNetwork.support.title') }}
</h2>
<p class="mb-12 text-lg">
Feel free to contact your customer service or report a bug on the
GitHub.
{{ t('page.product.solarNetwork.support.content') }}
</p>
<div class="flex flex-wrap justify-center gap-8">
<a
@@ -383,14 +387,14 @@
class="flex items-center gap-3 px-6 py-4 rounded-xl bg-white dark:bg-white/5 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors border border-gray-200 dark:border-white/5 text-gray-900 dark:text-white shadow-sm"
>
<n-icon :component="LogoGithub" size="24" />
<span class="font-semibold">Report an Issue</span>
<span class="font-semibold">{{ t('page.product.solarNetwork.support.report') }}</span>
</a>
<a
href="mailto:lily@solsynth.dev"
class="flex items-center gap-3 px-6 py-4 rounded-xl bg-white dark:bg-white/5 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors border border-gray-200 dark:border-white/5 text-gray-900 dark:text-white shadow-sm"
>
<n-icon :component="MailOutlineRound" size="24" />
<span class="font-semibold">Contact Support</span>
<span class="font-semibold">{{ t('page.product.solarNetwork.support.contact') }}</span>
</a>
</div>
</div>
@@ -423,14 +427,16 @@ import {
LogoWindows,
LogoTux,
} from "@vicons/ionicons5";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
useHead({
title: "Solar Network - Stay Connected",
title: t('page.product.solarNetwork.title'),
meta: [
{
name: "description",
content:
"The amazing social network for technology, programming, and ACG fans.",
content: t('page.product.solarNetwork.description'),
},
],
});