Files
cstb-next/src/app/(main)/dynamic/page.tsx

127 lines
4.2 KiB
TypeScript
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.
"use client"
import { useState } from "react"
import { MarkdownRender } from "@/components/markdown"
import { Card, CardBody, CardHeader, CardIcon, CardTool } from "@/components/window/Card"
import { createClient } from "@/utils/supabase/client"
import { NewspaperFolding } from "@icon-park/react"
import useSWR from "swr"
import { Chip, Skeleton, Tabs, Tab } from "@heroui/react"
import { Key } from "@react-types/shared"
export default function Page() {
const [selectedKey, setSelectedKey] = useState<Key>("stable")
const showTestVersions = selectedKey === "test"
return (
<section className="flex flex-col gap-4 overflow-hidden">
<Card className="overflow-hidden">
<CardHeader>
<CardIcon>
<NewspaperFolding />
</CardIcon>
<CardTool>
<Tabs
selectedKey={selectedKey}
onSelectionChange={setSelectedKey}
size="sm"
radius="full"
classNames={{
base: "min-w-0",
tabList: "gap-0 p-0",
tab: "min-w-0 px-3",
tabContent: "text-xs",
}}
>
<Tab key="stable" title="正式版" />
<Tab key="test" title="测试版" />
</Tabs>
</CardTool>
</CardHeader>
<CardBody className="overflow-y-hidden">
<ReleaseNotes showTestVersions={showTestVersions} />
</CardBody>
</Card>
</section>
)
}
const ReleaseNotes = ({ showTestVersions }: { showTestVersions: boolean }) => {
const noticeFetcher = async () => {
const supabase = createClient()
let query = supabase
.from("ReleaseNote")
.select("version, content, created_at, stable")
if (!showTestVersions) {
query = query.eq("stable", true)
}
const { data /* , error */ } = await query
.order("created_at", { ascending: false })
.range(0, 10)
return data
}
const { data: releases /* , error */, isLoading } = useSWR(
`/api/release-notes?test=${showTestVersions}`,
noticeFetcher
)
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"
>
{isLoading ? (
<>
<li><Skeleton className="h-32 rounded-lg"></Skeleton></li>
<li><Skeleton className="h-32 rounded-lg"></Skeleton></li>
<li><Skeleton className="h-32 rounded-lg"></Skeleton></li>
</>
) : (
releases?.map((release) => {
const isStable = release.stable === true
return (
<li key={release.version}>
{/* <Link href={`/releases/${release.version}`} className="w-full"> */}
<Card
className="w-full h-full pt-3 transition bg-white/60 text-zinc-900 dark:bg-white/5 dark:text-white"
>
<CardHeader>
<div className="flex items-center justify-between w-full gap-2">
<h3 className="text-2xl font-semibold">CS工具箱 {release.version}</h3>
<Chip
size="sm"
variant="bordered"
className={
isStable
? "border-blue-400 text-blue-600 dark:border-blue-500 dark:text-blue-400"
: "border-orange-400 text-orange-600 dark:border-orange-500 dark:text-orange-400"
}
>
{isStable ? "正式版" : "测试版"}
</Chip>
</div>
<span className="flex items-center gap-3">
<Chip size="sm" className="bg-zinc-200 dark:bg-white/10">
{release.created_at ? new Date(release.created_at as string).toLocaleString() : "未知时间"}
</Chip>
</span>
</CardHeader>
<CardBody className="gap-3">
<div className="">
<MarkdownRender>{release.content || "无内容"}</MarkdownRender>
</div>
</CardBody>
</Card>
{/* </Link> */}
</li>
)
})
)}
</ul>
)
}