From 3c779bf19636963f350a182ea32a3dc0925ee21c Mon Sep 17 00:00:00 2001 From: Wojtek Bazant Date: Thu, 26 Dec 2024 18:12:52 +0000 Subject: [PATCH] Refactor routes code, save form when back from add location --- public/locales/en.json | 6 + src/components/connect/ConnectNewLocation.js | 17 +- src/components/connect/connectRoutes.js | 2 +- src/components/desktop/SidePane.js | 51 +----- src/components/form/LocationForm.js | 3 +- src/components/form/formRoutes.js | 159 +++++++++++++++++ ...itionNav.js => EditLocationPositionNav.js} | 4 +- src/components/mobile/InitLocationNav.js | 50 ++++++ src/components/mobile/LocationNav.js | 94 ---------- src/components/mobile/MobileLayout.js | 164 +++++++++--------- ...terWrapper.js => SearchAndFilterTopBar.js} | 15 +- src/components/mobile/TopBarSwitch.js | 32 ---- src/redux/locationSlice.js | 8 +- 13 files changed, 331 insertions(+), 274 deletions(-) create mode 100644 src/components/form/formRoutes.js rename src/components/mobile/{LocationPositionNav.js => EditLocationPositionNav.js} (96%) create mode 100644 src/components/mobile/InitLocationNav.js delete mode 100644 src/components/mobile/LocationNav.js rename src/components/mobile/{FilterWrapper.js => SearchAndFilterTopBar.js} (66%) delete mode 100644 src/components/mobile/TopBarSwitch.js diff --git a/public/locales/en.json b/public/locales/en.json index a36b07b77..7742dcff5 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -90,6 +90,12 @@ "zoom_in_to_add_location": "Zoom in to add location" }, "layouts": { + "page_title": { + "editing_location": "Editing Location", + "adding_location": "Adding Location", + "adding_review": "Adding Review", + "editing_review": "Editing Review" + }, "application": { "menu": { "the_project": "The project", diff --git a/src/components/connect/ConnectNewLocation.js b/src/components/connect/ConnectNewLocation.js index 1b030ac14..5de642095 100644 --- a/src/components/connect/ConnectNewLocation.js +++ b/src/components/connect/ConnectNewLocation.js @@ -1,8 +1,7 @@ import { useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { useLocation } from 'react-router-dom' -import { initNewLocation } from '../../redux/locationSlice' +import { initNewLocation, updatePosition } from '../../redux/locationSlice' import { setInitialView } from '../../redux/mapSlice' import { parseCurrentUrl } from '../../utils/appUrl' import { useAppHistory } from '../../utils/useAppHistory' @@ -10,16 +9,17 @@ import { useIsDesktop } from '../../utils/useBreakpoint' const ConnectNewLocation = () => { const dispatch = useDispatch() - const location = useLocation() const history = useAppHistory() const isDesktop = useIsDesktop() const { initialView } = useSelector((state) => state.map) + const { locationId } = useSelector((state) => state.location) + const hasInitialView = !!initialView useEffect(() => { const { view } = parseCurrentUrl() if (view) { - if (!initialView) { + if (!hasInitialView) { dispatch( setInitialView({ center: view.center, @@ -27,13 +27,16 @@ const ConnectNewLocation = () => { }), ) } - dispatch(initNewLocation(view.center)) + if (locationId !== 'new') { + dispatch(initNewLocation(view.center)) + } else if (!isDesktop) { + dispatch(updatePosition(view.center)) + } } else { // Should only happen for an artificially constructed URL history.push('/map') } - }, [dispatch, location.pathname]) //eslint-disable-line - + }, [dispatch, locationId, hasInitialView, isDesktop]) //eslint-disable-line return null } diff --git a/src/components/connect/connectRoutes.js b/src/components/connect/connectRoutes.js index b2af271c3..90d7f1fe3 100644 --- a/src/components/connect/connectRoutes.js +++ b/src/components/connect/connectRoutes.js @@ -154,7 +154,7 @@ const connectRoutes = [ * * action: clear location in Redux */ - + {({ match }) => match && } , /* diff --git a/src/components/desktop/SidePane.js b/src/components/desktop/SidePane.js index 53627d616..6afe7fc5b 100644 --- a/src/components/desktop/SidePane.js +++ b/src/components/desktop/SidePane.js @@ -7,9 +7,7 @@ import styled from 'styled-components/macro' import { pathWithCurrentView } from '../../utils/appUrl' import { useAppHistory } from '../../utils/useAppHistory' import EntryDesktop from '../entry/EntryDesktop' -import { EditLocationForm } from '../form/EditLocation' -import { EditReviewForm } from '../form/EditReview' -import { LocationForm } from '../form/LocationForm' +import { formRoutesDesktop } from '../form/formRoutes' import SettingsPage from '../settings/SettingsPage' import BackButton from '../ui/BackButton' import MainSidePane from './MainSidePane' @@ -71,50 +69,7 @@ const SidePane = () => { - - - { - event.stopPropagation() - history.push(`/locations/${review?.location_id}`) - }} - > - - {t('back')} - - -
Editing My Review
- -
- - {({ match }) => ( - <> - - { - event.stopPropagation() - history.push(`/locations/${match.params.locationId}`) - }} - > - - {t('back')} - - -
Editing Location
- - - )} -
- - - - - {t('back')} - - -
Adding Location
- -
+ {formRoutesDesktop} { history.push( - `/locations/${match.params.locationId}/edit`, + `/locations/${match.params.locationId}/edit/details`, ) } > diff --git a/src/components/form/LocationForm.js b/src/components/form/LocationForm.js index 54ddd5505..7ae981152 100644 --- a/src/components/form/LocationForm.js +++ b/src/components/form/LocationForm.js @@ -149,7 +149,7 @@ const LocationStep = ({ lat, lng, isDesktop, editingId, isLoading }) => { ) } -export const LocationForm = ({ editingId, initialValues }) => { +export const LocationForm = ({ editingId, initialValues, innerRef }) => { const reduxFormValues = useSelector((state) => state.location.form) const mergedInitialValues = { ...INITIAL_LOCATION_VALUES, @@ -227,6 +227,7 @@ export const LocationForm = ({ editingId, initialValues }) => { initialValues={mergedInitialValues} validateOnMount onSubmit={isLoggedIn ? handleSubmit : onPresubmit} + innerRef={innerRef} > {(formikProps) => { const { isSubmitting, isValid, dirty } = formikProps diff --git a/src/components/form/formRoutes.js b/src/components/form/formRoutes.js new file mode 100644 index 000000000..e4827ac7c --- /dev/null +++ b/src/components/form/formRoutes.js @@ -0,0 +1,159 @@ +import { ArrowBack } from '@styled-icons/boxicons-regular' +import { useRef } from 'react' +import { useTranslation } from 'react-i18next' +import { useDispatch, useSelector } from 'react-redux' +import { Route, useParams } from 'react-router-dom' +import styled from 'styled-components/macro' + +import { saveFormValues } from '../../redux/locationSlice' +import { useAppHistory } from '../../utils/useAppHistory' +import BackButton from '../ui/BackButton' +import TopBar from '../ui/TopBar' +import TopBarNav from '../ui/TopBarNav' +import { EditLocationForm } from './EditLocation' +import { EditReviewForm } from './EditReview' +import { LocationForm } from './LocationForm' +import { ReviewForm } from './ReviewForm' + +const StyledNavBack = styled.div` + padding: 25px 15px 15px 10px; + display: flex; + justify-content: space-between; + + svg { + height: 20px; + margin-right: 5px; + } +` + +const Header = styled.h3` + margin-left: 10px; +` + +const MobileNav = ({ titleKey, onBack }) => { + const { t } = useTranslation() + + return ( + + + + ) +} + +const DesktopNav = ({ titleKey, onBack }) => { + const { t } = useTranslation() + return ( + <> + + + + {t('back')} + + +
{t(titleKey)}
+ + ) +} + +const EditLocation = ({ NavComponent }) => { + const history = useAppHistory() + const { locationId } = useParams() + + return ( + <> + { + event.stopPropagation() + history.push(`/locations/${locationId}`) + }} + /> + + + ) +} + +const AddLocation = ({ NavComponent, backUrl }) => { + const history = useAppHistory() + const formRef = useRef() + const dispatch = useDispatch() + + return ( + <> + { + event.stopPropagation() + if (formRef.current) { + dispatch(saveFormValues(formRef.current.values)) + } + history.push(backUrl) + }} + /> + + + ) +} + +const AddReview = ({ NavComponent }) => { + const history = useAppHistory() + const { locationId } = useParams() + + return ( + <> + { + event.stopPropagation() + history.push(`/locations/${locationId}`) + }} + /> + + + ) +} + +const EditReview = ({ NavComponent }) => { + const history = useAppHistory() + const { review } = useSelector((state) => state.review) + + return ( + <> + { + event.stopPropagation() + history.push(`/locations/${review?.location_id}`) + }} + /> + + + ) +} + +export const formRoutesMobile = [ + + + , + + + , + + + , + + + , +] + +export const formRoutesDesktop = [ + + + , + + + , + + + , +] diff --git a/src/components/mobile/LocationPositionNav.js b/src/components/mobile/EditLocationPositionNav.js similarity index 96% rename from src/components/mobile/LocationPositionNav.js rename to src/components/mobile/EditLocationPositionNav.js index ead8f7a7c..0b83d81a5 100644 --- a/src/components/mobile/LocationPositionNav.js +++ b/src/components/mobile/EditLocationPositionNav.js @@ -15,7 +15,7 @@ const Instructions = styled.span` margin-left: 15px; ` -const LocationPositionNav = () => { +const EditLocationPositionNav = () => { const history = useAppHistory() const dispatch = useDispatch() const { locationId } = useParams() @@ -79,4 +79,4 @@ const LocationPositionNav = () => { ) } -export default LocationPositionNav +export default EditLocationPositionNav diff --git a/src/components/mobile/InitLocationNav.js b/src/components/mobile/InitLocationNav.js new file mode 100644 index 000000000..241b27a4b --- /dev/null +++ b/src/components/mobile/InitLocationNav.js @@ -0,0 +1,50 @@ +import { Check, X } from '@styled-icons/boxicons-regular' +import { useSelector } from 'react-redux' +import styled from 'styled-components/macro' + +import { useAppHistory } from '../../utils/useAppHistory' +import { theme } from '../ui/GlobalStyle' +import IconButton from '../ui/IconButton' +import TopBarNav from '../ui/TopBarNav' + +const Instructions = styled.span` + margin-left: 15px; +` + +const InitLocationNav = () => { + const history = useAppHistory() + const { form } = useSelector((state) => state.location) + + return ( + + {form + ? 'Edit position for your new location.' + : 'Choose a position for your new location.'} + + } + rightIcons={ + <> + } + raised + size={54} + onClick={() => history.push('/map')} + /> + } + raised + size={54} + color={theme.green} + onClick={() => history.push('/locations/new')} + /> + + } + /> + ) +} + +export default InitLocationNav diff --git a/src/components/mobile/LocationNav.js b/src/components/mobile/LocationNav.js deleted file mode 100644 index 00b84db28..000000000 --- a/src/components/mobile/LocationNav.js +++ /dev/null @@ -1,94 +0,0 @@ -import { Check, X } from '@styled-icons/boxicons-regular' -import { useSelector } from 'react-redux' -import { Route, Switch } from 'react-router-dom' -import styled from 'styled-components/macro' - -import { useAppHistory } from '../../utils/useAppHistory' -import { theme } from '../ui/GlobalStyle' -import IconButton from '../ui/IconButton' -import TopBarNav from '../ui/TopBarNav' -import LocationPositionNav from './LocationPositionNav' - -const Instructions = styled.span` - margin-left: 15px; -` - -const LocationNav = () => { - const history = useAppHistory() - const { review } = useSelector((state) => state.review) - - const handleGoBack = (event) => { - event.stopPropagation() - history.goBack() - } - - return ( - - - {() => ( - { - event.stopPropagation() - history.push(`/locations/${review?.location_id}`) - }} - title="Editing Review" - /> - )} - - - {() => } - - - {({ match }) => ( - { - event.stopPropagation() - history.push(`/locations/${match.params.locationId}`) - }} - title="Editing location" - /> - )} - - - - history.push('/locations/init')} - title="New location" - /> - - - - Choose a position for your new location. - - } - rightIcons={ - <> - } - raised - size={54} - onClick={() => history.push('/map')} - /> - } - raised - size={54} - color={theme.green} - onClick={() => history.push('/locations/new')} - /> - - } - /> - - - ) -} - -export default LocationNav diff --git a/src/components/mobile/MobileLayout.js b/src/components/mobile/MobileLayout.js index ad82e2fa3..4f6473ec7 100644 --- a/src/components/mobile/MobileLayout.js +++ b/src/components/mobile/MobileLayout.js @@ -8,17 +8,17 @@ import AccountPage from '../auth/AccountPage' import authRoutes from '../auth/authRoutes' import connectRoutes from '../connect/connectRoutes' import EntryMobile from '../entry/EntryMobile' -import { EditLocationForm } from '../form/EditLocation' -import { EditReviewForm } from '../form/EditReview' -import { LocationForm } from '../form/LocationForm' -import { ReviewForm } from '../form/ReviewForm' +import { formRoutesMobile } from '../form/formRoutes' import ListPage from '../list/ListPage' import MapPage from '../map/MapPage' import SettingsPage from '../settings/SettingsPage' import { zIndex } from '../ui/GlobalStyle' import { PageTabs, TabList, TabPanels } from '../ui/PageTabs' +import TopBar from '../ui/TopBar' +import EditLocationPositionNav from './EditLocationPositionNav' +import InitLocationNav from './InitLocationNav' +import SearchAndFilterTopBar from './SearchAndFilterTopBar' import Tabs from './Tabs' -import TopBarSwitch from './TopBarSwitch' const shouldDisplayMapPage = (pathname) => { if (matchPath(pathname, { path: '/map', exact: false, strict: false })) { @@ -64,95 +64,101 @@ const MobileLayout = () => { const { tabIndex, handleTabChange, tabContent } = Tabs() return ( - + <> - -
- -
- {connectRoutes} - + + {formRoutesMobile} +
+ +
+ {connectRoutes} - {activityRoutes} - {aboutRoutes} - {authRoutes} - - {({ match }) => ( - - )} - - - - - - {({ match }) => ( - - )} - - - - - + + - - - - {!streetView && } + + + + + + + + + + + + + {activityRoutes} + {aboutRoutes} + {authRoutes} + + + + + + {!streetView && } + + + + + + + + + + + + + + + + - - - - - - - - + + + {tabContent} + -
- - - - - {tabContent} - - - -
+ + ) } diff --git a/src/components/mobile/FilterWrapper.js b/src/components/mobile/SearchAndFilterTopBar.js similarity index 66% rename from src/components/mobile/FilterWrapper.js rename to src/components/mobile/SearchAndFilterTopBar.js index 3215a978e..9dbe68168 100644 --- a/src/components/mobile/FilterWrapper.js +++ b/src/components/mobile/SearchAndFilterTopBar.js @@ -3,6 +3,8 @@ import { useSelector } from 'react-redux' import styled, { css } from 'styled-components' import Filter from '../filter/Filter' +import Search from '../search/Search' +import TopBar from '../ui/TopBar' const StyledFilter = styled.div` box-sizing: border-box; @@ -15,7 +17,7 @@ const StyledFilter = styled.div` `} ` -const FilterWrapper = () => { +const SearchAndFilterTopBar = () => { const filterOpen = useSelector((state) => state.filter.isOpenInMobileLayout) const { typesAccess } = useSelector((state) => state.type) @@ -24,10 +26,13 @@ const FilterWrapper = () => { } return ( - - - + + + + + + ) } -export default FilterWrapper +export default SearchAndFilterTopBar diff --git a/src/components/mobile/TopBarSwitch.js b/src/components/mobile/TopBarSwitch.js deleted file mode 100644 index 2daaf4051..000000000 --- a/src/components/mobile/TopBarSwitch.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Route, Switch } from 'react-router-dom' - -import Search from '../search/Search' -import TopBar from '../ui/TopBar' -import FilterWrapper from './FilterWrapper' -import LocationNav from './LocationNav' - -const TopBarSwitch = () => ( - - - - - - - - - - - - - -) - -export default TopBarSwitch diff --git a/src/redux/locationSlice.js b/src/redux/locationSlice.js index 2627ad160..3377e176f 100644 --- a/src/redux/locationSlice.js +++ b/src/redux/locationSlice.js @@ -94,12 +94,10 @@ const locationSlice = createSlice({ state.isLoading = false state.location = null state.isBeingEdited = false - if (state.locationId !== 'new') { - state.locationId = 'new' - state.position = action.payload - state.tooltipOpen = true - } + state.locationId = 'new' + state.tooltipOpen = true state.form = null + state.position = action.payload state.streetViewOpen = false }, updatePosition: (state, action) => {