import * as React from "react" import { createFileRoute, useParams } from "@tanstack/react-router" import { useAccountOrGuest, useCoState } from "@/lib/providers/jazz-provider" import { GraphData, JAZZ_GLOBAL_GROUP_ID } from "@/lib/constants" import { Topic } from "@/lib/schema" import { atom } from "jotai" import { Skeleton } from "@/components/ui/skeleton" import { LaIcon } from "@/components/custom/la-icon" import { TopicDetailHeader } from "./-header" import { TopicDetailList } from "./-list" export const Route = createFileRoute("/_layout/_pages/(topic)/$")({ component: TopicDetailComponent, }) export const openPopoverForIdAtom = atom(null) export function TopicDetailComponent() { const params = useParams({ from: "/_layout/_pages/(topic)/$" }) const { me } = useAccountOrGuest({ root: { personalLinks: [{}] } }) const topicID = React.useMemo( () => me && Topic.findUnique({ topicName: params._splat }, JAZZ_GLOBAL_GROUP_ID, me), [params._splat, me], ) const topic = useCoState(Topic, topicID, { latestGlobalGuide: { sections: [] }, }) const [activeIndex, setActiveIndex] = React.useState(-1) const [searchQuery, setSearchQuery] = React.useState("") const topicExists = React.useMemo( () => GraphData.find((node) => node.name === params._splat), [params._splat], ) const latestGlobalGuide = React.useMemo( () => topic?.latestGlobalGuide, [topic?.latestGlobalGuide], ) const flattenedItems = React.useMemo( () => latestGlobalGuide?.sections.flatMap((section) => [ { type: "section" as const, data: section }, ...(section?.links?.map((link) => ({ type: "link" as const, data: link, })) || []), ]) || [], [latestGlobalGuide], ) const filteredItems = React.useMemo(() => { if (!searchQuery) return flattenedItems return flattenedItems.filter((item) => { if (item.type === "section") { return item.data?.title .toLowerCase() .includes(searchQuery.toLowerCase()) } if (item.type === "link") { return ( item.data?.title.toLowerCase().includes(searchQuery.toLowerCase()) || item.data?.url.toLowerCase().includes(searchQuery.toLowerCase()) ) } return false }) }, [flattenedItems, searchQuery]) if (!topicExists) { return } if (!topic || !me) { return } return ( <> ) } function NotFoundPlaceholder() { return (
Topic not found
There is no topic with the given identifier.
) } function TopicDetailSkeleton() { return ( <>
{[...Array(10)].map((_, index) => (
))}
) }