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 22, 2024
1 parent 3a3cbc3 commit 3a1bd72
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 7 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 @@ -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, locationContext } 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 (
<locationContext.Provider value={context}>
{children}
</locationContext.Provider>
)
}

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

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

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

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

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

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

if (open) {
document.addEventListener('mousedown', handleClickOutside)
} else {
document.removeEventListener('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),
}))

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}>
<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,
}}
/>

<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'
11 changes: 11 additions & 0 deletions front/example-app/src/contexts/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Dispatch, SetStateAction, createContext } from 'react'

export interface ISettingsContext {
longitude: string
latitude: string
// onChange: (newLongitude: string, newLattitude: sting) => void,
setLongitude: Dispatch<SetStateAction<ISettingsContext['longitude']>>
setLatitude: Dispatch<SetStateAction<ISettingsContext['latitude']>>
}

export const locationContext = createContext<ISettingsContext>(null)
27 changes: 23 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, locationContext } 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(locationContext)

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 @@ -131,7 +142,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 @@ -158,7 +177,7 @@ export function useProducts(
}
})
},
[graphqlApi, localizedCatalogId, queryFilters, search]
[graphqlApi, localizedCatalogId, queryFilters, search, latitude, longitude]
)

function updateFilters(filters: SetStateAction<IActiveFilters>): void {
Expand Down

0 comments on commit 3a1bd72

Please sign in to comment.