[feat] dynamic page with latest stable release notes
This commit is contained in:
82
src/app/(main)/dynamic/page.tsx
Normal file
82
src/app/(main)/dynamic/page.tsx
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { MarkdownRender } from "@/components/markdown"
|
||||||
|
import { Card, CardBody, CardHeader, CardIcon } from "@/components/window/Card"
|
||||||
|
import { createClient } from "@/utils/supabase/client"
|
||||||
|
import { NewspaperFolding } from "@icon-park/react"
|
||||||
|
import useSWR from "swr"
|
||||||
|
import { Chip, Skeleton } from "@heroui/react"
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<section className="flex flex-col gap-4 overflow-hidden">
|
||||||
|
<Card className="overflow-hidden">
|
||||||
|
<CardHeader>
|
||||||
|
<CardIcon>
|
||||||
|
<NewspaperFolding /> 动态
|
||||||
|
</CardIcon>
|
||||||
|
{/* <CardTool>
|
||||||
|
<ToolButton onClick={async () => {}}>读取</ToolButton>
|
||||||
|
</CardTool> */}
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="overflow-y-hidden">
|
||||||
|
<ReleaseNotes />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReleaseNotes = () => {
|
||||||
|
const noticeFetcher = async () => {
|
||||||
|
const supabase = createClient()
|
||||||
|
const { data /* , error */ } = await supabase
|
||||||
|
.from("ReleaseNote")
|
||||||
|
.select("version, content, created_at")
|
||||||
|
.eq("stable", true)
|
||||||
|
.order("created_at", { ascending: false })
|
||||||
|
.range(0, 10)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: releases /* , error */, isLoading } = useSWR("/api/release-notes", noticeFetcher)
|
||||||
|
|
||||||
|
if (isLoading) return (
|
||||||
|
<div className="grid h-full grid-cols-1 gap-2 overflow-y-auto rounded-lg grid-flow-dense lg:grid-cols-2 xl:grid-cols-3 pb-9 hide-scrollbar">
|
||||||
|
<Skeleton className="h-32 rounded-lg"></Skeleton>
|
||||||
|
<Skeleton className="h-32 rounded-lg"></Skeleton>
|
||||||
|
<Skeleton className="h-32 rounded-lg"></Skeleton>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className="grid h-full grid-cols-1 gap-2 overflow-y-auto rounded-lg grid-flow-dense lg:grid-cols-2 xl:grid-cols-3 pb-9 hide-scrollbar">
|
||||||
|
{releases?.map((release, index) => (
|
||||||
|
<li key={index}>
|
||||||
|
{/* <Link href={`/releases/${release.version}`} className="w-full"> */}
|
||||||
|
<Card className="w-full h-full pt-3 transition bg-white text-zinc-900 dark:bg-white/10 dark:text-white">
|
||||||
|
<CardHeader>
|
||||||
|
<h3 className="w-full text-2xl font-semibold">CS工具箱 {release.version}</h3>
|
||||||
|
<span className="flex items-center gap-3">
|
||||||
|
{/* <Chip size="sm" className="bg-zinc-200">
|
||||||
|
版本:{release?.version}
|
||||||
|
</Chip> */}
|
||||||
|
<Chip size="sm" className="bg-zinc-200 dark:bg-white/10">
|
||||||
|
发布时间:
|
||||||
|
{release?.created_at ? new Date(release.created_at).toLocaleString() : "未知时间"}
|
||||||
|
</Chip>
|
||||||
|
</span>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="gap-3">
|
||||||
|
<div className="">
|
||||||
|
<MarkdownRender>{release?.content || "无内容"}</MarkdownRender>
|
||||||
|
</div>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
{/* </Link> */}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -21,3 +21,8 @@ a {
|
|||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 隐藏滚动条 */
|
||||||
|
.hide-scrollbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { cn, user } from "@heroui/react"
|
import { cn } from "@heroui/react"
|
||||||
import { Home, MonitorOne, Movie, Setting, Terminal, Toolkit } from "@icon-park/react"
|
import { Home, MonitorOne, Movie, NewspaperFolding, Setting, Terminal, Toolkit } from "@icon-park/react"
|
||||||
import { usePathname, useRouter } from "next/navigation"
|
import { usePathname, useRouter } from "next/navigation"
|
||||||
import type { ReactNode } from "react"
|
import type { ReactNode } from "react"
|
||||||
import { getVersion } from "@tauri-apps/api/app"
|
import { getVersion } from "@tauri-apps/api/app"
|
||||||
@@ -90,12 +90,15 @@ const SideBar = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
className="flex flex-col items-center justify-center h-full gap-5"
|
className="flex flex-col items-center justify-center h-full gap-5 pt-5"
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
>
|
>
|
||||||
<SideButton route="/home">
|
<SideButton route="/home">
|
||||||
<Home size={24} />
|
<Home size={24} />
|
||||||
</SideButton>
|
</SideButton>
|
||||||
|
<SideButton route="/dynamic">
|
||||||
|
<NewspaperFolding size={24} />
|
||||||
|
</SideButton>
|
||||||
<SideButton route="/tool">
|
<SideButton route="/tool">
|
||||||
<Toolkit size={24} />
|
<Toolkit size={24} />
|
||||||
</SideButton>
|
</SideButton>
|
||||||
|
|||||||
Reference in New Issue
Block a user