diff --git a/src/client/hooks/useURLSearchParams.js b/src/client/hooks/useURLSearchParams.js new file mode 100644 index 000000000..ec3230dd5 --- /dev/null +++ b/src/client/hooks/useURLSearchParams.js @@ -0,0 +1,16 @@ +import React from 'react' +import { useLocation } from 'react-router' + +const useURLSearchParams = () => { + const location = useLocation() + const params = React.useMemo(() => new URLSearchParams(location.search), [location.search]) + return [ + params, + React.useCallback(nextParams => { + const nextSearch = nextParams.toString() + window.history.replaceState({}, '', `${location.pathname}?${nextSearch}`) + }, []), + ] +} + +export default useURLSearchParams diff --git a/src/client/pages/CourseSummary/SummaryV2/context.js b/src/client/pages/CourseSummary/SummaryV2/context.js index 858beaa41..a93209f89 100644 --- a/src/client/pages/CourseSummary/SummaryV2/context.js +++ b/src/client/pages/CourseSummary/SummaryV2/context.js @@ -1,12 +1,13 @@ import React from 'react' -import useHistoryState from '../../../hooks/useHistoryState' +import { format, isValid } from 'date-fns' +import useURLSearchParams from '../../../hooks/useURLSearchParams' const summaryContext = React.createContext({ showSummariesWithNoFeedback: false, setShowSummariesWithNoFeedback: () => {}, dateRange: { - startDate: new Date('2023-01-01'), - endDate: new Date('2024-01-01'), + start: new Date('2023-01-01'), + end: new Date('2024-01-01'), }, setDateRange: () => {}, option: 'year', @@ -14,21 +15,60 @@ const summaryContext = React.createContext({ }) export const SummaryContextProvider = ({ children }) => { - const [showSummariesWithNoFeedback, setShowSummariesWithNoFeedback] = React.useState(false) - const [dateRange, setDateRange] = useHistoryState('summary-v2-time-range', { - start: new Date('2023-01-01'), - end: new Date('2024-01-01'), + const [params, setParams] = useURLSearchParams() + + const [showSummariesWithNoFeedback, setShowSummariesWithNoFeedback] = React.useState(() => { + const showSummariesWithNoFeedbackParam = params.get('showSummariesWithNoFeedback') + return showSummariesWithNoFeedbackParam ? showSummariesWithNoFeedbackParam === 'true' : false + }) + + const updateShowSummariesWithNoFeedbackQS = React.useCallback(showSummariesWithNoFeedback => { + setShowSummariesWithNoFeedback(showSummariesWithNoFeedback) + params.set('showSummariesWithNoFeedback', showSummariesWithNoFeedback) + setParams(params) + }) + + const [dateRange, setDateRange] = React.useState(() => { + // Converting to string is important, params.get may return 0 which would take us to the 70s + const start = new Date(String(params.get('startDate'))) + const end = new Date(String(params.get('endDate'))) + + return isValid(start) && isValid(end) + ? { start, end } + : { + start: new Date('2023-01-01'), + end: new Date('2024-01-01'), + } + }) + + const updateDateRangeQS = React.useCallback(dateRange => { + setDateRange(dateRange) + if (isValid(dateRange.start) && isValid(dateRange.end)) { + params.set('startDate', format(dateRange.start, 'yyyy-MM-dd')) + params.set('endDate', format(dateRange.end, 'yyyy-MM-dd')) + setParams(params) + } + }) + + const [option, setOption] = React.useState(() => { + const option = params.get('option') + return option || 'year' + }) + + const updateOptionQS = React.useCallback(option => { + setOption(option) + params.set('option', option) + setParams(params) }) - const [option, setOption] = React.useState('year') const value = React.useMemo( () => ({ showSummariesWithNoFeedback, - setShowSummariesWithNoFeedback, + setShowSummariesWithNoFeedback: updateShowSummariesWithNoFeedbackQS, dateRange, - setDateRange, + setDateRange: updateDateRangeQS, option, - setOption, + setOption: updateOptionQS, }), [showSummariesWithNoFeedback, dateRange, option] )