import { useActionQuery } from "@agent-native/core/client/hooks"; import { IconArrowsShuffle, IconFeather, IconSearch } from "@tabler/icons-react"; import { useMemo, useState } from "react"; import { QuoteCard } from "@/components/quotes/QuoteCard"; import { SubmitQuoteDialog } from "@/components/quotes/SubmitQuoteDialog"; import { TagFilterBar } from "@/components/quotes/TagFilterBar"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Skeleton } from "@/components/ui/skeleton"; import { useVisitorId } from "@/lib/visitor-id"; export function meta() { return [ { title: "Verse — quotes drawn from poems" }, { name: "description", content: "Discover, search, and save quotes drawn from classic and community-submitted poems.", }, ]; } export function HydrateFallback() { return (
); } function DailyQuoteHero() { const visitorId = useVisitorId(); const { data: quote, isLoading, refetch, isFetching } = useActionQuery("get-random-quote", { visitorId, }); return (
Quote of the moment
{isLoading ? (
) : quote ? ( ) : (

No quotes yet — be the first to submit one below.

)}
); } export default function QuotesHomeRoute() { const visitorId = useVisitorId(); const [search, setSearch] = useState(""); const [activeTag, setActiveTag] = useState(null); const { data: quotes, isLoading } = useActionQuery("list-quotes", { visitorId }); const allTags = useMemo(() => { const set = new Set(); for (const q of quotes ?? []) for (const tag of q.tags) set.add(tag); return Array.from(set).sort(); }, [quotes]); const filtered = useMemo(() => { const term = search.trim().toLowerCase(); return (quotes ?? []).filter((q) => { if (activeTag && !q.tags.includes(activeTag)) return false; if (!term) return true; const haystack = `${q.text} ${q.poem.title} ${q.poem.author}`.toLowerCase(); return haystack.includes(term); }); }, [quotes, search, activeTag]); return (

Verse

Quotes drawn from poems — browse, search, and save your favorites.

setSearch(e.target.value)} placeholder="Search quotes, poets, poems..." className="pl-8" />
{isLoading ? (
{Array.from({ length: 4 }).map((_, i) => ( ))}
) : filtered.length === 0 ? (

No quotes match. Try a different search or tag.

) : (
{filtered.map((quote) => ( setActiveTag(tag)} /> ))}
)}
); }