diff --git a/src/features/ServerPage/features/RankingPage/features/PlayerPage/features/DailyPage/components/Ranking/Ranking.tsx b/src/features/ServerPage/features/RankingPage/features/PlayerPage/features/DailyPage/components/Ranking/Ranking.tsx index 7fad11c..55fa41b 100644 --- a/src/features/ServerPage/features/RankingPage/features/PlayerPage/features/DailyPage/components/Ranking/Ranking.tsx +++ b/src/features/ServerPage/features/RankingPage/features/PlayerPage/features/DailyPage/components/Ranking/Ranking.tsx @@ -4,7 +4,6 @@ import { NumberParam, withDefault, StringParam, - DateParam, } from 'use-query-params'; import { useDebouncedCallback } from 'use-debounce'; import useDateUtils from '@libs/date/useDateUtils'; @@ -12,6 +11,7 @@ import useUpdateEffect from '@libs/useUpdateEffect'; import useScrollToElement from '@libs/useScrollToElement'; import useServer from '@features/ServerPage/libs/ServerContext/useServer'; import SortParam from '@libs/serialize-query-params/SortParam'; +import DateParam from '@libs/serialize-query-params/DateParam'; import useStats from './useStats'; import { validateRowsPerPage } from '@common/Table/helpers'; import { COLUMNS, LIMIT, DEFAULT_SORT } from './constants'; @@ -35,13 +35,16 @@ function Ranking({ t }: Props) { const classes = useStyles(); const server = useServer(); const dateUtils = useDateUtils(); - const defaultDate = useRef(dateUtils.date(server.historyUpdatedAt)); + const dateParam = new DateParam({ dateUtils }); + const defaultDate = useRef( + dateParam.newDecodedDate(dateUtils.date(server.historyUpdatedAt)) + ); const [query, setQuery] = useQueryParams({ page: withDefault(NumberParam, 0), limit: withDefault(NumberParam, LIMIT), q: withDefault(StringParam, ''), sort: withDefault(SortParam, DEFAULT_SORT), - createDate: withDefault(DateParam, defaultDate.current), + createDate: withDefault(dateParam, defaultDate.current), }); const limit = validateRowsPerPage(query.limit); const [q, setQ] = useState(query.q); @@ -60,7 +63,7 @@ function Ranking({ t }: Props) { server.key, query.q, query.sort.toString(), - dateUtils.toJSON(query.createDate) + query.createDate.server ); return ( @@ -69,7 +72,7 @@ function Ranking({ t }: Props) { { diff --git a/src/features/ServerPage/features/RankingPage/features/TribePage/features/DailyPage/components/Ranking/Ranking.tsx b/src/features/ServerPage/features/RankingPage/features/TribePage/features/DailyPage/components/Ranking/Ranking.tsx index cebc8da..d9437c8 100644 --- a/src/features/ServerPage/features/RankingPage/features/TribePage/features/DailyPage/components/Ranking/Ranking.tsx +++ b/src/features/ServerPage/features/RankingPage/features/TribePage/features/DailyPage/components/Ranking/Ranking.tsx @@ -4,7 +4,6 @@ import { NumberParam, withDefault, StringParam, - DateParam, } from 'use-query-params'; import { useDebouncedCallback } from 'use-debounce'; import useDateUtils from '@libs/date/useDateUtils'; @@ -13,6 +12,7 @@ import useScrollToElement from '@libs/useScrollToElement'; import useServer from '@features/ServerPage/libs/ServerContext/useServer'; import useStats from './useStats'; import SortParam from '@libs/serialize-query-params/SortParam'; +import DateParam from '@libs/serialize-query-params/DateParam'; import { validateRowsPerPage } from '@common/Table/helpers'; import * as ROUTES from '@config/routes'; import { COLUMNS, LIMIT, DEFAULT_SORT } from './constants'; @@ -36,13 +36,16 @@ function Ranking({ t }: Props) { const classes = useStyles(); const server = useServer(); const dateUtils = useDateUtils(); - const defaultDate = useRef(dateUtils.date(server.historyUpdatedAt)); + const dateParam = new DateParam({ dateUtils }); + const defaultDate = useRef( + dateParam.newDecodedDate(dateUtils.date(server.historyUpdatedAt)) + ); const [query, setQuery] = useQueryParams({ page: withDefault(NumberParam, 0), limit: withDefault(NumberParam, LIMIT), q: withDefault(StringParam, ''), sort: withDefault(SortParam, DEFAULT_SORT), - createDate: withDefault(DateParam, defaultDate.current), + createDate: withDefault(dateParam, defaultDate.current), }); const limit = validateRowsPerPage(query.limit); const [q, setQ] = useState(query.q); @@ -61,7 +64,7 @@ function Ranking({ t }: Props) { server.key, query.q, query.sort.toString(), - dateUtils.toJSON(query.createDate) + query.createDate.server ); return ( @@ -70,7 +73,7 @@ function Ranking({ t }: Props) { { diff --git a/src/libs/serialize-query-params/DateParam.ts b/src/libs/serialize-query-params/DateParam.ts new file mode 100644 index 0000000..5ef255e --- /dev/null +++ b/src/libs/serialize-query-params/DateParam.ts @@ -0,0 +1,59 @@ +import { QueryParamConfig } from 'use-query-params'; +import DateUtils from '@libs/date/DateUtils'; +import { getEncodedValue } from './helpers'; + +type Decoded = { + display: Date; + server: Date; +}; + +export default class DateParam + implements QueryParamConfig { + private dateUtils: DateUtils; + constructor({ dateUtils }: { dateUtils: DateUtils }) { + this.dateUtils = dateUtils; + } + + public newDecodedDate = (val: any): Decoded => { + return { + server: new Date(this.dateUtils.toJSON(new Date(val))), + display: this.dateUtils.date(val), + }; + }; + + public encode = ( + date: Date | null | undefined + ): string | null | undefined => { + if (!date) { + return undefined; + } + + return this.dateUtils.format(date, 'yyyy-MM-dd'); + }; + + public decode = ( + input: string | (string | null)[] | null | undefined + ): Decoded | undefined => { + const dateString = getEncodedValue(input); + if (!dateString) return undefined; + + const parts = dateString.split('-') as any; + // may only be a year so won't even have a month + if (parts[1] !== null) { + parts[1] -= 1; // Note: months are 0-based + } else { + // just a year, set the month and day to the first + parts[1] = 0; + parts[2] = 1; + } + + const decoded = this.newDecodedDate( + new Date(...(parts as [number, number, number])) + ); + if (isNaN(decoded.server.getTime()) || isNaN(decoded.server.getTime())) { + return undefined; + } + + return decoded; + }; +}