实现blog列表

This commit is contained in:
2025-05-18 14:30:03 +08:00
parent e1606b707e
commit 327f49bff0

View File

@@ -1,4 +1,16 @@
"use client"
import { Skeleton } from "@/components/ui/skeleton";
import { BlogApi } from "@/lib/api";
import { useCallback } from "react"
import useSWR from "swr";
import {
Alert,
AlertDescription,
AlertTitle,
} from "@/components/ui/alert";
import { AlertCircle } from "lucide-react";
import { base62 } from "@/lib/utils";
export default function Blog() {
const formatNumber = useCallback((num: number) => {
@@ -10,14 +22,39 @@ export default function Blog() {
return num.toString();
}, []);
const { data: blogs, error, isLoading } = useSWR(
'/api/blogs',
() => BlogApi.list(),
)
return (
<div className="max-w-120 w-auto mx-auto my-10 flex flex-col gap-8">
{
Array.from({ length: 10 }).map(() => (
<div className="w-full px-5 cursor-default" key={Math.random()}>
<a className="text-2xl font-medium cursor-pointer" target="_black"></a>
<p className="text-sm font-medium text-zinc-400">asdjkasdas </p>
<p className="text-sm font-medium text-zinc-400 mt-3">{new Date().toLocaleString()} · {formatNumber(1090)} 访</p>
isLoading && (
<div className="w-full">
<Skeleton className="w-full h-5" />
<Skeleton className="w-full h-10 mt-1" />
<Skeleton className="w-full h-5 mt-5" />
</div>
)
}
{
error && (
<Alert variant="destructive" className="w-full">
<AlertCircle className="h-4 w-4" />
<AlertTitle></AlertTitle>
<AlertDescription>
{error.message}
</AlertDescription>
</Alert>
)
}
{
blogs && blogs.map((blog) => (
<div className="w-full px-5 cursor-default" key={blog.id}>
<a className="text-2xl font-medium cursor-pointer hover:underline" target="_black" href={`/blog/${base62.encode(Buffer.from(blog.id.replace(/-/g, ''), 'hex'))}`}>{blog.title}</a>
<p className="text-sm font-medium text-zinc-400">{blog.description}</p>
<p className="text-sm font-medium text-zinc-400 mt-3">{new Date(blog.createdAt).toLocaleString()} · {formatNumber(blog.viewCount)} 访</p>
</div>
))
}