"use client" import { Button } from "../ui/button" import { Input } from "../ui/input" import { ArticleInEvidenceCard } from "./article-in-evidance-card" import { ArticleListCard } from "./article-list-card" import { LABELS } from "@/app/labels" import { Article, ArticleTag } from "@/lib/content" import { useQuery } from "@tanstack/react-query" import { Search as SearchIcon } from "lucide-react" import { useRouter, useSearchParams } from "next/navigation" import { useState } from "react" import { useDebounce, useMedia } from "react-use" async function fetchArticles(tag?: string) { try { const params = new URLSearchParams() if (tag) params.append("tag", tag) const response = await fetch(`/api/articles?${params.toString()}`, { cache: "default", }) if (!response.ok) { throw new Error(`Failed to fetch articles: ${response.status}`) } const data = await response.json() return data.articles || [] } catch (error) { console.error("Error fetching articles:", error) return [] } } interface ArticlesListProps { tag?: string } export const ArticlesList: React.FC = ({ tag, }: ArticlesListProps) => { const router = useRouter() const params = useSearchParams() const query = params.get("query") const [searchQuery, setSearchQuery] = useState(query ?? "") const { data: articles = [], isLoading, isError, } = useQuery({ queryKey: ["articles", tag], queryFn: () => fetchArticles(tag), }) if (isLoading || articles.length === 0) { return null } if (isError) { return (

Error loading articles

) } const hasSearchParams = (searchQuery ?? "")?.length > 0 && searchQuery !== "all" const lastArticle = articles[0] const featuredArticles = !tag ? articles.slice(1, 3) : [] let otherArticles = !tag && !hasSearchParams ? articles.slice(3, 6) : [] if (searchQuery === "all") { otherArticles = articles } else if (searchQuery?.length > 0) { otherArticles = articles.filter((article: Article) => { const title = article.title.toLowerCase() const content = article.content.toLowerCase() const tags = article.tags?.map((tag: ArticleTag) => tag.name.toLowerCase()) ?? [] return ( title.includes(searchQuery.toLowerCase()) || tags.some((tag: string) => tag.includes(searchQuery.toLowerCase())) ) }) } const hasTag = tag !== undefined const onSearchArticles = (query: string) => { setSearchQuery(query) router.push(`/blog?query=${query}`) } useDebounce( () => { if (searchQuery === "") return null onSearchArticles(searchQuery) }, 500, // debounce timeout in ms when user is typing [searchQuery] ) const isMobile = useMedia("(max-width: 768px)") return (
{!hasTag && !hasSearchParams && searchQuery !== "all" && (
{isMobile && ( <> {featuredArticles?.map((article: Article) => { return ( ) })} )}
{!isMobile && (
{featuredArticles?.map((article: Article) => { return ( ) })}
)}
)}
{ onSearchArticles(e?.target?.value ?? "") }} onIconClick={() => { onSearchArticles(searchQuery) }} />
{otherArticles .filter((article: Article) => article.id !== lastArticle.id) .map((article: Article) => { return })}
{searchQuery?.length === 0 && ( )}
) }