mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-02-11 06:24:56 -05:00
showing adjacent timezones for players
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { Flex, LoadingState, Text, TimezoneOptions, VStack } from '@metafam/ds';
|
||||
import { PlayerList } from 'components/Player/PlayerList';
|
||||
import { GetPlayersQueryVariables } from 'graphql/autogen/types';
|
||||
import { usePlayerFilter } from 'lib/hooks/players';
|
||||
import { useOnScreen } from 'lib/hooks/useOnScreen';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
type Props = {
|
||||
queryVariables: GetPlayersQueryVariables;
|
||||
};
|
||||
|
||||
export const AdjascentTimezonePlayers: React.FC<Props> = ({
|
||||
queryVariables: defaultQueryVariables,
|
||||
}) => {
|
||||
const moreRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const queryVariables = useMemo(() => {
|
||||
const timezoneValue = defaultQueryVariables.timezones
|
||||
? defaultQueryVariables.timezones[0]
|
||||
: undefined;
|
||||
const timezone = TimezoneOptions.find((t) => t.value === timezoneValue);
|
||||
const adjascentTimezones = timezone
|
||||
? TimezoneOptions.filter(
|
||||
(t) =>
|
||||
Math.abs(t.offset - timezone.offset) <= 4 &&
|
||||
t.value !== timezoneValue,
|
||||
).sort((a, b) => (a.offset < b.offset ? -1 : 1))
|
||||
: [];
|
||||
return {
|
||||
...defaultQueryVariables,
|
||||
offset: 0,
|
||||
timezones: adjascentTimezones.map((t) => t.value),
|
||||
};
|
||||
}, [defaultQueryVariables]);
|
||||
|
||||
const onScreen = useOnScreen(moreRef);
|
||||
|
||||
const {
|
||||
players,
|
||||
totalCount,
|
||||
fetching,
|
||||
fetchingMore,
|
||||
error,
|
||||
nextPage,
|
||||
moreAvailable,
|
||||
} = usePlayerFilter(queryVariables);
|
||||
|
||||
const loadMore = useCallback(() => {
|
||||
if (onScreen && !fetching && !fetchingMore && moreAvailable) {
|
||||
nextPage();
|
||||
}
|
||||
}, [nextPage, fetching, fetchingMore, onScreen, moreAvailable]);
|
||||
|
||||
useEffect(() => {
|
||||
loadMore();
|
||||
}, [loadMore]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{error ? <Text>{`Error: ${error.message}`}</Text> : null}
|
||||
{!error && players.length && (fetchingMore || !fetching) ? (
|
||||
<>
|
||||
<Flex
|
||||
justify="space-between"
|
||||
w="100%"
|
||||
maxW="80rem"
|
||||
px="4"
|
||||
align="center"
|
||||
>
|
||||
<Text fontWeight="bold" fontSize="xl" w="100%" maxW="79rem" mb="8">
|
||||
{totalCount} player{totalCount === 1 ? '' : 's'} in adjacent time
|
||||
zones
|
||||
</Text>
|
||||
</Flex>
|
||||
<PlayerList players={players} />
|
||||
</>
|
||||
) : null}
|
||||
<VStack w="100%" ref={moreRef}>
|
||||
{fetching || fetchingMore || moreAvailable ? (
|
||||
<LoadingState color="white" />
|
||||
) : (
|
||||
<Text color="white">No more players available</Text>
|
||||
)}
|
||||
</VStack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -150,7 +150,8 @@ export const DesktopFilters: React.FC<Props> = ({
|
||||
styles={styles}
|
||||
value={timezones}
|
||||
onChange={(value) => {
|
||||
setTimezones(value as ValueType[]);
|
||||
const values = value as ValueType[];
|
||||
setTimezones(values.slice(-1));
|
||||
}}
|
||||
options={TimezoneOptions}
|
||||
showSearch
|
||||
|
||||
@@ -231,10 +231,12 @@ export const MobileFilters: React.FC<Props> = ({
|
||||
<FilterContent
|
||||
value={timezones}
|
||||
onChange={(value) => {
|
||||
setTimezones(value as ValueType[]);
|
||||
const values = value as ValueType[];
|
||||
setTimezones(values.slice(-1));
|
||||
}}
|
||||
options={TimezoneOptions}
|
||||
onBack={onBack}
|
||||
isMulti={false}
|
||||
showSearch
|
||||
isTimezone
|
||||
/>
|
||||
|
||||
@@ -53,11 +53,17 @@ const useFilteredPlayers = (variables: GetPlayersQueryVariables) => {
|
||||
return { fetching, players, totalCount, error };
|
||||
};
|
||||
|
||||
export const usePlayerFilter = (): PlayerFilter => {
|
||||
export const usePlayerFilter = (
|
||||
defaultVariables: GetPlayersQueryVariables = defaultQueryVariables,
|
||||
): PlayerFilter => {
|
||||
const [
|
||||
queryVariables,
|
||||
setQueryVariables,
|
||||
] = useState<GetPlayersQueryVariables>(defaultQueryVariables);
|
||||
] = useState<GetPlayersQueryVariables>(defaultVariables);
|
||||
|
||||
useEffect(() => {
|
||||
setQueryVariables(defaultVariables);
|
||||
}, [defaultVariables]);
|
||||
|
||||
const aggregates = usePlayerAggregates();
|
||||
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { LoadingState, Text, VStack } from '@metafam/ds';
|
||||
import { PageContainer } from 'components/Container';
|
||||
import { AdjascentTimezonePlayers } from 'components/Player/Filter/AdjascentTimezonePlayers';
|
||||
import { PlayerFilter } from 'components/Player/Filter/PlayerFilter';
|
||||
import { PlayerList } from 'components/Player/PlayerList';
|
||||
import { HeadComponent } from 'components/Seo';
|
||||
import { GetPlayersQueryVariables } from 'graphql/autogen/types';
|
||||
import { getSsrClient } from 'graphql/client';
|
||||
import { getPlayerFilters, getPlayersWithCount } from 'graphql/getPlayers';
|
||||
import { usePlayerFilter } from 'lib/hooks/players';
|
||||
import { useOnScreen } from 'lib/hooks/useOnScreen';
|
||||
import { InferGetStaticPropsType } from 'next';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
type Props = InferGetStaticPropsType<typeof getStaticProps>;
|
||||
|
||||
@@ -46,15 +48,15 @@ const Players: React.FC<Props> = () => {
|
||||
moreAvailable,
|
||||
} = usePlayerFilter();
|
||||
|
||||
const loaderRef = useRef<HTMLDivElement>(null);
|
||||
const moreRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const onScreen = useOnScreen(loaderRef);
|
||||
const onScreen = useOnScreen(moreRef);
|
||||
|
||||
const loadMore = useCallback(() => {
|
||||
if (onScreen && !fetching) {
|
||||
if (onScreen && !fetching && !fetchingMore && moreAvailable) {
|
||||
nextPage();
|
||||
}
|
||||
}, [nextPage, fetching, onScreen]);
|
||||
}, [nextPage, fetching, fetchingMore, moreAvailable, onScreen]);
|
||||
|
||||
useEffect(() => {
|
||||
loadMore();
|
||||
@@ -77,24 +79,49 @@ const Players: React.FC<Props> = () => {
|
||||
resetFilter={resetFilter}
|
||||
totalCount={totalCount}
|
||||
/>
|
||||
{error && <Text>{`Error: ${error.message}`}</Text>}
|
||||
{!error && players.length && (fetchingMore || !fetching) && (
|
||||
{error ? <Text>{`Error: ${error.message}`}</Text> : null}
|
||||
{!error && players.length && (fetchingMore || !fetching) ? (
|
||||
<PlayerList players={players} />
|
||||
)}
|
||||
<VStack ref={loaderRef} w="100%">
|
||||
{fetching || fetchingMore || moreAvailable ? (
|
||||
<LoadingState color="white" />
|
||||
) : (
|
||||
<Text color="white">
|
||||
{totalCount > 0
|
||||
? 'No more players available'
|
||||
: 'There were no matches'}
|
||||
</Text>
|
||||
)}
|
||||
</VStack>
|
||||
) : null}
|
||||
<MorePlayers
|
||||
ref={moreRef}
|
||||
fetching={fetching || fetchingMore || moreAvailable}
|
||||
totalCount={totalCount}
|
||||
queryVariables={queryVariables}
|
||||
/>
|
||||
</VStack>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Players;
|
||||
|
||||
type MorePlayersProps = {
|
||||
fetching: boolean;
|
||||
totalCount: number;
|
||||
queryVariables: GetPlayersQueryVariables;
|
||||
};
|
||||
|
||||
const MorePlayers = React.forwardRef<HTMLDivElement, MorePlayersProps>(
|
||||
({ fetching, totalCount, queryVariables }, ref) => {
|
||||
const isTimezoneSelected = useMemo(
|
||||
() => queryVariables.timezones && queryVariables.timezones.length > 0,
|
||||
[queryVariables],
|
||||
);
|
||||
return (
|
||||
<VStack w="100%" ref={ref}>
|
||||
{fetching ? <LoadingState color="white" /> : null}
|
||||
{!fetching && !isTimezoneSelected ? (
|
||||
<Text color="white">
|
||||
{totalCount > 0
|
||||
? 'No more players available'
|
||||
: 'There were no matches'}
|
||||
</Text>
|
||||
) : null}
|
||||
{!fetching && isTimezoneSelected ? (
|
||||
<AdjascentTimezonePlayers queryVariables={queryVariables} />
|
||||
) : null}
|
||||
</VStack>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user