Remake the home page.

This commit is contained in:
吳元皓 2025-05-13 14:14:50 +08:00
parent 5a585ddf7c
commit 34a0868b26
6 changed files with 72 additions and 7 deletions

View File

@ -6,13 +6,16 @@ import Button from "~/components/ui/button/Button.vue";
const pending = ref(); const pending = ref();
try { try {
const { data, pending: isPending } = await useFetch("/api/rss/google"); const { data, pending } = await useFetch("/api/rss/google");
ffeed.value = data.value; ffeed.value = data.value;
} catch (error) { } catch (error) {
console.error("Error:", error); console.error("Error:", error);
} }
</script> </script>
<template> <template>
<div v-if="!ffeed">
Loading...
</div>
<div <div
v-for="item in ffeed" v-for="item in ffeed"
class="justify-center align-center text-center p-4 border border-black rounded-lg m-4" class="justify-center align-center text-center p-4 border border-black rounded-lg m-4"

View File

@ -17,6 +17,7 @@
}, },
"startusing": "Let's Start!", "startusing": "Let's Start!",
"learnmore": "Learn more", "learnmore": "Learn more",
"documentation": "Documentation",
"qanda": { "qanda": {
"titles": { "titles": {
"whydes": "Why make this platform?", "whydes": "Why make this platform?",
@ -30,6 +31,18 @@
"supportedLocationNews": "We currently only support news from Taiwan for now, but if you want more, you can contribute to the project by adding more news sources to the python scraping scripts.", "supportedLocationNews": "We currently only support news from Taiwan for now, but if you want more, you can contribute to the project by adding more news sources to the python scraping scripts.",
"userData": "We handle your account and password in a secure way, with two encryption methods, one during transit to the server (and also SQL injecton), one saving to the database. For other user data, it is currently NOT end-to-end encrypted, like your AI chat history, your stars, and your name & email. In the near future, we will add E2E encryption (and I can also pratice).", "userData": "We handle your account and password in a secure way, with two encryption methods, one during transit to the server (and also SQL injecton), one saving to the database. For other user data, it is currently NOT end-to-end encrypted, like your AI chat history, your stars, and your name & email. In the near future, we will add E2E encryption (and I can also pratice).",
"mobileApp": "I will make a application using React Native in the future, but for now, mobile is not supported, but you can still kinda use it, it is just not pleasant." "mobileApp": "I will make a application using React Native in the future, but for now, mobile is not supported, but you can still kinda use it, it is just not pleasant."
},
"cards": {
"title": {
"find": "Find",
"interface": "Interface",
"documentation": "Documentation"
},
"description": {
"find": "You can easily find the same topic from different news sources.",
"interface": "Use a desktop like interface, the one that you already got used to.",
"documentation": "We provide a documentation for you to learn how to use the app."
}
} }
}, },
"dailybriefing": "Daily Briefing", "dailybriefing": "Daily Briefing",

View File

@ -17,6 +17,7 @@
}, },
"startusing": "開始使用!", "startusing": "開始使用!",
"learnmore": "了解更多", "learnmore": "了解更多",
"documentation": "如何使用",
"qanda": { "qanda": {
"titles": { "titles": {
"whydes": "為什麼要做這個平台?", "whydes": "為什麼要做這個平台?",
@ -30,6 +31,18 @@
"supportedLocationNews": "We currently only support news from Taiwan for now, but if you want more, you can contribute to the project by adding more news sources to the python scraping scripts.", "supportedLocationNews": "We currently only support news from Taiwan for now, but if you want more, you can contribute to the project by adding more news sources to the python scraping scripts.",
"userData": "We handle your account and password in a secure way, with two encryption methods, one during transit to the server (and also SQL injecton), one saving to the database. For other user data, it is currently NOT end-to-end encrypted, like your AI chat history, your stars, and your name & email. In the near future, we will add E2E encryption (and I can also pratice).", "userData": "We handle your account and password in a secure way, with two encryption methods, one during transit to the server (and also SQL injecton), one saving to the database. For other user data, it is currently NOT end-to-end encrypted, like your AI chat history, your stars, and your name & email. In the near future, we will add E2E encryption (and I can also pratice).",
"mobileApp": "I will make a application using React Native in the future, but for now, mobile is not supported, but you can still kinda use it, it is just not pleasant." "mobileApp": "I will make a application using React Native in the future, but for now, mobile is not supported, but you can still kinda use it, it is just not pleasant."
},
"cards": {
"title": {
"find": "尋找",
"interface": "使用者介面",
"documentation": "教學"
},
"description": {
"find": "你可以輕鬆地從不同的新聞來源找到相同的主題。",
"interface": "這個網站使用類似 Xfce / MacOS / DSM 的介面,讓你可以簡單使用這個網站。",
"documentation": "我做了一組教學,讓你可以學會如何使用這個網站 UI。"
}
} }
}, },
"dailybriefing": "今日報導", "dailybriefing": "今日報導",

View File

@ -281,10 +281,10 @@ onMounted(() => {
}); });
watchEffect((cleanupFn) => { watchEffect((cleanupFn) => {
const tier = setTimeout(() => (progress.value = 10), 200); const tier = setTimeout(() => (progress.value = 10), Math.random() * 50);
const timer = setTimeout(() => (progress.value = 30), 500); const timer = setTimeout(() => (progress.value = 30), Math.random() * 100);
const timmer = setTimeout(() => (progress.value = 70), 1000); const timmer = setTimeout(() => (progress.value = 70), Math.random() * 150);
const timmmer = setTimeout(() => (progress.value = 100), 1600); const timmmer = setTimeout(() => (progress.value = 100), 1800);
cleanupFn(() => clearTimeout(tier)); cleanupFn(() => clearTimeout(tier));
cleanupFn(() => clearTimeout(timer)); cleanupFn(() => clearTimeout(timer));
cleanupFn(() => clearTimeout(timmer)); cleanupFn(() => clearTimeout(timmer));

4
pages/docs/[slug].vue Normal file
View File

@ -0,0 +1,4 @@
<template>
<div class="h-[200px]"></div>
<h1 class="text-4xl text-center align-middle">Documentation is currently not available.</h1>
</template>

View File

@ -5,6 +5,7 @@ import {
AccordionItem, AccordionItem,
AccordionTrigger, AccordionTrigger,
} from "~/components/ui/accordion"; } from "~/components/ui/accordion";
import { ComputerDesktopIcon, CircleStackIcon, MagnifyingGlassIcon, ViewfinderCircleIcon, DocumentDuplicateIcon } from "@heroicons/vue/24/outline";
import { gsap } from "gsap"; import { gsap } from "gsap";
import { TextPlugin } from "gsap/TextPlugin"; import { TextPlugin } from "gsap/TextPlugin";
gsap.registerPlugin(TextPlugin); gsap.registerPlugin(TextPlugin);
@ -21,6 +22,23 @@ const messages = [
"BlindSpec", "BlindSpec",
]; ];
const cards = [
{
icon: ViewfinderCircleIcon,
title: t("home.cards.title.find"),
description: t("home.cards.description.find"),
},
{
icon: ComputerDesktopIcon,
title: t("home.cards.title.interface"),
description: t("home.cards.description.interface"),
},
{
icon: DocumentDuplicateIcon,
title: t("home.cards.title.documentation"),
description: t("home.cards.description.documentation"),
},
]
const accordionItems = [ const accordionItems = [
{ {
@ -96,6 +114,13 @@ onMounted(() => {
<span>{{ t("home.startusing") }}</span> <span>{{ t("home.startusing") }}</span>
</button> </button>
</NuxtLink> </NuxtLink>
<NuxtLink :to="localePath('/docs/gettingstarted')">
<button
class="m-4 ml-1 mr-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gray-700 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
>
<span>{{ t("home.documentation") }}</span>
</button>
</NuxtLink>
<NuxtLink to="#learnmore"> <NuxtLink to="#learnmore">
<button <button
class="m-4 ml-1 mr-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gray-700 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg" class="m-4 ml-1 mr-1 bg-[#8C9393] text-white p-3 rounded-[10px] bg-gray-700 transition-all duration-150 hover:transform hover:scale-105 hover:shadow-lg"
@ -107,13 +132,19 @@ onMounted(() => {
</div> </div>
<div class="h-screen"></div> <div class="h-screen"></div>
<div id="learnmore"></div> <div id="learnmore"></div>
<div class="h-[100px]"></div>
<div class=""> <div class="">
<div class=""></div> <div class="justify-center align-center gap-2 p-2 w-full flex flex-row flex-wrap" id="cards">
<div class="px-10 bg-gray-900/70 w-[300px] h-[200px] rounded-xl shadow-lg hover:shadow-sky-600/90 backdrop-blur-sm border border-gray-800 hover:border-gray-600/70 transition-all duration-700 justify-center align-middle flex flex-col" v-for="item in cards" :key="item.title">
<component :is="item.icon" class="w-8 h-8" />
<h3 class="text-xl font-bold">{{ item.title }}</h3>
<p class="">{{ item.description }}</p>
</div>
</div> </div>
<br /> <br />
<div class="justify-center align-center text-center w-full flex"> <div class="justify-center align-center text-center w-full flex">
<div <div
class="bg-[#C9C9C9]/60 rounded-xl shadow-lg p-4 m-4 w-1/2 align-center justify-center text-center" class="bg-gray-900/60 rounded-xl shadow-lg p-8 border border-gray-800 hover:border-sky-700 m-4 w-1/2 align-center justify-center text-center duration-700"
> >
<span class="text-2xl font-bold">Q/A</span> <span class="text-2xl font-bold">Q/A</span>
<Accordion <Accordion
@ -135,4 +166,5 @@ onMounted(() => {
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>