import Head from 'next/head' import React, { useEffect, useState } from 'react' import Loader from '../components/Loader' import Layout, { siteTitle } from '../components/Layout' import { matomoConfig } from '../lib/matomoConfig' import getMatomo from '../lib/getMatomo' import { GetServerSideProps, InferGetServerSidePropsType } from 'next' import SoftwareBadge from '../components/badges/SoftwareBadge' import SortToggle from '../components/SortToggle' import { faSearch, faAngleDoubleDown, faExclamationTriangle } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { useRouter } from 'next/router' import { useQuery } from '@apollo/client' import { ListNodesQuery, ListNodesResult } from '../graphql/client/queries/ListNodesQuery' import { nodeQueryInputSchema, NodeQueryInputType } from '../graphql/common/types/NodeQueryInput' import { ListNodesVariables } from '../graphql/common/queries/listNodes' import { NodeSoringByEnumType } from '../graphql/common/types/NodeSortingByEnum' const Nodes: React.FC> = ({ matomoConfig }) => { const router = useRouter() let routerQuery: NodeQueryInputType try { routerQuery = nodeQueryInputSchema.parse(router.query) } catch (e) { routerQuery = { search: '', sortBy: 'refreshedAt', sortWay: '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(ListNodesQuery, { variables: { query, paging: { page: 0 } } }) useEffect(() => { getMatomo(matomoConfig).trackEvent({ category: 'nodes', action: 'next-page', customDimensions: [ { value: page.toString(), id: 1 } ] }) }, [page]) useEffect((): void => { void router.push({ query }) getMatomo(matomoConfig).trackEvent({ category: 'nodes', action: 'new-search' }) }, [query]) const handleQueryChange = (event): void => { const targetInput = event.target const value = targetInput.value const name = targetInput.name const newQuery: NodeQueryInputType = { ...query } newQuery[name] = value console.info('Query changed', { name, value }) setQuery(newQuery) setPage(0) } const handleSearchSubmit = async (event): Promise => { setPageLoading(true) event.preventDefault() setQuery(query) setPage(0) await refetch({ paging: { page: 0 } }) setPageLoading(false) } const handleLoadMore = async (event): Promise => { event.preventDefault() 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 }) fetchMoreResult.listNodes.items = [ ...previousData.listNodes.items, ...fetchMoreResult.listNodes.items ] return fetchMoreResult } }) setPageLoading(false) } const toggleSort = (sortBy: NodeSoringByEnumType): void => { const sortWay = query.sortBy === sortBy && query.sortWay === 'asc' ? 'desc' : 'asc' getMatomo(matomoConfig).trackEvent({ category: 'nodes', action: 'sort', customDimensions: [ { value: `${sortBy} ${sortWay}`, id: 2 } ] }) setQuery({ ...query, sortBy, sortWay }) } return ( {siteTitle}

Search servers

{ (data != null) ? (
{(data.listNodes.items.length > 0) ? data.listNodes.items.map((node, index) => { return ( ) }) : ( )}
Domain Software User count Statuses Registrations Last refreshed
Total Indexed Month active Half year active
{node.domain}
{node.standardizedSoftwareVersion ?? ''}
{node.totalUserCount ?? '?'} {node.accountFeedCount ?? '0'} {node.monthActiveUserCount ?? '?'} {node.halfYearActiveUserCount ?? '?'} {node.statusesCount ?? '?'} {node.openRegistrations === null ? '?' : (node.openRegistrations ? 'Opened' : 'Closed')} {node.refreshedAt !== '' ? (new Date(node.refreshedAt)).toLocaleDateString() : 'Never'}
No servers found
) : '' }
{!loading && !pageLoading && data?.listNodes?.paging?.hasNext !== undefined && data?.listNodes?.paging?.hasNext ? (
) : ''} {(error != null) ? (
{error.message}
) : ''}
) } export const getServerSideProps: GetServerSideProps = async () => { console.info('Loading matomo config', matomoConfig) return { props: { matomoConfig } } } export default Nodes