'use client' import { type BlogView } from 'app/blog/blog-view' import BlogGridItem from 'components/Blog/BlogGridItem' import BlogListItem from 'components/Blog/BlogListItem' import BlogViewToggle from 'components/Blog/BlogViewToggle' import { Search } from 'lucide-react' import { useMemo, useState } from 'react' import type PostTypes from 'types/post' import { InputGroup, InputGroupAddon, InputGroupInput } from 'ui' import SectionContainerWithCn from '@/components/Layouts/SectionContainerWithCn' interface Props { posts: PostTypes[] initialView: BlogView /** * When provided the component operates in controlled mode: the caller owns * the view and search state and the built-in filter bar is not rendered. */ view?: BlogView searchTerm?: string } export default function BlogListingClient({ posts, initialView, view: viewProp, searchTerm: searchTermProp, }: Props) { const isControlled = viewProp !== undefined const [internalView, setInternalView] = useState(initialView) const [internalSearchTerm, setInternalSearchTerm] = useState('') const view = isControlled ? viewProp : internalView const searchTerm = isControlled ? (searchTermProp ?? '') : internalSearchTerm const isList = view === 'list' const visiblePosts = useMemo(() => { if (!searchTerm) return posts const term = searchTerm.toLowerCase() return posts.filter( (post) => (post.title ?? '').toLowerCase().includes(term) || (post.description ?? '').toLowerCase().includes(term) || (post.author ?? '').toLowerCase().includes(term) ) }, [posts, searchTerm]) return ( <> {!isControlled && (
setInternalSearchTerm(e.target.value)} />
)} {visiblePosts.length > 0 ? ( isList ? ( ) : ( ) ) : (

{searchTerm ? 'No posts matching your search.' : 'No posts found.'}

)}
) }