Skip to content

Commit

Permalink
feat(#1290383): [Example App] Add latitude and Longitude Field in a S…
Browse files Browse the repository at this point in the history
…ettings Component
  • Loading branch information
matthias-goupil committed Oct 28, 2024
1 parent 03423a0 commit 3233c36
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 10 deletions.
2 changes: 2 additions & 0 deletions front/example-app/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { catalogContext, extraBundlesContext } from '../../contexts'
import HeaderFormControl from '../HeaderFormControl/HeaderFormControl'
import SearchBar from '../SearchBar/SearchBar'
import Logo from './logo.svg'
import Settings from '../Settings/Settings'

function Header(): JSX.Element {
const catalogLabelId = useId()
Expand Down Expand Up @@ -142,6 +143,7 @@ function Header(): JSX.Element {
)}
</Box>
</Box>
<Settings />
</Toolbar>
</AppBar>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ exports[`Header match snapshot 1`] = `
</div>
</div>
</div>
<button
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-sizeMedium css-142yyjb-MuiButtonBase-root-MuiIconButton-root"
tabindex="0"
type="button"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root MuiSvgIcon-fontSizeMedium css-i4bv87-MuiSvgIcon-root"
color="#fff"
data-testid="SettingsIcon"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"
/>
</svg>
<span
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
/>
</button>
</div>
</nav>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import RequestedPathProvider from '../RequestedPathProvider/RequestedPathProvide
import SchemaProvider from '../SchemaProvider/SchemaProvider'
import SearchProvider from '../SearchProvider/SearchProvider'
import UserProvider from '../UserProvider/UserProvider'
import SettingsProvider from '../SettingsProvider/SettingsProvider'

interface IProps {
children: ReactNode
Expand All @@ -22,9 +23,11 @@ function AppProvider(props: IProps): JSX.Element {
<ConfigurationsProvider>
<RequestedPathProvider>
<ExtraBundlesProvider>
<CategoryProvider>
<SearchProvider>{children}</SearchProvider>
</CategoryProvider>
<SettingsProvider>
<CategoryProvider>
<SearchProvider>{children}</SearchProvider>
</CategoryProvider>
</SettingsProvider>
</ExtraBundlesProvider>
</RequestedPathProvider>
</ConfigurationsProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { ReactNode, useMemo, useState } from 'react'
import { ISettingsContext, settingsContext } from '../../../contexts'

interface IProps {
children: ReactNode
}

function SettingsProvider({ children }: IProps): JSX.Element {
const [longitude, setLongitude] = useState<string>('')
const [latitude, setLatitude] = useState<string>('')

const context = useMemo<ISettingsContext>(
() => ({
longitude,
latitude,
setLatitude,
setLongitude,
}),
[longitude, latitude, setLatitude, setLongitude]
)

return (
<settingsContext.Provider value={context}>
{children}
</settingsContext.Provider>
)
}

export default SettingsProvider
139 changes: 139 additions & 0 deletions front/example-app/src/components/Settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import {
Button,
Fade,
IconButton,
Paper,
Popper,
TextField,
styled,
} from '@mui/material'
import SettingsIcon from '@mui/icons-material/Settings'
import React, {
FormEvent,
MouseEvent,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from 'react'

import { settingsContext } from 'src/contexts'

function Settings(): JSX.Element {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
const formRef = useRef<HTMLFormElement>(null)
const open = useMemo(() => Boolean(anchorEl), [anchorEl])
const popperRef = useRef<HTMLDivElement>(null)
const handleClick = (event: MouseEvent<HTMLElement>): void => {
setAnchorEl(anchorEl ? null : event.currentTarget)
}

const { longitude, latitude, setLatitude, setLongitude } =
useContext(settingsContext)

const id = open ? 'simple-popper' : undefined

function handleSubmit(e: FormEvent<HTMLFormElement>): void {
e.preventDefault()
const { latitude, longitude } = Object.fromEntries(
new FormData(formRef.current).entries()
)
setLatitude(latitude.toString())
setLongitude(longitude.toString())
if (latitude && longitude) {
setAnchorEl(null)
}
}

useEffect(() => {
function handleClickOutside(event: globalThis.MouseEvent): void {
if (
popperRef.current &&
!popperRef.current.contains(event.target as Node) &&
!anchorEl?.contains(event.target as Node)
) {
setAnchorEl(null)
}
}

if (open) {
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
}
}, [open, anchorEl])

const CutomForm = styled('form')(({ theme }) => ({
padding: theme.spacing(2),
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(2),
}))

const Row = styled('div')(({ theme }) => ({
display: 'flex',
gap: theme.spacing(2),
alignItems: 'center',
}))

return (
<>
<IconButton onClick={handleClick} sx={{ marginLeft: '20px' }}>
<SettingsIcon htmlColor="#fff" />
</IconButton>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
ref={popperRef}
sx={{
zIndex: 1200,
}}
transition
>
{({ TransitionProps }): JSX.Element => (
<Fade {...TransitionProps} timeout={350}>
<Paper>
<CutomForm ref={formRef} onSubmit={handleSubmit}>
<Row>
<TextField
id="outlined-basic"
label="Latitude"
variant="outlined"
name="latitude"
type="number"
defaultValue={latitude}
inputProps={{
step: '0.000001',
min: -90,
max: 90,
}}
/>
<TextField
id="outlined-basic"
label="Longitude"
variant="outlined"
type="number"
name="longitude"
defaultValue={longitude}
inputProps={{
step: '0.000001',
min: -180,
max: 180,
}}
/>
</Row>

<Button type="submit" variant="outlined">
Appliquer
</Button>
</CutomForm>
</Paper>
</Fade>
)}
</Popper>
</>
)
}

export default Settings
1 change: 1 addition & 0 deletions front/example-app/src/contexts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './extraBundles'
export * from './search'
export * from './requestedPath'
export * from './user'
export * from './settings'
10 changes: 10 additions & 0 deletions front/example-app/src/contexts/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Dispatch, SetStateAction, createContext } from 'react'

export interface ISettingsContext {
longitude: string
latitude: string
setLongitude: Dispatch<SetStateAction<ISettingsContext['longitude']>>
setLatitude: Dispatch<SetStateAction<ISettingsContext['latitude']>>
}

export const settingsContext = createContext<ISettingsContext>(null)
4 changes: 2 additions & 2 deletions front/example-app/src/hooks/useProducts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import {
fetchGraphql,
} from '@elastic-suite/gally-admin-shared'

import { renderHookWithProviders } from '../utils/tests'

import { useProducts } from './useProducts'
import { renderHookWithProviders } from '../utils/tests'

describe('useProducts', () => {
it('should call the API when loading the product', async () => {
const { result } = renderHookWithProviders(() =>
useProducts(ProductRequestType.SEARCH)
)

expect(result.current.products).toEqual({
status: LoadStatus.IDLE,
})
Expand Down
35 changes: 31 additions & 4 deletions front/example-app/src/hooks/useProducts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
isError,
} from '@elastic-suite/gally-admin-shared'

import { catalogContext } from '../contexts'
import { catalogContext, settingsContext } from '../contexts'
import { IActiveFilters, IFilterMoreOptions, IProductsHook } from '../types'
import { getProductFilters } from '../services'

Expand All @@ -47,6 +47,7 @@ export function useProducts(
() => getProductFilters(activeFilters),
[activeFilters]
)
const { longitude, latitude } = useContext(settingsContext)

const [products, setProducts, load, debouncedLoad] =
useGraphqlApi<IGraphqlSearchProducts>()
Expand Down Expand Up @@ -90,7 +91,15 @@ export function useProducts(
const loadFunction = activeFilters.length === 0 ? load : debouncedLoad
return loadFunction(
getSearchProductsQuery(queryFilters, true),
variables as unknown as Record<string, unknown>
variables as unknown as Record<string, unknown>,
{
headers: {
...(latitude !== '' &&
longitude !== '' && {
'reference-location': `${latitude}, ${longitude}`,
}),
},
}
)
}
setProducts(null)
Expand All @@ -109,6 +118,8 @@ export function useProducts(
setProducts,
sort,
sortOrder,
latitude,
longitude,
]
)

Expand All @@ -134,7 +145,15 @@ export function useProducts(
}
graphqlApi<IGraphqlViewMoreProductFacetOptions>(
getMoreFacetProductOptionsQuery(queryFilters),
variables as unknown as Record<string, unknown>
variables as unknown as Record<string, unknown>,
{
headers: {
...(latitude !== '' &&
longitude !== '' && {
'reference-location': `${latitude}, ${longitude}`,
}),
},
}
).then((json) => {
if (isError(json)) {
setMoreOptions(
Expand All @@ -161,7 +180,15 @@ export function useProducts(
}
})
},
[graphqlApi, localizedCatalogId, queryFilters, search]
[
graphqlApi,
localizedCatalogId,
queryFilters,
search,
latitude,
longitude,
currentCategoryId,
]
)

function updateFilters(filters: SetStateAction<IActiveFilters>): void {
Expand Down
15 changes: 14 additions & 1 deletion front/example-app/src/utils/TestProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { IApi, IUser, schemaContext } from '@elastic-suite/gally-admin-shared'

import {
ICatalogContext,
ISettingsContext,
catalogContext,
categoryContext,
settingsContext,
userContext,
} from '../contexts'
import { catalogsGraphql, categoriesGraphql } from '../mocks'
Expand Down Expand Up @@ -36,6 +38,13 @@ const catalogContextValue = {
onLocalizedCatalogIdChange: (): void => void null,
} as ICatalogContext

const settingsContextValue: ISettingsContext = {
longitude: '',
latitude: '',
setLatitude: (): void => void null,
setLongitude: (): void => void null,
}

function TestProvider(props: IProps): JSX.Element {
const { api, children } = props

Expand All @@ -51,7 +60,11 @@ function TestProvider(props: IProps): JSX.Element {
<categoryContext.Provider
value={categoriesGraphql.data.getCategoryTree.categories}
>
<RequestedPathProvider>{children}</RequestedPathProvider>
<RequestedPathProvider>
<settingsContext.Provider value={settingsContextValue}>
{children}
</settingsContext.Provider>
</RequestedPathProvider>
</categoryContext.Provider>
</catalogContext.Provider>
</schemaContext.Provider>
Expand Down

0 comments on commit 3233c36

Please sign in to comment.