import { useState, useEffect, useMemo, useCallback } from 'react' import { useArticles } from '@/hooks/useArticles' import { useNostrAuth } from '@/hooks/useNostrAuth' import { applyFiltersAndSort } from '@/lib/articleFiltering' import type { Article } from '@/types/nostr' import type { ArticleFilters } from '@/components/ArticleFilters' import { HomeView } from '@/components/HomeView' function usePresentationArticles(allArticles: Article[]) { const [presentationArticles, setPresentationArticles] = useState>(new Map()) useEffect(() => { const presentations = new Map() allArticles.forEach((article) => { if (article.isPresentation && article.pubkey) { presentations.set(article.pubkey, article) } }) setPresentationArticles(presentations) }, [allArticles]) return presentationArticles } function useHomeState() { const [searchQuery, setSearchQuery] = useState('') const [selectedCategory, setSelectedCategory] = useState(null) const [filters, setFilters] = useState({ authorPubkey: null, sortBy: 'newest', category: null, }) const [unlockedArticles, setUnlockedArticles] = useState>(new Set()) return { searchQuery, setSearchQuery, selectedCategory, setSelectedCategory, filters, setFilters, unlockedArticles, setUnlockedArticles, } } function useArticlesData(searchQuery: string) { const { articles: allArticlesRaw, allArticles, loading, error, loadArticleContent } = useArticles(searchQuery, null) const presentationArticles = usePresentationArticles(allArticles) return { allArticlesRaw, allArticles, loading, error, loadArticleContent, presentationArticles } } function useCategorySync(selectedCategory: ArticleFilters['category'], setFilters: (value: ArticleFilters | ((prev: ArticleFilters) => ArticleFilters)) => void) { useEffect(() => { setFilters((prev) => ({ ...prev, category: selectedCategory, })) }, [selectedCategory, setFilters]) } function useFilteredArticles( allArticlesRaw: Article[], searchQuery: string, filters: ArticleFilters, presentationArticles: Map ) { return useMemo( () => applyFiltersAndSort(allArticlesRaw, searchQuery, filters, presentationArticles), [allArticlesRaw, searchQuery, filters, presentationArticles] ) } function useUnlockHandler( loadArticleContent: (id: string, pubkey: string) => Promise
, setUnlockedArticles: React.Dispatch>> ) { return useCallback( async (article: Article) => { const fullArticle = await loadArticleContent(article.id, article.pubkey) if (fullArticle?.paid) { setUnlockedArticles((prev) => new Set([...prev, article.id])) } }, [loadArticleContent, setUnlockedArticles] ) } function useHomeController() { const { } = useNostrAuth() const { searchQuery, setSearchQuery, selectedCategory, setSelectedCategory, filters, setFilters, unlockedArticles, setUnlockedArticles, } = useHomeState() const { allArticlesRaw, allArticles, loading, error, loadArticleContent, presentationArticles } = useArticlesData(searchQuery) // Presentation guard removed - users can browse without author page useCategorySync(selectedCategory, setFilters) const articles = useFilteredArticles(allArticlesRaw, searchQuery, filters, presentationArticles) const handleUnlock = useUnlockHandler(loadArticleContent, setUnlockedArticles) return { searchQuery, setSearchQuery, selectedCategory, setSelectedCategory, filters, setFilters, articles, allArticles, loading, error, unlockedArticles, handleUnlock, } } export default function Home() { const controller = useHomeController() return ( { void controller.handleUnlock(a) }} /> ) }