[feat] setup supabase + notice and cfgx fetching
This commit is contained in:
92
src/app/(main)/console/cfgx/page.tsx
Normal file
92
src/app/(main)/console/cfgx/page.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
"use client"
|
||||
|
||||
import { createClient } from "@/utils/supabase/client"
|
||||
import { Chip, Code, Skeleton } from "@heroui/react"
|
||||
import useSWR from "swr"
|
||||
|
||||
export default function Page() {
|
||||
return <CfgxList />
|
||||
}
|
||||
|
||||
function CfgxList() {
|
||||
const noticeFetcher = async () => {
|
||||
const supabase = createClient()
|
||||
const { data /* , error */ } = await supabase
|
||||
.from("CFGX")
|
||||
.select(
|
||||
"created_at, updated_at, cfgx_version, title, description, version, author, content, alias_list, key_list, value_list",
|
||||
)
|
||||
.order("created_at", { ascending: false })
|
||||
|
||||
return data as CfgxCardProps[]
|
||||
}
|
||||
|
||||
const { data: cfgx /* , error */, isLoading } = useSWR<CfgxCardProps[]>(
|
||||
"/api/cfgx",
|
||||
noticeFetcher,
|
||||
)
|
||||
|
||||
if (isLoading)
|
||||
return [1, 2, 3].map((id) => (
|
||||
<Skeleton className="mb-3 rounded-lg" key={id}>
|
||||
<div className="h-16" />
|
||||
</Skeleton>
|
||||
))
|
||||
|
||||
return (
|
||||
<ul className="flex flex-col gap-3">
|
||||
{cfgx?.map((cfgx) => (
|
||||
<CfgxCard key={cfgx.title} {...cfgx} />
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
interface CfgxCardProps {
|
||||
created_at: string
|
||||
updated_at: string
|
||||
cfgx_version: string
|
||||
title: string
|
||||
description: string
|
||||
version: string
|
||||
author: string
|
||||
content: string
|
||||
alias_list?: {
|
||||
id: string
|
||||
info: string
|
||||
value: string
|
||||
}
|
||||
key_list?: {
|
||||
id: string
|
||||
info: string
|
||||
value: string
|
||||
}
|
||||
value_list?: {
|
||||
id: string
|
||||
info: string
|
||||
value: string
|
||||
}
|
||||
}
|
||||
|
||||
function CfgxCard(props: CfgxCardProps) {
|
||||
return (
|
||||
<li className="flex flex-col gap-2 p-4 rounded-md bg-zinc-50 ">
|
||||
<span className="flex items-center gap-3">
|
||||
<h3 className="text-xl font-semibold">{props.title}</h3>
|
||||
<Chip size="sm" className="bg-zinc-200">
|
||||
{props.version}
|
||||
</Chip>
|
||||
<Chip size="sm" className="bg-zinc-200">
|
||||
{props.author}
|
||||
</Chip>
|
||||
</span>
|
||||
<p className="text-zinc-600">{props.description}</p>
|
||||
<Code className="p-3 whitespace-pre-line">{props.content}</Code>
|
||||
{props.alias_list && (
|
||||
<p className="text-zinc-600">
|
||||
{props.alias_list.id} {props.alias_list.info} {props.alias_list.value}
|
||||
</p>
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
52
src/app/(main)/console/layout.tsx
Normal file
52
src/app/(main)/console/layout.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client"
|
||||
import { Card, CardBody, CardHeader, CardIcon } from "@/components/window/Card"
|
||||
import { cn } from "@heroui/react"
|
||||
import { SettingConfig } from "@icon-park/react"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
export default function PreferenceLayout({
|
||||
children,
|
||||
}: { children: React.ReactNode }) {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
|
||||
return (
|
||||
<Card className="h-full max-w-full overflow-y-scroll">
|
||||
<CardHeader>
|
||||
<CardIcon
|
||||
type="menu"
|
||||
onClick={() => router.push("/console/cfgx")}
|
||||
className={cn(pathname === "/console/cfgx" && "bg-black/5")}
|
||||
>
|
||||
<SettingConfig /> CFGX
|
||||
</CardIcon>
|
||||
{/* <CardIcon
|
||||
type="menu"
|
||||
onClick={() => router.push("/console/path")}
|
||||
className={cn(pathname === "/console/path" && "bg-black/5")}
|
||||
>
|
||||
<AssemblyLine /> 路径
|
||||
</CardIcon>
|
||||
<CardIcon
|
||||
type="menu"
|
||||
onClick={() => router.push("/console/replay")}
|
||||
className={cn(pathname === "/console/replay" && "bg-black/5")}
|
||||
>
|
||||
<Videocamera /> 录像
|
||||
</CardIcon> */}
|
||||
|
||||
{/* <CardTool>
|
||||
<ToolButton>
|
||||
<UploadOne />
|
||||
云同步
|
||||
</ToolButton>
|
||||
<ToolButton>
|
||||
<HardDisk />
|
||||
保存
|
||||
</ToolButton>
|
||||
</CardTool> */}
|
||||
</CardHeader>
|
||||
<CardBody>{children}</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
"use client"
|
||||
import { redirect } from "next/navigation"
|
||||
|
||||
export default function Page() {
|
||||
return <div>Console</div>
|
||||
redirect("/console/cfgx")
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use client"
|
||||
import Nav from "@/components/window/Nav"
|
||||
|
||||
export default function BaseLayout({ children }: { children: React.ReactNode }) {
|
||||
export default function BaseLayout({
|
||||
children,
|
||||
}: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="w-full h-full">
|
||||
<Nav />
|
||||
|
||||
@@ -13,7 +13,10 @@ export default function Providers({ children }: { children: React.ReactNode }) {
|
||||
|
||||
return (
|
||||
<HeroUIProvider
|
||||
className={cn("h-full bg-zinc-100/90 dark:bg-zinc-900", os === "macos" && "rounded-lg")}
|
||||
className={cn(
|
||||
"h-full bg-zinc-100/90 dark:bg-zinc-900",
|
||||
os === "macos" && "rounded-lg",
|
||||
)}
|
||||
>
|
||||
<NextThemesProvider attribute="class" defaultTheme="light">
|
||||
<ToastProvider toastOffset={10} placement="top-center" />
|
||||
|
||||
Reference in New Issue
Block a user