"use client" import { BlogCardGrid } from "@/components/blog-home/blog-home-card"; import { Button } from "@/components/ui/button"; import { TrendingUp, Clock, } from "lucide-react"; import Sidebar, { SidebarAbout, SidebarHotPosts, SidebarMisskeyIframe, SidebarTags } from "../blog/blog-sidebar-card"; import type { Post } from "@/models/post"; import { listPosts } from "@/api/post"; import { useEffect, useState } from "react"; import { motion } from "motion/react"; import { useTranslations } from "next-intl"; import { useSearchParams } from "next/navigation"; import { OrderBy } from "@/models/common"; import { PaginationController } from "@/components/common/pagination"; import { QueryKey } from "@/constant"; import { useStoredState } from "@/hooks/use-storage-state"; import { parseAsInteger, useQueryState } from "nuqs"; import { useSiteInfo } from "@/contexts/site-info-context"; // 定义排序类型 enum SortBy { Latest = 'latest', Hottest = 'hottest', } const DEFAULT_SORTBY: SortBy = SortBy.Latest; export default function BlogHome() { // 从路由查询参数中获取页码和标签们 const t = useTranslations("BlogHome"); const {siteInfo} = useSiteInfo(); const [labels, setLabels] = useState([]); const [keywords, setKeywords] = useState([]); const [page, setPage] = useQueryState("page", parseAsInteger.withDefault(1).withOptions({ history: "replace", clearOnDefault: true })); const [posts, setPosts] = useState([]); const [totalPosts, setTotalPosts] = useState(0); const [loading, setLoading] = useState(false); const [sortBy, setSortBy, isSortByLoaded] = useStoredState(QueryKey.SortBy, DEFAULT_SORTBY); useEffect(() => { if (!isSortByLoaded) return; setLoading(true); listPosts( { page, size: siteInfo.postsPerPage || 9, orderBy: sortBy === SortBy.Latest ? OrderBy.CreatedAt : OrderBy.Heat, desc: true, keywords: keywords.join(",") || undefined, labels: labels.join(",") || undefined, } ).then(res => { setPosts(res.data.posts); setTotalPosts(res.data.total); setLoading(false); }).catch(err => { console.error(err); setLoading(false); }); }, [keywords, labels, page, sortBy, isSortByLoaded]); const handleSortChange = (type: SortBy) => { if (sortBy !== type) { setSortBy(type); setPage(1); } }; const handlePageChange = (page: number) => { window.scrollTo({ top: 0, behavior: 'smooth' }); setPage(page); } return ( <> {/* 主内容区域 */}
{/* 容器 - 关键布局 */}
{/* 主要内容区域 */} {/* 文章列表标题 */}

{sortBy === 'latest' ? t("latest_posts") : t("hottest_posts")} {posts.length > 0 && ( ({posts.length}) )}

{/* 排序按钮组 */} {isSortByLoaded &&
}
{/* 博客卡片网格 */} {/* 分页控制器 */}
{totalPosts > 0 && }
{/* 加载状态指示器 */} {loading && (
{t("loading")}
)}
{/* 侧边栏 */} , posts.length > 0 ? : null, , , ].filter(Boolean)} />
); }