'use client' import { useQuery } from '@apollo/client' import { usePathname, useRouter, useSearchParams } from 'next/navigation' import React, { ReactElement, useEffect, useState } from 'react' import { z } from 'zod' import { FeedQueryInput, ListNodesDocument, NodeQueryInput, NodeSortingByEnum, SortingWayEnum } from '../../graphql/generated/types' import { useMatomo } from '../../hooks/MatomoHook' import createUrlSearchParams from '../../utils/createUrlSearchParams' import { stringTrimmed, transform } from '../../utils/transform' import createSortingInputSchema from '../../schema/createSortingInputSchema' import ErrorMessage from '../ErrorMessage' import Loader from '../Loader' import LoadMoreButton from '../LoadMoreButton' import ResponsiveTable from '../ResponsiveTable' import NodeForm from './NodeForm' import NodeHeader from './NodeHeader' import NodePlaceholder from './NodePlaceholder' import NodeResults from './NodeResults' export const nodeQueryInputSchema = createSortingInputSchema(NodeSortingByEnum) .extend( { search: transform( z.string().optional(), stringTrimmed, z.string() ) } ) export default function NodeSearch (): ReactElement { const matomo = useMatomo() const pathname = usePathname() const searchParams = useSearchParams() const router = useRouter() let routerQuery: NodeQueryInput try { routerQuery = nodeQueryInputSchema.parse(Object.fromEntries(searchParams)) } catch (e) { routerQuery = { search: '', sortBy: NodeSortingByEnum.RefreshedAt, sortWay: SortingWayEnum.Desc } } console.log('Router query', routerQuery) const [query, setQuery] = useState(routerQuery) const [page, setPage] = useState(0) const [pageLoading, setPageLoading] = useState(false) const { loading, error, data, fetchMore, refetch } = useQuery(ListNodesDocument, { variables: { query, paging: { page: 0 } } }) useEffect(() => { matomo.trackEvent({ category: 'nodes', action: 'next-page', customDimensions: [ { value: page.toString(), id: 1 } ] }) }, [page]) useEffect((): void => { router.push(`${pathname ?? ''}?${createUrlSearchParams(query).toString()}`) matomo.trackEvent({ category: 'nodes', action: 'new-search' }) }, [query]) const handleQueryChange = (query: FeedQueryInput): void => { console.info('Query changed', { query }) setQuery(query) setPage(0) } const handleSearchSubmit = async (): Promise => { setPageLoading(true) setQuery(query) setPage(0) await refetch({ paging: { page: 0 } }) setPageLoading(false) } const handleLoadMore = async (): Promise => { setPage(page + 1) console.info('Loading next page', { query, page }) setPageLoading(true) await fetchMore({ variables: { paging: { page: page + 1 } }, updateQuery: (previousData, { fetchMoreResult }) => { console.log('more', { previousData, fetchMoreResult }) if (undefined === fetchMoreResult?.listNodes?.items) { return previousData } if (undefined === previousData?.listNodes?.items) { return fetchMoreResult } fetchMoreResult.listNodes.items = [ ...previousData.listNodes.items, ...fetchMoreResult.listNodes.items ] return fetchMoreResult } }) setPageLoading(false) } const toggleSort = (sortBy: NodeSortingByEnum): void => { const sortWay = query.sortBy === sortBy && query.sortWay === SortingWayEnum.Asc ? SortingWayEnum.Desc : SortingWayEnum.Asc matomo.trackEvent({ category: 'nodes', action: 'sort', customDimensions: [ { value: `${sortBy} ${sortWay}`, id: 2 } ] }) setQuery({ ...query, sortBy, sortWay }) } return ( <> )}> ) }