"use client"; import { useEffect, useRef, useState } from "react"; import CatalogCardControls, { type CatalogControlsMode, } from "@/components/catalog/CatalogCardControls"; import CatalogEmptyState from "@/components/catalog/CatalogEmptyState"; import CatalogPagination from "@/components/catalog/CatalogPagination"; import { BLOG_PAGE_SIZE, blogImage, excerpt, formatDate, toPlainText, } from "@/components/catalog/utils"; import ConfirmDialog from "@/components/ConfirmDialog"; import styles from "@/components/BusinessDetailsPage.module.css"; import { en } from "@/lib/i18n/en"; import { deleteMeshkeeBlog, listMeshkeeBlogs, type MeshkeeBlog, } from "@/services/meshkee-content"; export default function BlogPanel({ meshkeeId, emptyLabel = en.blog.empty, addHref, controlsMode = "edit-remove", onManage, }: { meshkeeId: string; emptyLabel?: string; addHref?: string; controlsMode?: CatalogControlsMode; onManage?: () => void; }) { const sectionRef = useRef(null); const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [busy, setBusy] = useState(false); const [removing, setRemoving] = useState(null); const [removeBusy, setRemoveBusy] = useState(false); const [error, setError] = useState(""); useEffect(() => { let cancelled = false; void (async () => { setBusy(true); setError(""); try { const res = await listMeshkeeBlogs(meshkeeId, { page: 1, pageSize: BLOG_PAGE_SIZE, }); if (cancelled) return; setItems(res.items); setTotal(res.total); setPage(1); } catch (err) { if (!cancelled) { setError( err instanceof Error ? err.message : "Could not load blog posts.", ); } } finally { if (!cancelled) setBusy(false); } })(); return () => { cancelled = true; }; }, [meshkeeId]); function scrollToSection() { const node = sectionRef.current; if (!node) return; requestAnimationFrame(() => { requestAnimationFrame(() => { node.scrollIntoView({ behavior: "smooth", block: "start" }); }); }); } async function loadPage(next: number) { setBusy(true); try { const res = await listMeshkeeBlogs(meshkeeId, { page: next, pageSize: BLOG_PAGE_SIZE, }); setItems(res.items); setTotal(res.total); setPage(res.page); scrollToSection(); } finally { setBusy(false); } } async function confirmRemove() { if (!removing) return; setRemoveBusy(true); try { await deleteMeshkeeBlog(meshkeeId, removing.id); setItems((prev) => prev.filter((item) => item.id !== removing.id)); setTotal((value) => Math.max(0, value - 1)); setRemoving(null); } catch (err) { window.alert( err instanceof Error ? err.message : "Could not remove blog post.", ); } finally { setRemoveBusy(false); } } if (error) { return

{error}

; } return (
{busy ?

Loading blog…

: null}
{items.map((post) => { const image = blogImage(post); const text = post.abstract ? excerpt(toPlainText(post.abstract), 160) : ""; return (
{image ? ( ) : (
)}

{post.title}

{text ?

{text}

: null} {post.createdAt ? ( {formatDate(post.createdAt)} ) : null}
window.alert(`Edit blog coming soon: ${post.title}`) } onRemove={() => setRemoving(post)} />
); })}
{!items.length && !busy ? ( ) : null} void loadPage(next)} /> { if (!removeBusy) setRemoving(null); }} onConfirm={() => { void confirmRemove(); }} />
); }