Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
"^@mui/[^/]+$",
"(?=^|[^/])shared/((?!api)|api/(?!endpoints/testing)).+"
],
"codescene.enableTelemetry": false
"codescene.enableTelemetry": false,
"jest.virtualFolders": [
{ "name": "web", "rootPath": "web" },
{ "name": "native", "rootPath": "native" },
{ "name": "shared", "rootPath": "shared" },
{ "name": "translations", "rootPath": "translations" }
]
}
6 changes: 4 additions & 2 deletions translations/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -7738,7 +7738,8 @@
"skipToContent": "Zum Inhalt springen",
"shareQrCodeTitle": "Über QR-Code teilen",
"shareQrCodeDescription": "Teile diese Seite einfach, indem du den QR-Code auf einem anderen Gerät scannst.",
"qrCode": "QR-Code"
"qrCode": "QR-Code",
"backToContent": "Zurück zum Inhalt"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ulyanahoy-cloud is Back to content/Zurück zum Inhalt necessary or would a simple Go Back/Zurück be enough? That would save us another translation :)

},
"am": {
"imprint": "ዕትም",
Expand Down Expand Up @@ -8053,7 +8054,8 @@
"skipToContent": "Skip to content",
"shareQrCodeTitle": "Share via QR code",
"shareQrCodeDescription": "Share this page easily by scanning the QR code on another device.",
"qrCode": "QR code"
"qrCode": "QR code",
"backToContent": "Back to content"
},
"es": {
"imprint": "Aviso legal",
Expand Down
38 changes: 38 additions & 0 deletions web/src/components/BackToRegionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Button from '@mui/material/Button'
import { styled } from '@mui/material/styles'
import React, { ReactElement, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'

import useDimensions from '../hooks/useDimensions'
import { DirectionDependentBackIcon } from './base/Dialog'

const StyledButton = styled(Button)({
textTransform: 'none',
alignSelf: 'flex-start',
})

const BackToRegionButton = (): ReactElement | null => {
const navigate = useNavigate()
const { mobile } = useDimensions()
const { t } = useTranslation('layout')
const currentHistoryIndex = window.history.state?.idx ?? 0

// Initial history index to account for language changes or other user interactions on this page.
const [initialHistoryIndex] = useState(currentHistoryIndex)

if (!mobile || initialHistoryIndex === 0) {
return null
}

return (
<StyledButton
onClick={() => navigate(initialHistoryIndex - currentHistoryIndex - 1)}
startIcon={<DirectionDependentBackIcon />}
color='inherit'>
{t('backToContent')}
</StyledButton>
)
}

export default BackToRegionButton
42 changes: 42 additions & 0 deletions web/src/components/__tests__/BackToRegionButton.spec.tsx
Comment thread
bahaaTuffaha marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { fireEvent } from '@testing-library/react'
import React from 'react'

import { mockDimensions } from '../../__mocks__/useDimensions'
import useDimensions from '../../hooks/useDimensions'
import { renderWithRouterAndTheme } from '../../testing/render'
import BackToRegionButton from '../BackToRegionButton'

const mockNavigate = jest.fn()
jest.mock('react-i18next')
jest.mock('../../hooks/useDimensions')
jest.mock('react-router', () => ({
...jest.requireActual('react-router'),
useNavigate: () => mockNavigate,
}))

describe('BackToRegionButton', () => {
const { mocked } = jest

const setHistoryIndex = (idx: number) => window.history.replaceState({ idx }, '')

beforeEach(() => {
jest.clearAllMocks()
mocked(useDimensions).mockImplementation(() => ({ ...mockDimensions, mobile: true }))
setHistoryIndex(1)
})

it('should render on mobile and navigate back on click', () => {
const { getByText } = renderWithRouterAndTheme(<BackToRegionButton />)

fireEvent.click(getByText('layout:backToContent'))

expect(mockNavigate).toHaveBeenCalledWith(-1)
})

it('should render nothing when there is no history to go back to', () => {
setHistoryIndex(0)
const { queryByText } = renderWithRouterAndTheme(<BackToRegionButton />)

expect(queryByText('layout:backToContent')).toBeFalsy()
})
})
2 changes: 2 additions & 0 deletions web/src/routes/RegionsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'

import { createRegionsEndpoint } from 'shared/api'

import BackToRegionButton from '../components/BackToRegionButton'
import FailureSwitcherWithHelmet from '../components/FailureSwitcherWithHelmet'
import Footer from '../components/Footer'
import GeneralHeader from '../components/GeneralHeader'
Expand Down Expand Up @@ -44,6 +45,7 @@ const RegionsPage = ({ languageCode }: RegionsPageProps): ReactElement => {
</>
}>
<Helmet pageTitle={pageTitle} metaDescription={metaDescription} rootPage />
<BackToRegionButton />
<RegionSelector regions={regions ?? []} language={languageCode} stickyTop={stickyTop} loading={isPending} />
</Layout>
)
Expand Down
Loading