"use client"; import { IconEye, IconMessages } from "@tabler/icons-react"; import Link from "next/link"; import { createContext, type ReactNode, useContext, useEffect, useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; import { getAllCommentCounts } from "@/lib/server/comments"; import { getAllViewCounts } from "@/lib/server/views"; const numberFormatter = new Intl.NumberFormat(process.env.NEXT_PUBLIC_SITE_LOCALE); type Stats = { views: Record; comments: Record; loaded: boolean; }; const StatsContext = createContext({ views: {}, comments: {}, loaded: false, }); /** * Provider that fetches ALL post stats in a single batch (2 requests total). * Wrap this around any component tree that contains PostStats components. */ export const PostStatsProvider = ({ children }: { children: ReactNode }) => { const [stats, setStats] = useState({ views: {}, comments: {}, loaded: false, }); useEffect(() => { Promise.all([getAllViewCounts(), getAllCommentCounts()]) .then(([views, comments]) => { setStats({ views, comments, loaded: true }); }) .catch((err) => { console.error("[post-stats] error fetching stats:", err); setStats({ views: {}, comments: {}, loaded: true }); }); }, []); return {children}; }; /** * Displays view/comment badges for a single post. * Must be used within a PostStatsProvider. */ const PostStats = ({ slug }: { slug: string }) => { const { views, comments, loaded } = useContext(StatsContext); if (!loaded) { return ( <> ); } const viewCount = views[slug] ?? 0; const commentCount = comments[slug] ?? 0; return ( <> {viewCount > 0 && ( )} {commentCount > 0 && ( } > )} ); }; export { PostStats };