"use client";
import { format } from "date-fns";
import FuzzySearch from "fuzzy-search";
import Link from "next/link";
import { useMemo, useState } from "react";
import { Container } from "@/components/container";
import type { BlogEntry } from "./page";
function truncate(text: string, length: number) {
return text.length > length ? `${text.slice(0, length)}…` : text;
}
function SearchIcon({ className }: { className?: string }) {
return (
);
}
export function BlogWithSearchMagazine({ blogs }: { blogs: BlogEntry[] }) {
if (blogs.length === 0) {
return (
No blog posts yet.
);
}
// `blogs` arrives pre-sorted from the server: explicitly featured posts
// first (ordered by `featured_order` asc, then date desc), then the rest
// by date desc. If nothing is explicitly featured, fall back to treating
// the newest post as the cover so the layout never feels empty up top.
// `MagazineSearchGrid` re-filters using `heroSlugs` so the hero/featured
// posts never duplicate into the archive grid.
const explicitlyFeatured = blogs.filter((b) => b.featured);
const heroBlogs = explicitlyFeatured.length > 0 ? explicitlyFeatured : blogs.slice(0, 1);
const heroSlugs = new Set(heroBlogs.map((b) => b.slug));
const [coverStory, ...secondaryFeatured] = heroBlogs;
return (