diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5efb761..cfa44eae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,7 +72,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v1 with: - node-version: 12 + node-version: 16 - run: yarn install --frozen-lockfile - run: npx semantic-release env: diff --git a/package.json b/package.json index ee24fa15..14d2cdb6 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "@types/node": "^15.0.1", "conventional-changelog-conventionalcommits": "^4.6.0", "jest": "^26.2.2", + "nx": "14.6.4", "semantic-release": "^17.4.3", "ts-jest": "^26.1.4", - "typescript": "^4.2.4", - "nx": "14.6.4" + "typescript": "^4.8.2" }, "scripts": { "test": "yarn jest", diff --git a/packages/front/package.json b/packages/front/package.json index ae1359cc..b2302b3f 100644 --- a/packages/front/package.json +++ b/packages/front/package.json @@ -6,6 +6,7 @@ "dependencies": { "@craco/craco": "^6.1.2", "@mach/common": "*", + "@tanstack/react-query": "^4.2.3", "@testing-library/jest-dom": "^5.12.0", "@testing-library/react": "^11.2.6", "@testing-library/user-event": "^12.8.3", @@ -14,10 +15,10 @@ "@types/react": "^17.0.5", "@types/react-dom": "^17.0.3", "@types/react-router-dom": "^5.1.7", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-infinite-scroll-component": "^6.1.0", - "react-router-dom": "^5.2.0", + "react-router-dom": "6", "typescript": "^4.2.4", "web-vitals": "^1.1.2" }, diff --git a/packages/front/src/App.tsx b/packages/front/src/App.tsx index 52b88c64..812837b1 100644 --- a/packages/front/src/App.tsx +++ b/packages/front/src/App.tsx @@ -1,19 +1,21 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { FC } from 'react' -import { BrowserRouter, Route, Switch } from 'react-router-dom' -import { FlightsProvider } from './contexts/FlightsContext' +import { BrowserRouter, Route, Routes } from 'react-router-dom' import Home from './views/Home' import Search from './views/Search' +const queryClient = new QueryClient() + const App: FC = () => { return ( - + - - - - + + } /> + } /> + - + ) } diff --git a/packages/front/src/components/SearchFlightsForm/index.tsx b/packages/front/src/components/SearchFlightsForm/index.tsx index c212f745..ef192590 100644 --- a/packages/front/src/components/SearchFlightsForm/index.tsx +++ b/packages/front/src/components/SearchFlightsForm/index.tsx @@ -1,23 +1,22 @@ import { ChangeEventHandler, FC, FormEventHandler, useState } from 'react' -import Alert from '../Alert' import Button from '../Button' import FormInput from '../FormInput' import styles from './index.module.css' -type SearchFlightsFormFields = { departureIcao: string; arrivalIcao: string } +export type SearchFlightsFormFields = { departureIcao: string; arrivalIcao: string } type Props = { onSubmit: (params: Partial) => void - loading: boolean - error: string } -const SearchFlightsForm: FC = ({ onSubmit, loading, error }) => { +const SearchFlightsForm: FC = ({ onSubmit }) => { const [form, setForm] = useState({ arrivalIcao: '', departureIcao: '' }) + const isSubmitDisabled = form.arrivalIcao.trim().length === 0 && form.departureIcao.trim().length === 0 + const onChange: ChangeEventHandler = evt => { setForm(form => ({ ...form, @@ -35,8 +34,6 @@ const SearchFlightsForm: FC = ({ onSubmit, loading, error }) => { return (
- {error ? {error} : ''} -
= ({ onSubmit, loading, error }) => { />
- +
) } diff --git a/packages/front/src/contexts/FlightsContext/index.tsx b/packages/front/src/contexts/FlightsContext/index.tsx deleted file mode 100644 index 32d56e3f..00000000 --- a/packages/front/src/contexts/FlightsContext/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import Flight from '@mach/common' -import { createContext, FC, useReducer } from 'react' -import http from '../../utils/http' -import reducer from './reducer' -import { FlightsContextData, LoadFlightsQuery } from './types' - -const FlightsContext = createContext({} as FlightsContextData) - -const FlightsProvider: FC = ({ children }) => { - const [state, dispatch] = useReducer(reducer, { - data: { items: [], count: 0 }, - query: { limit: 30, offset: 0 }, - loading: false, - error: null - }) - - const loadFlights = async (query: LoadFlightsQuery) => { - try { - if (!query.departureIcao && !query.arrivalIcao) { - throw new Error('You must fill at least one field.') - } - dispatch({ type: 'LOAD_FLIGHTS_INIT', payload: query }) - const payload = await http<{ items: Flight[]; count: number }>({ - url: '//mach-api.herokuapp.com/flights', - query - }) - if (payload.count === 0) { - throw new Error('No flights found.') - } - dispatch({ type: 'LOAD_FLIGHTS_SUCCESS', payload }) - } catch (error) { - dispatch({ type: 'LOAD_FLIGHTS_ERROR', payload: error }) - } - } - - const reset = () => dispatch({ type: 'LOAD_FLIGHTS_RESET' }) - - return ( - - {children} - - ) -} - -export { FlightsContext, FlightsProvider } diff --git a/packages/front/src/contexts/FlightsContext/reducer.ts b/packages/front/src/contexts/FlightsContext/reducer.ts deleted file mode 100644 index 14582090..00000000 --- a/packages/front/src/contexts/FlightsContext/reducer.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { FlightsState, FlightsAction } from './types' - -const reducer = (state: FlightsState, action: FlightsAction) => { - switch (action.type) { - case 'LOAD_FLIGHTS_INIT': - return { ...state, query: action.payload, loading: true, error: null } - case 'LOAD_FLIGHTS_SUCCESS': - return { - ...state, - data: { - items: [...state.data.items, ...action.payload.items], - count: action.payload.count - }, - loading: false, - error: null - } - case 'LOAD_FLIGHTS_RESET': - return { - ...state, - data: { - items: [], - count: 0 - }, - loading: false, - error: null - } - case 'LOAD_FLIGHTS_ERROR': - return { - ...state, - data: { - items: [], - count: 0 - }, - loading: false, - error: action.payload - } - default: - throw new Error('Invalid action provided') - } -} - -export default reducer diff --git a/packages/front/src/contexts/FlightsContext/types.tsx b/packages/front/src/contexts/FlightsContext/types.tsx deleted file mode 100644 index ad0c3ea8..00000000 --- a/packages/front/src/contexts/FlightsContext/types.tsx +++ /dev/null @@ -1,33 +0,0 @@ -export type LoadFlightsQuery = { - departureIcao?: string - arrivalIcao?: string - limit: number - offset: number -} - -export type FlightsState = { - data: { items: any[]; count: number } - query: { - departureIcao?: string - arrivalIcao?: string - limit: number - offset: number - } - loading: boolean - error: Error | null -} - -export type FlightsContextData = { - state: FlightsState - loadFlights: (params: LoadFlightsQuery) => void - reset: () => void -} - -export type FlightsAction = { - type: - | 'LOAD_FLIGHTS_INIT' - | 'LOAD_FLIGHTS_SUCCESS' - | 'LOAD_FLIGHTS_RESET' - | 'LOAD_FLIGHTS_ERROR' - payload?: any -} diff --git a/packages/front/src/hooks/use-extract-flight-parameters.ts b/packages/front/src/hooks/use-extract-flight-parameters.ts new file mode 100644 index 00000000..7951955f --- /dev/null +++ b/packages/front/src/hooks/use-extract-flight-parameters.ts @@ -0,0 +1,16 @@ +import { useLocation } from "react-router-dom" + +export function useExtractFlightParameters() { + const params = new URLSearchParams(useLocation().search) + + let query: Record = {} + + if (params.get('departureIcao')) { + query.departureIcao = params.get('departureIcao')! + } + if (params.get('arrivalIcao')) { + query.arrivalIcao = params.get('arrivalIcao')! + } + + return query +} \ No newline at end of file diff --git a/packages/front/src/hooks/use-flights-query.ts b/packages/front/src/hooks/use-flights-query.ts new file mode 100644 index 00000000..f918a5ef --- /dev/null +++ b/packages/front/src/hooks/use-flights-query.ts @@ -0,0 +1,31 @@ +import Flight from '@mach/common'; +import { useInfiniteQuery } from '@tanstack/react-query'; +import http from "../utils/http"; + +export type FlightsQuery = Partial<{ + departureIcao: string; + arrivalIcao: string; +}> + +type FlightsResponse = { + items: Flight[]; + count: number; +} + +function fetchFlights(query: FlightsQuery & { offset: number }) { + return http({ url: '//mach-api.herokuapp.com/flights', query: { ...query, limit: 30 } }) +} + +export function useFlightsQuery(params: FlightsQuery) { + const query = useInfiniteQuery({ + queryKey: ['flights', params.departureIcao, params.arrivalIcao], + queryFn: ({ pageParam: offset = 0 }) => fetchFlights({ ...params, offset }), + getNextPageParam: (_, allPages) => allPages.reduce((prev, cur) => prev + cur.items.length, 0) + }) + + return { + ...query, + data: query.data?.pages.flatMap(v => v.items) ?? [], + totalItems: query.data?.pages[0].count ?? 0 + } +} \ No newline at end of file diff --git a/packages/front/src/index.tsx b/packages/front/src/index.tsx index ba3503c6..b346d572 100644 --- a/packages/front/src/index.tsx +++ b/packages/front/src/index.tsx @@ -1,14 +1,16 @@ import React from 'react' -import ReactDOM from 'react-dom' +import { createRoot } from 'react-dom/client' import './index.css' import App from './App' import reportWebVitals from './reportWebVitals' -ReactDOM.render( +const container = document.getElementById('root') +const root = createRoot(container) + +root.render( - , - document.getElementById('root') + ) // If you want to start measuring performance in your app, pass a function diff --git a/packages/front/src/views/Home.tsx b/packages/front/src/views/Home.tsx index ffa5ad4f..b6dfb62f 100644 --- a/packages/front/src/views/Home.tsx +++ b/packages/front/src/views/Home.tsx @@ -1,29 +1,27 @@ -import { FC, useContext, useEffect } from 'react' -import { useHistory } from 'react-router-dom' +import { FC } from 'react' +import { useNavigate } from 'react-router-dom' import Lead from '../components/Lead' -import SearchFlightsForm from '../components/SearchFlightsForm' -import { FlightsContext } from '../contexts/FlightsContext' +import SearchFlightsForm, { SearchFlightsFormFields } from '../components/SearchFlightsForm' import GeneralLayout from '../layouts/GeneralLayout' const Home: FC = () => { - const { state, loadFlights } = useContext(FlightsContext) - const history = useHistory() + const navigate = useNavigate() - useEffect(() => { - if (state.data.count > 0) { - history.push('/search') + const handleSubmit = (params: Partial) => { + const urlParams = new URLSearchParams() + if (params.departureIcao) { + urlParams.set('departureIcao', params.departureIcao) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [state.data.count]) + if (params.arrivalIcao) { + urlParams.set('arrivalIcao', params.arrivalIcao) + } + navigate(`/search?${urlParams.toString()}`); + } return ( To begin, fill at least one of the following fields. - loadFlights({ offset: 0, limit: 30, ...params })} - loading={state.loading} - error={state.error ? state.error.message : ''} - /> + ) } diff --git a/packages/front/src/views/Search.tsx b/packages/front/src/views/Search.tsx index 14b0a2b7..bebaf94e 100644 --- a/packages/front/src/views/Search.tsx +++ b/packages/front/src/views/Search.tsx @@ -1,10 +1,11 @@ import Flight from '@mach/common' -import { FC, useContext, useEffect, useState } from 'react' +import { FC, useState } from 'react' import { Link } from 'react-router-dom' import FlightModal from '../components/FlightModal' import FlightsTable from '../components/FlightsTable' import Lead from '../components/Lead' -import { FlightsContext } from '../contexts/FlightsContext' +import { useExtractFlightParameters } from '../hooks/use-extract-flight-parameters' +import { useFlightsQuery } from '../hooks/use-flights-query' import GeneralLayout from '../layouts/GeneralLayout' const getLeadMessage = (count: number) => { @@ -14,43 +15,39 @@ const getLeadMessage = (count: number) => { } const Search: FC = () => { - const { state, loadFlights, reset } = useContext(FlightsContext) - const [offset, setOffset] = useState(0) - const [showModal, setShowModal] = useState(false) - const [flight, setFlight] = useState({} as Flight) - - useEffect(() => { - if (offset === 0) { - return - } - loadFlights({ ...state.query, offset }) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [offset]) + const flightsParameters = useExtractFlightParameters(); + const query = useFlightsQuery(flightsParameters); + const [flight, setFlight] = useState(); + + const showModal = flight !== undefined; + + if (query.totalItems === 0 && query.isSuccess) { + return + + There are no results for your search.{" "} + Click here to make a new search. + + + } return ( - {getLeadMessage(state.data.count)}{' '} - reset()} to="/"> - Click here - {' '} - to make a new search. + {getLeadMessage(query.totalItems)}{' '} + Click here to make a new search. setOffset(v => v + state.query.limit)} - count={state.data.count} - onButtonClick={flight => { - setFlight(flight) - setShowModal(true) - }} + items={query.data} + next={() => query.fetchNextPage()} + count={query.totalItems} + onButtonClick={flight => setFlight(flight)} /> setShowModal(false)} + onClose={() => setFlight(undefined)} /> ) diff --git a/tsconfig.json b/tsconfig.json index 522b42d6..2412dd0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "lib": [ "es6", "es2020" - ] + ], + "skipLibCheck": true }, "exclude": [ "node_modules", diff --git a/yarn.lock b/yarn.lock index 64ea3d22..b6382cc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -470,13 +470,20 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2": version "7.14.0" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.7.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" + integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.13", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1214,6 +1221,20 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@tanstack/query-core@4.2.3": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.2.3.tgz#52d75430c9662cc85c160761c1421de483c7791f" + integrity sha512-zdt5lYWs1dZaA3IxJbCgtAfHZJScRZONpiLL7YkeOkrme5MfjQqTpjq7LYbzpyuwPOh2Jx68le0PLl57JFv5hQ== + +"@tanstack/react-query@^4.2.3": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.2.3.tgz#782fd0f84553ba6219f1137a12ea28ab8cd3a3f3" + integrity sha512-JLaMOxoJTkiAu7QpevRCt2uI/0vd3E8K/rSlCuRgWlcW5DeJDFpDS5kfzmLO5MOcD97fgsJRrDbxDORxR1FdJA== + dependencies: + "@tanstack/query-core" "4.2.3" + "@types/use-sync-external-store" "^0.0.3" + use-sync-external-store "^1.2.0" + "@testing-library/dom@^7.28.1": version "7.30.4" resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.4.tgz#c6a4a91557e92035fd565246bbbfb8107aa4634d" @@ -1503,6 +1524,11 @@ dependencies: "@types/jest" "*" +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + "@types/uuid@^8.3.0": version "8.3.0" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" @@ -4289,24 +4315,12 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -history@^4.9.0: - version "4.10.1" - resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== - dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" - -hoist-non-react-statics@^3.1.0: - version "3.3.2" - resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== +history@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b" + integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ== dependencies: - react-is "^16.7.0" + "@babel/runtime" "^7.7.6" hook-std@^2.0.0: version "2.0.0" @@ -4854,11 +4868,6 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -5739,7 +5748,7 @@ lodash@4.x, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5953,14 +5962,6 @@ min-indent@^1.0.0: resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -mini-create-react-context@^0.4.0: - version "0.4.1" - resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" - integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== - dependencies: - "@babel/runtime" "^7.12.1" - tiny-warning "^1.0.3" - minimatch@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" @@ -6867,13 +6868,6 @@ path-to-regexp@0.1.7: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -7168,7 +7162,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.7.2: version "15.7.2" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -7263,14 +7257,13 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" + scheduler "^0.23.0" react-infinite-scroll-component@^6.1.0: version "6.1.0" @@ -7279,7 +7272,7 @@ react-infinite-scroll-component@^6.1.0: dependencies: throttle-debounce "^2.1.0" -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.8.1: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -7294,42 +7287,27 @@ react-refresh@^0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== -react-router-dom@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" - integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== - dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.2.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react-router@5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" - integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== - dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - hoist-non-react-statics "^3.1.0" - loose-envify "^1.3.1" - mini-create-react-context "^0.4.0" - path-to-regexp "^1.7.0" - prop-types "^15.6.2" - react-is "^16.6.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - -react@^17.0.2: - version "17.0.2" - resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== +react-router-dom@6: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" + integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== + dependencies: + history "^5.2.0" + react-router "6.3.0" + +react-router@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" + integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== + dependencies: + history "^5.2.0" + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" read-cache@^1.0.0: version "1.0.0" @@ -7587,11 +7565,6 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -7722,13 +7695,12 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" semantic-release@^17.4.3: version "17.4.3" @@ -8496,21 +8468,11 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tiny-invariant@^1.0.2: - version "1.1.0" - resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== - tiny-relative-date@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== -tiny-warning@^1.0.0, tiny-warning@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - tmp@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -8738,6 +8700,11 @@ typescript@^4.2.4: resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +typescript@^4.8.2: + version "4.8.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790" + integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw== + uglify-js@^3.1.4: version "3.13.5" resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz#5d71d6dbba64cf441f32929b1efce7365bb4f113" @@ -8842,6 +8809,11 @@ url-join@^4.0.0: resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== +use-sync-external-store@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + use@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -8901,11 +8873,6 @@ validator@^10.11.0: resolved "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228" integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== - vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"