"use client"; import { useInfiniteQuery } from "@tanstack/react-query"; import { useSearchParams } from "next/navigation"; import { Fragment, useCallback, useMemo } from "react"; import { Button } from "@nextui-org/button"; import { Spacer } from "@nextui-org/spacer"; import { useClient } from "@/hooks/useClient"; import { useSearch } from "@/hooks/useSearch"; import { SearchType, SearchTypeModel } from "@/client/typings/search/options"; import { Container } from "@/components/Container"; import { LoadingPage } from "@/components/LoadingPage"; import { Search as SearchInput } from "@/components/Search"; import { Channel } from "./Channel"; import { Filter } from "./Filter"; import { Loading } from "./Loading"; import { Playlist } from "./Playlist"; import { Video } from "./Video"; import { Component } from "@/typings/component"; export const Search: Component = () => { const client = useClient(); const searchParams = useSearchParams(); const query = searchParams.get("search_query") as string; const invalidQuery = useMemo(() => { if (query === null || query.length === 0) return new Error(`The required parameter 'query' is missing`); }, [query]); const filter = (searchParams.get("filter") ?? "all") as SearchType; const invalidFilter = useMemo(() => { const parsed = SearchTypeModel.safeParse(filter); if (!parsed.success) return new Error(`The provided filter \`${filter}\` is invalid`); }, [filter]); const canSearch = !(!!invalidQuery || !!invalidFilter); const { data, error: fetchError, fetchNextPage, refetch, isPending, isFetchingNextPage } = useInfiniteQuery({ queryKey: ["search", query, filter], queryFn: async ({ pageParam }) => { return await client.getSearch(query ?? "", { pageParam: pageParam, type: filter }); }, enabled: canSearch, initialPageParam: "", getNextPageParam: (lastPage) => lastPage.nextCursor }); const error = invalidFilter ?? fetchError ?? undefined; const searchFor = useSearch(); const setFilter = useCallback( (filter: SearchType) => { searchFor(query, filter); }, [query, searchFor] ); const handleUserReachedPageEnd = useCallback( (visiblity: boolean) => { if (visiblity && !isFetchingNextPage) fetchNextPage(); }, [isFetchingNextPage, fetchNextPage] ); const hasLoadedData = canSearch && data?.pages.flat().length ? data?.pages.flat().length !== 0 : false; const isLoadingInitialData = canSearch && !isFetchingNextPage && isPending; return ( <>
{canSearch && (
)}
{isLoadingInitialData && } {error && (

An error occurred loading the search page

{error.toString()}

)} {hasLoadedData && ( <>
{data?.pages.map((page, i) => { return ( {page.items.map((result) => { switch (result.type) { case "channel": return ; case "video": return ); })}
)}
); };