Skip to content

Commit

Permalink
Refactor routes code, save form when back from add location
Browse files Browse the repository at this point in the history
  • Loading branch information
wbazant committed Jan 2, 2025
1 parent 899ee2f commit 3c779bf
Show file tree
Hide file tree
Showing 13 changed files with 331 additions and 274 deletions.
6 changes: 6 additions & 0 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
17 changes: 10 additions & 7 deletions src/components/connect/ConnectNewLocation.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,42 @@
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'
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,
zoom: Math.max(view.zoom, isDesktop ? 0 : 16),
}),
)
}
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
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/connect/connectRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const connectRoutes = [
*
* action: clear location in Redux
*/
<Route key="disconnect-location" path={['/map', '/locations/init']}>
<Route key="disconnect-location" path={['/map']}>
{({ match }) => match && <DisconnectLocation />}
</Route>,
/*
Expand Down
51 changes: 3 additions & 48 deletions src/components/desktop/SidePane.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -71,50 +69,7 @@ const SidePane = () => {
</Route>
<Route>
<Switch>
<Route path="/reviews/:reviewId/edit">
<StyledNavBack>
<BackButton
onClick={(event) => {
event.stopPropagation()
history.push(`/locations/${review?.location_id}`)
}}
>
<ArrowBack />
{t('back')}
</BackButton>
</StyledNavBack>
<Header>Editing My Review</Header>
<EditReviewForm />
</Route>
<Route path="/locations/:locationId/edit">
{({ match }) => (
<>
<StyledNavBack>
<BackButton
onClick={(event) => {
event.stopPropagation()
history.push(`/locations/${match.params.locationId}`)
}}
>
<ArrowBack />
{t('back')}
</BackButton>
</StyledNavBack>
<Header>Editing Location</Header>
<EditLocationForm />
</>
)}
</Route>
<Route path="/locations/new">
<StyledNavBack>
<BackButton onClick={goToMap}>
<ArrowBack />
{t('back')}
</BackButton>
</StyledNavBack>
<Header>Adding Location</Header>
<LocationForm />
</Route>
{formRoutesDesktop}
<Route path="/settings">
<StyledNavBack>
<BackButton
Expand Down Expand Up @@ -160,7 +115,7 @@ const SidePane = () => {
<BackButton
onClick={() =>
history.push(
`/locations/${match.params.locationId}/edit`,
`/locations/${match.params.locationId}/edit/details`,
)
}
>
Expand Down
3 changes: 2 additions & 1 deletion src/components/form/LocationForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -227,6 +227,7 @@ export const LocationForm = ({ editingId, initialValues }) => {
initialValues={mergedInitialValues}
validateOnMount
onSubmit={isLoggedIn ? handleSubmit : onPresubmit}
innerRef={innerRef}
>
{(formikProps) => {
const { isSubmitting, isValid, dirty } = formikProps
Expand Down
159 changes: 159 additions & 0 deletions src/components/form/formRoutes.js
Original file line number Diff line number Diff line change
@@ -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 (
<TopBar>
<TopBarNav onBack={onBack} title={t(titleKey)} />
</TopBar>
)
}

const DesktopNav = ({ titleKey, onBack }) => {
const { t } = useTranslation()
return (
<>
<StyledNavBack>
<BackButton onClick={onBack}>
<ArrowBack />
{t('back')}
</BackButton>
</StyledNavBack>
<Header>{t(titleKey)}</Header>
</>
)
}

const EditLocation = ({ NavComponent }) => {
const history = useAppHistory()
const { locationId } = useParams()

return (
<>
<NavComponent
titleKey="layouts.page_title.editing_location"
onBack={(event) => {
event.stopPropagation()
history.push(`/locations/${locationId}`)
}}
/>
<EditLocationForm />
</>
)
}

const AddLocation = ({ NavComponent, backUrl }) => {
const history = useAppHistory()
const formRef = useRef()
const dispatch = useDispatch()

return (
<>
<NavComponent
titleKey="layouts.page_title.adding_location"
onBack={(event) => {
event.stopPropagation()
if (formRef.current) {
dispatch(saveFormValues(formRef.current.values))
}
history.push(backUrl)
}}
/>
<LocationForm innerRef={formRef} />
</>
)
}

const AddReview = ({ NavComponent }) => {
const history = useAppHistory()
const { locationId } = useParams()

return (
<>
<NavComponent
titleKey="layouts.page_title.adding_review"
onBack={(event) => {
event.stopPropagation()
history.push(`/locations/${locationId}`)
}}
/>
<ReviewForm />
</>
)
}

const EditReview = ({ NavComponent }) => {
const history = useAppHistory()
const { review } = useSelector((state) => state.review)

return (
<>
<NavComponent
titleKey="layouts.page_title.editing_review"
onBack={(event) => {
event.stopPropagation()
history.push(`/locations/${review?.location_id}`)
}}
/>
<EditReviewForm />
</>
)
}

export const formRoutesMobile = [
<Route key="edit-location" path="/locations/:locationId/edit/details">
<EditLocation NavComponent={MobileNav} />
</Route>,
<Route key="add-location" path="/locations/new">
<AddLocation NavComponent={MobileNav} backUrl="/locations/init" />
</Route>,
<Route key="add-review" path="/locations/:locationId/review">
<AddReview NavComponent={MobileNav} />
</Route>,
<Route key="edit-review" path="/reviews/:reviewId/edit">
<EditReview NavComponent={MobileNav} />
</Route>,
]

export const formRoutesDesktop = [
<Route key="edit-location" path="/locations/:locationId/edit/details">
<EditLocation NavComponent={DesktopNav} />
</Route>,
<Route key="add-location" path="/locations/new">
<AddLocation NavComponent={DesktopNav} backUrl="/map" />
</Route>,
<Route key="edit-review" path="/reviews/:reviewId/edit">
<EditReview NavComponent={DesktopNav} />
</Route>,
]
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Instructions = styled.span`
margin-left: 15px;
`

const LocationPositionNav = () => {
const EditLocationPositionNav = () => {
const history = useAppHistory()
const dispatch = useDispatch()
const { locationId } = useParams()
Expand Down Expand Up @@ -79,4 +79,4 @@ const LocationPositionNav = () => {
)
}

export default LocationPositionNav
export default EditLocationPositionNav
50 changes: 50 additions & 0 deletions src/components/mobile/InitLocationNav.js
Original file line number Diff line number Diff line change
@@ -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 (
<TopBarNav
left={
<Instructions>
{form
? 'Edit position for your new location.'
: 'Choose a position for your new location.'}
</Instructions>
}
rightIcons={
<>
<IconButton
label="Cancel choose location"
icon={<X />}
raised
size={54}
onClick={() => history.push('/map')}
/>
<IconButton
label="Confirm choose location"
icon={<Check />}
raised
size={54}
color={theme.green}
onClick={() => history.push('/locations/new')}
/>
</>
}
/>
)
}

export default InitLocationNav
Loading

0 comments on commit 3c779bf

Please sign in to comment.