From 42bff4ee3a51c2da3171e91ef4b3807d5ba9874a Mon Sep 17 00:00:00 2001 From: Kichiyaki Date: Mon, 28 Dec 2020 19:54:37 +0100 Subject: [PATCH] [WIP]: /server/:key/war-stats - add DateTimePicker - add some basic logic to the WarStatsPage --- package.json | 2 + src/common/Picker/DateTimePicker.tsx | 42 ++++++ src/config/app.ts | 1 + src/config/namespaces.ts | 1 + src/config/routes.ts | 1 + src/features/ServerPage/ServerPage.tsx | 4 + .../ServerPage/features/MapPage/MapPage.tsx | 24 ++-- .../ServerPage/features/MapPage/helpers.ts | 3 - .../ServerPage/features/MapPage/types.ts | 3 + .../ServerPage/features/MapPage/useMarkers.ts | 46 +++--- .../features/WarStatsPage/WarStatsPage.tsx | 133 +++++++++++++++++ .../WarStatsPage/components/Card/Card.tsx | 19 +++ .../features/WarStatsPage/queries.ts | 47 ++++++ .../ServerPage/features/WarStatsPage/types.ts | 19 +++ .../features/WarStatsPage/useSide.ts | 135 ++++++++++++++++++ src/index.tsx | 21 ++- src/libs/date/locales.ts | 9 +- src/theme/createTheme.ts | 30 +--- yarn.lock | 44 +++++- 19 files changed, 513 insertions(+), 71 deletions(-) create mode 100644 src/common/Picker/DateTimePicker.tsx delete mode 100644 src/features/ServerPage/features/MapPage/helpers.ts create mode 100644 src/features/ServerPage/features/WarStatsPage/WarStatsPage.tsx create mode 100644 src/features/ServerPage/features/WarStatsPage/components/Card/Card.tsx create mode 100644 src/features/ServerPage/features/WarStatsPage/queries.ts create mode 100644 src/features/ServerPage/features/WarStatsPage/types.ts create mode 100644 src/features/ServerPage/features/WarStatsPage/useSide.ts diff --git a/package.json b/package.json index 0edc73b..efa6c92 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "private": true, "dependencies": { "@apollo/client": "^3.2.5", + "@date-io/date-fns": "1.3.13", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.11.0", "@material-ui/lab": "^4.0.0-alpha.57", + "@material-ui/pickers": "3.2.10", "@nivo/core": "0.64.0", "@nivo/line": "0.64.0", "@testing-library/jest-dom": "^5.11.4", diff --git a/src/common/Picker/DateTimePicker.tsx b/src/common/Picker/DateTimePicker.tsx new file mode 100644 index 0000000..5472f90 --- /dev/null +++ b/src/common/Picker/DateTimePicker.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import clsx from 'clsx'; +import { + DateTimePicker as MUIDateTimePicker, + DateTimePickerProps, +} from '@material-ui/pickers'; +import { makeStyles } from '@material-ui/core/styles'; + +function DateTimePicker({ + className, + ampm = false, + ...props +}: DateTimePickerProps) { + const classes = useStyles(); + return ( + + ); +} + +const useStyles = makeStyles(theme => ({ + dialog: { + '& .MuiTabs-indicator': { + backgroundColor: theme.palette.secondary.main, + }, + '& .MuiPickersDay-daySelected': { + backgroundColor: theme.palette.secondary.main, + color: theme.palette.secondary.contrastText, + }, + '& .MuiPickersDay-current': { + color: theme.palette.secondary.main, + }, + '& .MuiDialogActions-root .MuiButton-root': { + color: theme.palette.secondary.contrastText, + }, + }, +})); + +export default DateTimePicker; diff --git a/src/config/app.ts b/src/config/app.ts index 8910572..ebbb3da 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -21,6 +21,7 @@ export const TRACKING_CODE = process.env.REACT_APP_TRACKING_CODE ?? ''; export const DATE_FORMAT = { MONTH_AND_YEAR: 'yyyy-MM', + HOUR_AND_SECOND: 'HH:mm', DAY_MONTH_AND_YEAR: 'yyyy-MM-dd', HOUR_MINUTES_DAY_MONTH_AND_YEAR: 'yyyy-MM-dd HH:mm', HOUR_MINUTES_SECONDS_DAY_MONTH_AND_YEAR: 'yyyy-MM-dd HH:mm:ss', diff --git a/src/config/namespaces.ts b/src/config/namespaces.ts index 6986526..e519049 100644 --- a/src/config/namespaces.ts +++ b/src/config/namespaces.ts @@ -9,6 +9,7 @@ export const SERVER_PAGE = { INDEX_PAGE: 'server-page/index-page', MAP_PAGE: 'server-page/map-page', ENNOBLEMENTS_PAGE: 'server-page/ennoblements-page', + WAR_STATS_PAGE: 'server-page/war-stats-page', PLAYER_PAGE: { COMMON: 'server-page/player-page/common', INDEX_PAGE: 'server-page/player-page/index-page', diff --git a/src/config/routes.ts b/src/config/routes.ts index 80bc4a9..f739452 100644 --- a/src/config/routes.ts +++ b/src/config/routes.ts @@ -37,4 +37,5 @@ export const SERVER_PAGE = { }, ENNOBLEMENTS_PAGE: '/server/:key/ennoblements', MAP_PAGE: '/server/:key/map', + WAR_STATS_PAGE: '/server/:key/war-stats' }; diff --git a/src/features/ServerPage/ServerPage.tsx b/src/features/ServerPage/ServerPage.tsx index 66ccf3a..189c990 100644 --- a/src/features/ServerPage/ServerPage.tsx +++ b/src/features/ServerPage/ServerPage.tsx @@ -10,6 +10,7 @@ import VillagePage from './features/VillagePage/VillagePage'; import RankingPage from './features/RankingPage/RankingPage'; import MapPage from './features/MapPage/MapPage'; import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage'; +import WarStatsPage from './features/WarStatsPage/WarStatsPage'; import NotFoundPage from './features/NotFoundPage/NotFoundPage'; function ServerPage() { @@ -37,6 +38,9 @@ function ServerPage() { + + + diff --git a/src/features/ServerPage/features/MapPage/MapPage.tsx b/src/features/ServerPage/features/MapPage/MapPage.tsx index 253d53a..7b7f1de 100644 --- a/src/features/ServerPage/features/MapPage/MapPage.tsx +++ b/src/features/ServerPage/features/MapPage/MapPage.tsx @@ -11,7 +11,6 @@ import useTitle from '@libs/useTitle'; import useServer from '../../libs/ServerContext/useServer'; import useMarkers from './useMarkers'; import ColorParam from '@libs/serialize-query-params/ColorParam'; -import { encodeMarker } from './helpers'; import { MAP_SERVICE } from '@config/app'; import { SERVER_PAGE } from '@config/namespaces'; import { PLAYERS, TRIBES } from './queries'; @@ -88,18 +87,6 @@ function MapPage() { const { t } = useTranslation(SERVER_PAGE.MAP_PAGE); useTitle(t('title', { key })); const loading = loadingTribeMarkers || loadingPlayerMarkers; - const centerFlex = { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - }; - let serverPageLayoutProps: ServerPageLayoutProps = loading - ? { - noPadding: true, - contentStyle: centerFlex as React.CSSProperties, - } - : {}; const createSettingsChangeHandler = (key: keyof Settings) => ( e: React.ChangeEvent, @@ -158,6 +145,10 @@ function MapPage() { } }; + const encodeMarker = (id: number, color: string): string => { + return encodeURIComponent(id + ',' + color); + }; + const handleSubmit = (e: React.FormEvent<{}>) => { e.preventDefault(); @@ -189,11 +180,14 @@ function MapPage() { option && value ? option.name === value.name : false; return ( - + {loading && ( { - return encodeURIComponent(id + ',' + color); -}; diff --git a/src/features/ServerPage/features/MapPage/types.ts b/src/features/ServerPage/features/MapPage/types.ts index 1285915..a0dc68b 100644 --- a/src/features/ServerPage/features/MapPage/types.ts +++ b/src/features/ServerPage/features/MapPage/types.ts @@ -4,13 +4,16 @@ export type Tribe = { id: number; tag: string; }; + export type TribeList = { tribes?: List; }; + export type Player = { id: number; name: string; }; + export type PlayerList = { players?: List; }; diff --git a/src/features/ServerPage/features/MapPage/useMarkers.ts b/src/features/ServerPage/features/MapPage/useMarkers.ts index f146e68..e580f06 100644 --- a/src/features/ServerPage/features/MapPage/useMarkers.ts +++ b/src/features/ServerPage/features/MapPage/useMarkers.ts @@ -45,7 +45,7 @@ const useMarkers = ( const [markers, setMarkers] = useState[]>([]); useEffect(() => { - const markers: { [key: number]: string } = {}; + const colorByID: { [key: number]: string } = {}; query[opts.paramName].forEach((rawStr: string | null) => { if (!rawStr) { return; @@ -62,34 +62,38 @@ const useMarkers = ( return; } - markers[idInt] = color; + colorByID[idInt] = color; }); - const ids = Object.keys(markers).map(id => parseInt(id, 10)); + const ids = Object.keys(colorByID).map(id => parseInt(id, 10)); if (ids.length > 0) { - client - .query>, VariablesT>({ - query: opts.query, - variables: opts.getVariables(ids), - fetchPolicy: 'network-only', - }) - .then(res => { - if (opts.dataKey in res.data && res.data[opts.dataKey]) { - setMarkers( - res.data[opts.dataKey].items.map(item => { - return getNewMarker(item, markers[item.id]); - }) - ); - } - }) - .finally(() => { - setLoading(false); - }); + loadMarkers(ids, colorByID); } else { setLoading(false); } // eslint-disable-next-line }, []); + const loadMarkers = (ids: number[], colorByID: { [key: number]: string }) => { + return client + .query>, VariablesT>({ + query: opts.query, + variables: opts.getVariables(ids), + fetchPolicy: 'network-only', + }) + .then(res => { + if (opts.dataKey in res.data && res.data[opts.dataKey]) { + setMarkers( + res.data[opts.dataKey].items.map(item => { + return getNewMarker(item, colorByID[item.id]); + }) + ); + } + }) + .finally(() => { + setLoading(false); + }); + }; + const getNewMarker = ( item: T | null = null, color: string = '#000000' diff --git a/src/features/ServerPage/features/WarStatsPage/WarStatsPage.tsx b/src/features/ServerPage/features/WarStatsPage/WarStatsPage.tsx new file mode 100644 index 0000000..c4813c1 --- /dev/null +++ b/src/features/ServerPage/features/WarStatsPage/WarStatsPage.tsx @@ -0,0 +1,133 @@ +import React, { useRef } from 'react'; +import { subDays } from 'date-fns'; +import { useQueryParams, DateTimeParam, withDefault } from 'use-query-params'; +import { useTranslation } from 'react-i18next'; +import useTitle from '@libs/useTitle'; +import useServer from '../../libs/ServerContext/useServer'; +import useSide from './useSide'; +import { SERVER_PAGE } from '@config/namespaces'; + +import { makeStyles } from '@material-ui/core/styles'; +import { Container, Grid, Typography, TextField } from '@material-ui/core'; +import DateTimePicker from '@common/Picker/DateTimePicker'; +import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; +import Spinner from '@common/Spinner/Spinner'; +import Card from './components/Card/Card'; + +function WarStatsPage() { + const now = useRef(new Date()); + const [query, setQuery] = useQueryParams({ + ennobledAtGTE: withDefault(DateTimeParam, subDays(now.current, 1)), + ennobledAtLTE: withDefault(DateTimeParam, now.current), + }); + const classes = useStyles(); + const server = useServer(); + const { t } = useTranslation(SERVER_PAGE.WAR_STATS_PAGE); + useTitle(t('title', { key: server.key })); + const { + players: sideOnePlayers, + tribes: sideOneTribes, + loading: sideOneLoading, + handleChangePlayers: sideOneHandleChangePlayers, + handleChangeTribes: sideOneHandleChangeTribes, + } = useSide(server.key, { paramNamePrefix: 'sideOne' }); + const { + players: sideTwoPlayers, + tribes: sideTwoTribes, + loading: sideTwoLoading, + handleChangePlayers: sideTwoHandleChangePlayers, + handleChangeTribes: sideTwoHandleChangeTribes, + } = useSide(server.key, { paramNamePrefix: 'sideTwo' }); + const loading = true; + + return ( + + {loading && ( + + )} + {!loading && ( + +
+ + + + {t('sections.settings')} + +
+ {[ + { + name: 'ennobledAtGTE', + val: query.ennobledAtGTE, + maxDate: query.ennobledAtLTE, + }, + { + name: 'ennobledAtLTE', + val: query.ennobledAtLTE, + minDate: query.ennobledAtGTE, + }, + ].map(({ name, val, maxDate, minDate }) => { + return ( + { + return ( + + ); + }} + label={t('inputLabels.' + name)} + value={val} + format="yyyy/MM/dd HH:mm" + onChange={d => { + setQuery({ [name]: d ? d : undefined }); + }} + /> + ); + })} +
+
+ + + {t('sections.sideOne')} + + + + + {t('sections.sideTwo')} + + +
+
+
+ )} +
+ ); +} + +const useStyles = makeStyles(theme => ({ + formGroup: { + '& > *': { + marginBottom: theme.spacing(1), + }, + }, +})); + +export default WarStatsPage; diff --git a/src/features/ServerPage/features/WarStatsPage/components/Card/Card.tsx b/src/features/ServerPage/features/WarStatsPage/components/Card/Card.tsx new file mode 100644 index 0000000..a350bd3 --- /dev/null +++ b/src/features/ServerPage/features/WarStatsPage/components/Card/Card.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import { Grid, Card as MUICard, CardContent } from '@material-ui/core'; + +export interface Props { + children?: React.ReactNode; +} + +const Card = ({ children }: Props) => { + return ( + + + {children} + + + ); +}; + +export default Card; diff --git a/src/features/ServerPage/features/WarStatsPage/queries.ts b/src/features/ServerPage/features/WarStatsPage/queries.ts new file mode 100644 index 0000000..8f33ac9 --- /dev/null +++ b/src/features/ServerPage/features/WarStatsPage/queries.ts @@ -0,0 +1,47 @@ +import { gql } from '@apollo/client'; + +export const PLAYERS = gql` + query players( + $server: String! + $filter: PlayerFilter! + $limit: Int + $offset: Int + $sort: [String!] + ) { + players( + server: $server + filter: $filter + limit: $limit + offset: $offset + sort: $sort + ) { + items { + id + name + } + } + } +`; + +export const TRIBES = gql` + query tribes( + $server: String! + $filter: TribeFilter! + $limit: Int + $offset: Int + $sort: [String!] + ) { + tribes( + server: $server + filter: $filter + limit: $limit + offset: $offset + sort: $sort + ) { + items { + id + tag + } + } + } +`; diff --git a/src/features/ServerPage/features/WarStatsPage/types.ts b/src/features/ServerPage/features/WarStatsPage/types.ts new file mode 100644 index 0000000..104254b --- /dev/null +++ b/src/features/ServerPage/features/WarStatsPage/types.ts @@ -0,0 +1,19 @@ +import { List } from '@libs/graphql/types'; + +export type Tribe = { + id: number; + tag: string; +}; + +export type TribeList = { + tribes?: List; +}; + +export type Player = { + id: number; + name: string; +}; + +export type PlayerList = { + players?: List; +}; diff --git a/src/features/ServerPage/features/WarStatsPage/useSide.ts b/src/features/ServerPage/features/WarStatsPage/useSide.ts new file mode 100644 index 0000000..1ac93cb --- /dev/null +++ b/src/features/ServerPage/features/WarStatsPage/useSide.ts @@ -0,0 +1,135 @@ +import { useState, useEffect } from 'react'; +import { useApolloClient, DocumentNode } from '@apollo/client'; +import { + useQueryParams, + NumericArrayParam, + withDefault, +} from 'use-query-params'; +import { PLAYERS, TRIBES } from './queries'; +import { + PlayersQueryVariables, + TribesQueryVariables, +} from '@libs/graphql/types'; +import { Player, Tribe, PlayerList, TribeList } from './types'; + +const getParamName = ( + type: 'player' | 'tribe', + paramNamePrefix: string +): string => { + return type === 'player' + ? `${paramNamePrefix}Player` + : `${paramNamePrefix}Tribe`; +}; + +export type Options = { + paramNamePrefix: string; +}; + +interface HasID { + id: number; +} + +export type Bag = { + players: Player[]; + tribes: Tribe[]; + loading: boolean; + handleChangePlayers: (_e: React.ChangeEvent<{}>, players: Player[]) => void; + handleChangeTribes: (_e: React.ChangeEvent<{}>, tribes: Tribe[]) => void; +}; + +const useSide = (server: string, opts: Options): Bag => { + const [loading, setLoading] = useState(true); + const [players, setPlayers] = useState([]); + const [tribes, setTribes] = useState([]); + const paramNamePlayer = getParamName('player', opts.paramNamePrefix); + const paramNameTribe = getParamName('tribe', opts.paramNamePrefix); + const [query, setQuery] = useQueryParams({ + [paramNamePlayer]: withDefault(NumericArrayParam, []), + [paramNameTribe]: withDefault(NumericArrayParam, []), + }); + const client = useApolloClient(); + + useEffect(() => { + const validPlayerIDs = query[paramNamePlayer].filter( + val => val && val > 0 + ) as number[]; + const validTribeIDs = query[paramNameTribe].filter( + val => val && val > 0 + ) as number[]; + const promises: Promise[] = []; + + if (validPlayerIDs.length > 0) { + promises.push( + loadData(PLAYERS, { + server, + filter: { exists: true, id: validPlayerIDs }, + }) + ); + } + if (validTribeIDs.length > 0) { + promises.push( + loadData(TRIBES, { + server, + filter: { exists: true, id: validTribeIDs }, + }) + ); + } + Promise.all(promises).finally(() => { + setLoading(false); + }); // eslint-disable-next-line + }, []); + + const loadData = ( + query: DocumentNode, + variables: PlayersQueryVariables | TribesQueryVariables + ) => { + return client + .query< + PlayerList | TribeList, + PlayersQueryVariables | TribesQueryVariables + >({ + query, + variables, + fetchPolicy: 'network-only', + }) + .then(res => { + if ('players' in res.data && res.data.players) { + setPlayers(res.data.players.items); + } + if ('tribes' in res.data && res.data.tribes) { + setTribes(res.data.tribes.items); + } + }); + }; + + const getIDs = (arr: HasID[]) => { + return arr.map(({ id }) => id); + }; + + const updateQueryParams = (key: string, ids: number[]) => { + setQuery({ [key]: ids }); + }; + + const handleChangePlayers = ( + _e: React.ChangeEvent<{}>, + players: Player[] + ) => { + setPlayers(players); + updateQueryParams(paramNamePlayer, getIDs(players)); + }; + + const handleChangeTribes = (_e: React.ChangeEvent<{}>, tribes: Tribe[]) => { + setTribes(tribes); + updateQueryParams(paramNameTribe, getIDs(tribes)); + }; + + return { + players, + tribes, + loading, + handleChangePlayers, + handleChangeTribes, + }; +}; + +export default useSide; diff --git a/src/index.tsx b/src/index.tsx index c081a89..0f168ad 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,22 +4,37 @@ import { ThemeProvider } from '@material-ui/styles'; import { ApolloProvider } from '@apollo/client'; import { BrowserRouter, Route } from 'react-router-dom'; import { I18nextProvider } from 'react-i18next'; +import { MuiPickersUtilsProvider } from '@material-ui/pickers'; import { QueryParamProvider } from 'use-query-params'; +import DateFnsUtils from '@date-io/date-fns'; import App from './features/App'; import createTheme from './theme/createTheme'; import createGraphQLClient from './libs/graphql/createClient'; import initI18N from './libs/i18n/init'; +import locales, { Locale } from './libs/date/locales'; +import extractVersionCodeFromHostname from './utils/extractVersionCodeFromHostname'; import { URI as API_URI } from './config/api'; +import { DEFAULT_LANGUAGE } from './config/app'; import reportWebVitals from './reportWebVitals'; +const version = extractVersionCodeFromHostname(); const jsx = ( - - - + + + + + diff --git a/src/libs/date/locales.ts b/src/libs/date/locales.ts index 9844a48..2a410ca 100644 --- a/src/libs/date/locales.ts +++ b/src/libs/date/locales.ts @@ -1,9 +1,14 @@ +import { Locale as DFLocale } from 'date-fns'; import pl from 'date-fns/locale/pl'; import enGB from 'date-fns/locale/en-GB'; -export type Locale = 'pl' | 'en'; +export type Locales = { + pl: DFLocale; + en: DFLocale; +}; +export type Locale = keyof Locales; -const locales = { +const locales: Locales = { pl, en: enGB, }; diff --git a/src/theme/createTheme.ts b/src/theme/createTheme.ts index 6f215f3..26e31c2 100644 --- a/src/theme/createTheme.ts +++ b/src/theme/createTheme.ts @@ -6,8 +6,6 @@ import { } from '@material-ui/core/styles'; const createTheme = (): Theme => { - const defaultTheme = createMuiTheme(); - return responsiveFontSizes( createMuiTheme({ palette: { @@ -29,30 +27,14 @@ const createTheme = (): Theme => { color: 'secondary', underline: 'none', }, + MuiInput: { + color: 'secondary', + }, + MuiInputLabel: { + color: 'secondary', + }, }, overrides: { - MuiTooltip: { - tooltipPlacementTop: { - [defaultTheme.breakpoints.down('xs')]: { - margin: defaultTheme.spacing(2, 0), - }, - }, - tooltipPlacementBottom: { - [defaultTheme.breakpoints.down('xs')]: { - margin: defaultTheme.spacing(2, 0), - }, - }, - tooltipPlacementLeft: { - [defaultTheme.breakpoints.down('xs')]: { - margin: defaultTheme.spacing(2, 0), - }, - }, - tooltipPlacementRight: { - [defaultTheme.breakpoints.down('xs')]: { - margin: defaultTheme.spacing(2, 0), - }, - }, - }, MuiTab: { root: { whiteSpace: 'nowrap', diff --git a/yarn.lock b/yarn.lock index 3f697d3..e579a8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -989,7 +989,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== @@ -1052,6 +1052,18 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== +"@date-io/core@1.x", "@date-io/core@^1.3.13": + version "1.3.13" + resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" + integrity sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA== + +"@date-io/date-fns@1.3.13": + version "1.3.13" + resolved "https://registry.yarnpkg.com/@date-io/date-fns/-/date-fns-1.3.13.tgz#7798844041640ab393f7e21a7769a65d672f4735" + integrity sha512-yXxGzcRUPcogiMj58wVgFjc9qUYrCnnU9eLcyNbsQCmae4jPuZCDoIBR21j8ZURsM7GRtU62VOw5yNd4dDHunA== + dependencies: + "@date-io/core" "^1.3.13" + "@emotion/hash@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" @@ -1338,6 +1350,18 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" +"@material-ui/pickers@3.2.10": + version "3.2.10" + resolved "https://registry.yarnpkg.com/@material-ui/pickers/-/pickers-3.2.10.tgz#19df024895876eb0ec7cd239bbaea595f703f0ae" + integrity sha512-B8G6Obn5S3RCl7hwahkQj9sKUapwXWFjiaz/Bsw1fhYFdNMnDUolRiWQSoKPb1/oKe37Dtfszoywi1Ynbo3y8w== + dependencies: + "@babel/runtime" "^7.6.0" + "@date-io/core" "1.x" + "@types/styled-jsx" "^2.2.8" + clsx "^1.0.2" + react-transition-group "^4.0.0" + rifm "^0.7.0" + "@material-ui/styles@^4.11.2": version "4.11.2" resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.2.tgz#e70558be3f41719e8c0d63c7a3c9ae163fdc84cb" @@ -1967,6 +1991,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== +"@types/styled-jsx@^2.2.8": + version "2.2.8" + resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.8.tgz#b50d13d8a3c34036282d65194554cf186bab7234" + integrity sha512-Yjye9VwMdYeXfS71ihueWRSxrruuXTwKCbzue4+5b2rjnQ//AtyM7myZ1BEhNhBQ/nL/RE7bdToUoLln2miKvg== + dependencies: + "@types/react" "*" + "@types/tapable@*", "@types/tapable@^1.0.5": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" @@ -3471,7 +3502,7 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clsx@^1.0.4, clsx@^1.1.1: +clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== @@ -9901,7 +9932,7 @@ react-spring@^8.0.27: "@babel/runtime" "^7.3.1" prop-types "^15.5.8" -react-transition-group@^4.4.0: +react-transition-group@^4.0.0, react-transition-group@^4.4.0: version "4.4.1" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== @@ -10313,6 +10344,13 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rifm@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be" + integrity sha512-DSOJTWHD67860I5ojetXdEQRIBvF6YcpNe53j0vn1vp9EUb9N80EiZTxgP+FkDKorWC8PZw052kTF4C1GOivCQ== + dependencies: + "@babel/runtime" "^7.3.1" + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"