diff --git a/packages/design-system/babel.config.js b/packages/design-system/babel.config.js new file mode 100644 index 00000000..7f31bf5b --- /dev/null +++ b/packages/design-system/babel.config.js @@ -0,0 +1,7 @@ +module.exports = { + env: { + test: { + presets: ['@babel/preset-env', '@babel/preset-react'], + }, + }, +}; diff --git a/packages/design-system/jest.config.js b/packages/design-system/jest.config.js new file mode 100644 index 00000000..95206c30 --- /dev/null +++ b/packages/design-system/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + transformIgnorePatterns: ['SelectTimezone'], +}; diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 5c67dc4d..c53eaa23 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -24,18 +24,20 @@ "react": ">=16" }, "dependencies": { - "@types/react": "17.0.5", - "@types/react-dom": "17.0.5", - "@types/react-select": "3.0.22", "@chakra-ui/icons": "1.0.13", "@chakra-ui/react": "1.6.1", "@chakra-ui/theme-tools": "1.1.7", "@emotion/react": "11.4.0", "@emotion/styled": "11.3.0", - "framer-motion": "4.1.16", + "@types/react": "17.0.5", + "@types/react-dom": "17.0.5", + "@types/react-select": "3.0.22", + "framer-motion": "4.1.17", "next": "10.2.0", "react-select": "4.3.1", - "react-timezone-select": "0.9.8", + "react-timezone-select": "1.0.3", + "spacetime": "6.16.1", + "spacetime-informal": "0.6.1", "storybook-addon-performance": "0.15.2" }, "devDependencies": { diff --git a/packages/design-system/src/MetaButton.tsx b/packages/design-system/src/MetaButton.tsx index 8ae8e36a..255d16bb 100644 --- a/packages/design-system/src/MetaButton.tsx +++ b/packages/design-system/src/MetaButton.tsx @@ -14,6 +14,7 @@ export const MetaButton: React.FC< letterSpacing="0.1em" size="lg" fontSize="sm" + bg="purple.400" ref={ref} {...props} > diff --git a/packages/design-system/src/MetaSelect.tsx b/packages/design-system/src/MetaSelect.tsx new file mode 100644 index 00000000..aadb4741 --- /dev/null +++ b/packages/design-system/src/MetaSelect.tsx @@ -0,0 +1,19 @@ +import { Select, SelectProps } from '@chakra-ui/react'; +import React from 'react'; + +import { DropDownIcon } from './icons/DropDownIcon'; + +export const MetaSelect: React.FC = (props) => ( + setSearch(e.target.value)} + size="lg" + borderRadius="0" + borderColor="purple.400" + fontSize="md" + borderWidth="2px" + /> + + SEARCH + + + + + + + + + + Show + + + setQueryVariable('limit', Number(e.target.value)) + } + minW="3rem" + > + + + + + + + + + + + Player Type + + + setQueryVariable('playerType', e.target.value) + } + > + + {aggregates.playerTypes && + aggregates.playerTypes.map(({ id, title }) => ( + + ))} + + + + + + + Skills + + + setQueryVariable('skillCategory', e.target.value) + } + > + + {aggregates.skillCategories && + aggregates.skillCategories.map(({ name }) => ( + + ))} + + + + + + + Availability + + + setQueryVariable('availability', e.target.value) + } + > + + + + + + + + + + + + + + Timezone + + setQueryVariable('timezone', e.target.value)} + > + + {TimezoneOptions.map((z: TimezoneType) => ( + + ))} + + + + + + {players && !fetching && ( + + + {players.length} players + + + )} + + + ); +}; diff --git a/packages/web/components/Player/PlayerList.tsx b/packages/web/components/Player/PlayerList.tsx new file mode 100644 index 00000000..60298ee4 --- /dev/null +++ b/packages/web/components/Player/PlayerList.tsx @@ -0,0 +1,23 @@ +import { SimpleGrid, Text } from '@metafam/ds'; +import { PlayerTile } from 'components/Player/PlayerTile'; +import { PlayerFragmentFragment } from 'graphql/autogen/types'; +import React from 'react'; + +type Props = { + players: PlayerFragmentFragment[]; +}; + +export const PlayerList: React.FC = ({ players }) => + players.length > 0 ? ( + + {players.map((p) => ( + + ))} + + ) : ( + No players found + ); diff --git a/packages/web/components/PlayerList.tsx b/packages/web/components/PlayerList.tsx deleted file mode 100644 index fca6b96c..00000000 --- a/packages/web/components/PlayerList.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { SimpleGrid } from '@metafam/ds'; -import { PlayerTile } from 'components/Player/PlayerTile'; -import { PlayerFragmentFragment } from 'graphql/autogen/types'; -import React from 'react'; - -type Props = { - players: PlayerFragmentFragment[]; -}; - -export const PlayerList: React.FC = ({ players }) => ( - - {players.map((p) => ( - - ))} - -); diff --git a/packages/web/components/Quest/QuestFilter.tsx b/packages/web/components/Quest/QuestFilter.tsx index f641c78b..9ee31086 100644 --- a/packages/web/components/Quest/QuestFilter.tsx +++ b/packages/web/components/Quest/QuestFilter.tsx @@ -1,7 +1,7 @@ import { Flex, MetaButton, - Select, + MetaSelect, Switch, Text, Wrap, @@ -43,7 +43,7 @@ export const QuestFilter: React.FC = ({ - + - + - + - + {myId && ( @@ -94,6 +94,8 @@ export const QuestFilter: React.FC = ({ size="md" colorScheme="cyan" variant="outline" + borderWidth="2px" + borderRadius="4px" px={4} onClick={() => setQueryVariable( @@ -107,13 +109,6 @@ export const QuestFilter: React.FC = ({ isChecked={ myId && queryVariables.created_by_player_id === myId } - onClick={(e) => { - setQueryVariable( - 'created_by_player_id', - queryVariables.created_by_player_id ? '' : myId, - ); - e.preventDefault(); - }} /> @@ -123,7 +118,9 @@ export const QuestFilter: React.FC = ({ {quests && ( - {quests.length} quests + + {quests.length} quests + )} diff --git a/packages/web/graphql/client.ts b/packages/web/graphql/client.ts index e001b361..94241a49 100644 --- a/packages/web/graphql/client.ts +++ b/packages/web/graphql/client.ts @@ -23,18 +23,14 @@ const errorHasResponseTimeout = (err: CombinedError): boolean => err.graphQLErrors.length > 0 && !!err.graphQLErrors.find((_err) => _err.message === 'ResponseTimeout'); +const retryExchangeFunc = retryExchange({ + retryIf: (error) => !!(errorHasResponseTimeout(error) || error.networkError), +}); + export const client = createClient({ url: CONFIG.graphqlURL, suspense: false, - exchanges: [ - dedupExchange, - cacheExchange, - retryExchange({ - retryIf: (error) => - !!(errorHasResponseTimeout(error) || error.networkError), - }), - fetchExchange, - ], + exchanges: [dedupExchange, cacheExchange, retryExchangeFunc, fetchExchange], }); export const getSsrClient = (): [Client, ReturnType] => { @@ -43,7 +39,13 @@ export const getSsrClient = (): [Client, ReturnType] => { const ssrClient = initUrqlClient( { url: CONFIG.graphqlURL, - exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange], + exchanges: [ + dedupExchange, + cacheExchange, + ssrCache, + retryExchangeFunc, + fetchExchange, + ], }, false, ); diff --git a/packages/web/graphql/getPlayers.ts b/packages/web/graphql/getPlayers.ts index a952fbd9..20c9b5ee 100644 --- a/packages/web/graphql/getPlayers.ts +++ b/packages/web/graphql/getPlayers.ts @@ -1,77 +1,92 @@ import gql from 'fake-tag'; +import { Client } from 'urql'; import { + GetPlayersDocument, GetPlayersQuery, GetPlayersQueryVariables, GetPlayerUsernamesQuery, GetPlayerUsernamesQueryVariables, PlayerFragmentFragment, } from './autogen/types'; -import { client } from './client'; +import { client as defaultClient } from './client'; import { PlayerFragment } from './fragments'; -const playersQuery = gql` - query GetPlayers($limit: Int, $offset: Int) { - player(order_by: { total_xp: desc }, limit: $limit, offset: $offset) { +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +gql` + query GetPlayers( + $offset: Int + $limit: Int + $skillCategory: SkillCategory_enum + $playerType: Int + $availability: Int + $timezone: String + $search: String + ) { + player( + order_by: { total_xp: desc } + offset: $offset + limit: $limit + where: { + Player_Skills: { Skill: { category: { _eq: $skillCategory } } } + playerType: { id: { _eq: $playerType } } + availability_hours: { _gte: $availability } + timezone: { _eq: $timezone } + _or: [ + { username: { _ilike: $search } } + { ethereum_address: { _ilike: $search } } + ] + } + ) { ...PlayerFragment } } ${PlayerFragment} `; -export const getPlayers = async ( - limit = 50, - offset = 0, -): Promise => { - const { data, error } = await client - .query(playersQuery, { - limit, - offset, - }) - .toPromise(); - - if (!data) { - if (error) { - throw error; - } - - return []; - } - - return data.player; +export const defaultQueryVariables: GetPlayersQueryVariables = { + offset: 0, + limit: 50, + skillCategory: undefined, + playerType: undefined, + availability: 0, + timezone: undefined, + search: '%%', }; -const LIMIT = 50; -const TOTAL_PLAYERS = 150; +export type PlayersResponse = { + error: Error | undefined; + players: PlayerFragmentFragment[]; +}; -export const getTopPlayers = async (): Promise => { - const promises: Promise[] = new Array( - TOTAL_PLAYERS / LIMIT, - ) - .fill(false) - .map((_, i) => getPlayers(LIMIT, i * LIMIT)); - const playersArr = await Promise.all(promises); - return playersArr.reduce((_total, _players) => [..._total, ..._players], []); +export const getPlayers = async ( + queryVariables = defaultQueryVariables, + client: Client = defaultClient, +): Promise => { + const { data, error } = await client + .query( + GetPlayersDocument, + queryVariables, + ) + .toPromise(); + + return { players: data?.player || [], error }; }; const playerUsernamesQuery = gql` - query GetPlayerUsernames($limit: Int, $offset: Int) { - player(order_by: { total_xp: desc }, limit: $limit, offset: $offset) { + query GetPlayerUsernames($limit: Int) { + player(order_by: { total_xp: desc }, limit: $limit) { username } } `; -export const getPlayerUsernames = async ( - limit = 50, - offset = 0, -): Promise => { - const { data, error } = await client +export const getPlayerUsernames = async (limit = 150): Promise => { + const { data, error } = await defaultClient .query( playerUsernamesQuery, { limit, - offset, }, ) .toPromise(); @@ -87,10 +102,47 @@ export const getPlayerUsernames = async ( return data.player.map((p) => p.username); }; -export const getTopPlayerUsernames = async (): Promise => { - const promises: Promise[] = new Array(TOTAL_PLAYERS / LIMIT) +export const getTopPlayerUsernames = getPlayerUsernames; + +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +gql` + query GetPlayerFilters { + skill_aggregate(distinct_on: category) { + nodes { + name: category + } + } + player_type(distinct_on: id) { + id + title + } + } +`; + +export const getPlayersInParallel = async ( + variables: GetPlayersQueryVariables, +): Promise => { + const limit = 50; + const total = variables?.limit as number; + if (total <= limit) { + return getPlayers(variables); + } + const len = Math.ceil(total / limit); + const variablesArr: GetPlayersQueryVariables[] = new Array(len) .fill(false) - .map((_, i) => getPlayerUsernames(LIMIT, i * LIMIT)); - const playersArr = await Promise.all(promises); - return playersArr.reduce((_total, _players) => [..._total, ..._players], []); + .map((_, i) => ({ + ...variables, + offset: i * limit, + limit: i < len - 1 ? limit : total - limit * (len - 1), + })); + + const promises = variablesArr.map((vars) => getPlayers(vars)); + const playersRespArr = await Promise.all(promises); + return playersRespArr.reduce( + (totalRes, response) => ({ + error: totalRes.error || response.error, + players: [...totalRes.players, ...response.players], + }), + { error: undefined, players: [] }, + ); }; diff --git a/packages/web/graphql/getQuests.ts b/packages/web/graphql/getQuests.ts index ee2bcf78..976dc849 100644 --- a/packages/web/graphql/getQuests.ts +++ b/packages/web/graphql/getQuests.ts @@ -43,14 +43,6 @@ gql` ) { ...QuestFragment } - quest_aggregate(distinct_on: guild_id) { - nodes { - guild_id - guild { - name - } - } - } } ${QuestFragment} diff --git a/packages/web/lib/hooks/players.ts b/packages/web/lib/hooks/players.ts new file mode 100644 index 00000000..5744dbca --- /dev/null +++ b/packages/web/lib/hooks/players.ts @@ -0,0 +1,112 @@ +import { + GetPlayersQueryVariables, + PlayerFragmentFragment, + useGetPlayerFiltersQuery, + useGetPlayersQuery, +} from 'graphql/autogen/types'; +import { + defaultQueryVariables, + getPlayersInParallel, + PlayersResponse, +} from 'graphql/getPlayers'; +import { useCallback, useEffect, useState } from 'react'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type QueryVariableSetter = (key: string, value: any) => void; + +export interface PlayerAggregates { + skillCategories: { name: string }[]; + playerTypes: { id: number; title: string }[]; +} + +interface PlayerFilter { + players: PlayerFragmentFragment[]; + fetching: boolean; + aggregates: PlayerAggregates; + queryVariables: GetPlayersQueryVariables; + setQueryVariable: QueryVariableSetter; + error?: Error; +} + +const usePlayerAggregates = () => { + const [{ data }] = useGetPlayerFiltersQuery(); + return { + skillCategories: data?.skill_aggregate.nodes || [], + playerTypes: data?.player_type || [], + }; +}; + +const usePlayersSingle = ( + run: boolean, + variables: GetPlayersQueryVariables, +) => { + const [{ fetching, data, error }] = useGetPlayersQuery({ + variables, + pause: !run, + }); + const players = data?.player || []; + return { fetching, players, error }; +}; + +const usePlayersParallel = ( + run: boolean, + variables: GetPlayersQueryVariables, +) => { + const [fetching, setFetching] = useState(true); + const [{ players, error }, setResponse] = useState({ + error: undefined, + players: [], + }); + + useEffect(() => { + const load = async () => { + if (run) { + setFetching(true); + const response = await getPlayersInParallel(variables); + setResponse(response); + setFetching(false); + } + }; + load(); + }, [run, variables]); + + return { fetching, players, error }; +}; + +const useFilteredPlayers = (variables: GetPlayersQueryVariables) => { + const runParallel = (variables.limit as number) > 50; // if limit is 150 then hasura is unable to handle in one query + const playersParallel = usePlayersParallel(runParallel, variables); + const playersSingle = usePlayersSingle(!runParallel, variables); + return runParallel ? playersParallel : playersSingle; +}; + +export const usePlayerFilter = (): PlayerFilter => { + const [ + queryVariables, + setQueryVariables, + ] = useState(defaultQueryVariables); + + const aggregates = usePlayerAggregates(); + + const setQueryVariable: QueryVariableSetter = useCallback( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (key: string, value: any) => { + setQueryVariables((oldQueryVariables) => ({ + ...oldQueryVariables, + [key]: value !== '' ? value : null, + })); + }, + [], + ); + + const { fetching, players, error } = useFilteredPlayers(queryVariables); + + return { + players, + aggregates, + fetching, + error, + queryVariables, + setQueryVariable, + }; +}; diff --git a/packages/web/next.config.js b/packages/web/next.config.js index dbe80f4c..8dcbd47e 100644 --- a/packages/web/next.config.js +++ b/packages/web/next.config.js @@ -1,14 +1,17 @@ -// eslint-disable-next-line +/* eslint-disable @typescript-eslint/no-var-requires */ +const withTM = require('next-transpile-modules')(['react-timezone-select']); const withImages = require('next-images'); -module.exports = withImages({ - async redirects() { - return [ - { - source: '/', - destination: '/players', - permanent: false, - }, - ]; - }, -}); +module.exports = withTM( + withImages({ + async redirects() { + return [ + { + source: '/', + destination: '/players', + permanent: false, + }, + ]; + }, + }), +); diff --git a/packages/web/package.json b/packages/web/package.json index 01039054..a1cf43e0 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -25,6 +25,7 @@ "moment": "2.29.1", "next": "10.2.0", "next-images": "1.7.0", + "next-transpile-modules": "7.0.0", "next-urql": "3.1.0", "node-fetch": "2.6.1", "opensea-js": "1.1.11", @@ -33,9 +34,9 @@ "react-hook-form": "6.15.5", "react-icons": "4.2.0", "react-qr-svg": "2.3.0", - "spacetime": "6.16.0", - "spacetime-informal": "0.6.1", "urql": "2.0.2", - "web3modal": "1.9.3" + "web3modal": "1.9.3", + "spacetime": "6.16.1", + "spacetime-informal": "0.6.1" } } diff --git a/packages/web/pages/guilds.tsx b/packages/web/pages/guilds.tsx index 87102f10..ff1cd3d3 100644 --- a/packages/web/pages/guilds.tsx +++ b/packages/web/pages/guilds.tsx @@ -1,5 +1,5 @@ import { PageContainer } from 'components/Container'; -import { GuildList } from 'components/GuildList'; +import { GuildList } from 'components/Guild/GuildList'; import { getGuilds } from 'graphql/getGuilds'; import { InferGetStaticPropsType } from 'next'; import React from 'react'; diff --git a/packages/web/pages/patrons.tsx b/packages/web/pages/patrons.tsx index 9302fe8d..9730ad4c 100644 --- a/packages/web/pages/patrons.tsx +++ b/packages/web/pages/patrons.tsx @@ -1,5 +1,5 @@ import { PageContainer } from 'components/Container'; -import { PatronList } from 'components/PatronList'; +import { PatronList } from 'components/Patron/PatronList'; import { getPatrons } from 'graphql/getPatrons'; import { InferGetStaticPropsType } from 'next'; import React from 'react'; diff --git a/packages/web/pages/players.tsx b/packages/web/pages/players.tsx index dd7599a1..7bf6df3b 100644 --- a/packages/web/pages/players.tsx +++ b/packages/web/pages/players.tsx @@ -1,25 +1,52 @@ +import { LoadingState, Text, VStack } from '@metafam/ds'; import { PageContainer } from 'components/Container'; -import { PlayerList } from 'components/PlayerList'; -import { getTopPlayers } from 'graphql/getPlayers'; +import { PlayerFilter } from 'components/Player/PlayerFilter'; +import { PlayerList } from 'components/Player/PlayerList'; +import { getSsrClient } from 'graphql/client'; +import { getPlayers } from 'graphql/getPlayers'; +import { usePlayerFilter } from 'lib/hooks/players'; import { InferGetStaticPropsType } from 'next'; import React from 'react'; type Props = InferGetStaticPropsType; export const getStaticProps = async () => { - const players = await getTopPlayers(); + const [ssrClient, ssrCache] = getSsrClient(); + // This populate the cache server-side + await getPlayers(undefined, ssrClient); return { props: { - players, + urqlState: ssrCache.extractData(), }, revalidate: 1, }; }; -const Players: React.FC = ({ players }) => ( - - - -); +const Players: React.FC = () => { + const { + players, + aggregates, + fetching, + error, + queryVariables, + setQueryVariable, + } = usePlayerFilter(); + return ( + + + + {error && {`Error: ${error.message}`}} + {fetching && } + {players && !fetching && !error && } + + + ); +}; export default Players; diff --git a/packages/web/pages/quests.tsx b/packages/web/pages/quests.tsx index 0c4f727c..762aa2b7 100644 --- a/packages/web/pages/quests.tsx +++ b/packages/web/pages/quests.tsx @@ -10,15 +10,14 @@ import { import { PageContainer } from 'components/Container'; import { QuestFilter } from 'components/Quest/QuestFilter'; import { QuestList } from 'components/Quest/QuestList'; +import { getSsrClient } from 'graphql/client'; import { getQuests } from 'graphql/getQuests'; +import { usePSeedBalance } from 'lib/hooks/balances'; +import { useQuestFilter } from 'lib/hooks/quests'; import { InferGetStaticPropsType } from 'next'; import { useRouter } from 'next/router'; import React, { useMemo } from 'react'; - -import { getSsrClient } from '../graphql/client'; -import { usePSeedBalance } from '../lib/hooks/balances'; -import { useQuestFilter } from '../lib/hooks/quests'; -import { isAllowedToCreateQuest } from '../utils/questHelpers'; +import { isAllowedToCreateQuest } from 'utils/questHelpers'; type Props = InferGetStaticPropsType; diff --git a/yarn.lock b/yarn.lock index 50f1ee7c..77471622 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2026,7 +2026,7 @@ source-map "^0.5.7" stylis "^4.0.3" -"@emotion/cache@^10.0.27", "@emotion/cache@^10.0.9": +"@emotion/cache@^10.0.27": version "10.0.29" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== @@ -2047,7 +2047,7 @@ "@emotion/weak-memoize" "^0.2.5" stylis "^4.0.3" -"@emotion/core@^10.0.9", "@emotion/core@^10.1.1": +"@emotion/core@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA== @@ -2059,7 +2059,7 @@ "@emotion/sheet" "0.9.4" "@emotion/utils" "0.11.3" -"@emotion/css@^10.0.27", "@emotion/css@^10.0.9": +"@emotion/css@^10.0.27": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== @@ -12009,6 +12009,14 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.5.0: memory-fs "^0.5.0" tapable "^1.0.0" +enhanced-resolve@^5.7.0: + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.4, enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -13804,10 +13812,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -framer-motion@4.1.16: - version "4.1.16" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.16.tgz#dc715334847d0a146acf47f61019222d0d1c46c9" - integrity sha512-sEc3UI3oncwE+RUzdd86TxbmpEaX/Ki/T0AmFYSsbxEqGZ3feLvzGL7BJlkhERIyyuAC9+OzI4BnhJM0GSUAMA== +framer-motion@4.1.17: + version "4.1.17" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.17.tgz#4029469252a62ea599902e5a92b537120cc89721" + integrity sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw== dependencies: framesync "5.3.0" hey-listen "^1.0.8" @@ -20658,6 +20666,14 @@ next-tick@~1.0.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= +next-transpile-modules@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-7.0.0.tgz#5a48988cede89bc5920defb15378093d0d8562eb" + integrity sha512-HgVczU5ajXKvE7HO3ZLmBmxXj79aq8jSZNYpCttim+MZ+b0GIsdk7AV2w7Ax/tIM1/dJA+vV/6loXCRYlbsGGA== + dependencies: + enhanced-resolve "^5.7.0" + escalade "^3.1.1" + next-urql@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/next-urql/-/next-urql-3.1.0.tgz#9c354cfd54cdf886988a2cb1ea0fd89f48ee7555" @@ -23613,7 +23629,7 @@ react-router@5.2.0, react-router@^5.1.0, react-router@^5.2.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-select@4.3.1: +react-select@4.3.1, react-select@^4.2.1: version "4.3.1" resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81" integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q== @@ -23626,20 +23642,6 @@ react-select@4.3.1: react-input-autosize "^3.0.0" react-transition-group "^4.3.0" -react-select@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.2.0.tgz#de9284700196f5f9b5277c5d850a9ce85f5c72fe" - integrity sha512-B/q3TnCZXEKItO0fFN/I0tWOX3WJvi/X2wtdffmwSQVRwg5BpValScTO1vdic9AxlUgmeSzib2hAZAwIUQUZGQ== - dependencies: - "@babel/runtime" "^7.4.4" - "@emotion/cache" "^10.0.9" - "@emotion/core" "^10.0.9" - "@emotion/css" "^10.0.9" - memoize-one "^5.0.0" - prop-types "^15.6.0" - react-input-autosize "^3.0.0" - react-transition-group "^4.3.0" - react-sizeme@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-3.0.1.tgz#4d12f4244e0e6a0fb97253e7af0314dc7c83a5a0" @@ -23684,14 +23686,14 @@ react-textarea-autosize@^8.3.0: use-composed-ref "^1.0.0" use-latest "^1.0.0" -react-timezone-select@0.9.8: - version "0.9.8" - resolved "https://registry.yarnpkg.com/react-timezone-select/-/react-timezone-select-0.9.8.tgz#a5d9ead1fa0b40dab1b3a77d9cdcc20354fe2ec4" - integrity sha512-CzIOs9IwAb5hmjs5jnB1uShQvw9zJGUVeH5dIpRVy1dgVnwkasvXc2fGwnggI6nYXAmN7uOCt5kFIcQOpZmUNw== +react-timezone-select@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/react-timezone-select/-/react-timezone-select-1.0.3.tgz#e257f7204c8ee74c30ab033f34a1d2d3a45963b9" + integrity sha512-wpsu2jhEkn+/G91m24oqSlT/iAmcE4pQot9tOTUcV9kI+uA1kc+0YpvJFL5aT2jMVJ/uwpQkxUWAhRwa8U9YKg== dependencies: - react-select "^3.1.0" - spacetime "^6.6.2" - spacetime-informal "^0.3.0" + react-select "^4.2.1" + spacetime "^6.14.0" + spacetime-informal "^0.6.1" react-transition-group@^4.3.0, react-transition-group@^4.4.0, react-transition-group@^4.4.1: version "4.4.1" @@ -25409,22 +25411,17 @@ space-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== -spacetime-informal@0.6.1: +spacetime-informal@0.6.1, spacetime-informal@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/spacetime-informal/-/spacetime-informal-0.6.1.tgz#621b4156a98f20f5c3f0151475d2ea886e1c19c1" integrity sha512-fOA+RMi2mpCbkLkjBIzWQttmkYE/v9VfdbbrvE2Pus/WoiQNmHO20YGNEqJOuFADsrrZOd/hJVuBwAkV3s6BHg== dependencies: efrt-unpack "2.2.0" -spacetime-informal@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/spacetime-informal/-/spacetime-informal-0.3.0.tgz#6d0feffe291697f686b737b678b59ee2dcef3297" - integrity sha512-HtFTwtkzDl7gswCfeWPQAxvQ+Fmrdt7WqoDT0Lq2FX7RVZKZ/+zmgBOAVAuH8oVcf4uXza9NvdX9QppGRiG8oQ== - -spacetime@6.16.0, spacetime@^6.6.2: - version "6.16.0" - resolved "https://registry.yarnpkg.com/spacetime/-/spacetime-6.16.0.tgz#f213963392eafc380716c3857b23251de87db97f" - integrity sha512-mkuniNOp6ssfPyJidj81tb54zKxK4vEKPTmcUsC/NEGIF8S07ppoSotdg6numT1/26rthQYmdxMY/M5a9WeJVQ== +spacetime@6.16.1, spacetime@^6.14.0: + version "6.16.1" + resolved "https://registry.yarnpkg.com/spacetime/-/spacetime-6.16.1.tgz#e032dc77bea494367a7a321a03458ebbf8f625b0" + integrity sha512-+aK5oTrCCfXZsg73NEoy3V2cLa0xY3obddFNbWSJ8UcbuPb7f8zWOV4vH3hEAncznUJQqA7tGHAuVR4TysfgIA== sparse-array@^1.3.1: version "1.3.2" @@ -26171,6 +26168,11 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + tape@^4.4.0, tape@^4.6.3: version "4.13.3" resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278"