Skip to content

Commit

Permalink
feat: add user preferences form and colorblind mod
Browse files Browse the repository at this point in the history
  • Loading branch information
MaGOs92 committed Aug 8, 2023
1 parent 6923b33 commit ad25161
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 63 deletions.
25 changes: 19 additions & 6 deletions components/map/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MapGl, {Source, Layer} from 'react-map-gl'
import maplibregl from 'maplibre-gl'
import {Pane, Alert} from 'evergreen-ui'

import MapContext, {BAL_API_URL, SOURCE_TILE_ID} from '@/contexts/map'
import MapContext, {SOURCE_TILE_ID} from '@/contexts/map'
import TokenContext from '@/contexts/token'
import DrawContext from '@/contexts/draw'
import ParcellesContext from '@/contexts/parcelles'
Expand Down Expand Up @@ -81,7 +81,9 @@ function Map({commune, isAddressFormOpen, handleAddressForm}) {
viewport,
setViewport,
isCadastreDisplayed,
setIsCadastreDisplayed
setIsCadastreDisplayed,
balTilesUrl,
isMapLoaded
} = useContext(MapContext)
const {isParcelleSelectionEnabled, handleParcelle} = useContext(ParcellesContext)

Expand All @@ -90,7 +92,6 @@ function Map({commune, isAddressFormOpen, handleAddressForm}) {
const [mapStyle, setMapStyle] = useState(generateNewStyle(defaultStyle))

const {balId} = router.query
const BAL_TILES_URL = BAL_API_URL + '/bases-locales/' + balId + '/tiles/{z}/{x}/{y}.pbf'
const {
voie,
toponyme,
Expand Down Expand Up @@ -244,10 +245,10 @@ function Map({commune, isAddressFormOpen, handleAddressForm}) {
return {
id: SOURCE_TILE_ID,
type: 'vector',
tiles: [BAL_TILES_URL],
tiles: [balTilesUrl],
promoteId: 'id',
}
}, [BAL_TILES_URL])
}, [balTilesUrl])

const sourceCommune = useMemo(() => {
return {
Expand Down Expand Up @@ -276,6 +277,18 @@ function Map({commune, isAddressFormOpen, handleAddressForm}) {
}
}

const selectedVoieColor = useMemo(() => {
if (!voie || !isMapLoaded) {
return
}

const featuresList = map?.querySourceFeatures(SOURCE_TILE_ID, {
sourceLayer: [LAYERS_SOURCE.VOIES_POINTS]
})

return featuresList?.find(feature => feature.id === voie._id)?.properties.color
}, [map, voie, isMapLoaded])

return (
<Pane display='flex' flexDirection='column' flex={1}>
<StyleControl
Expand Down Expand Up @@ -346,10 +359,10 @@ function Map({commune, isAddressFormOpen, handleAddressForm}) {
{(voie || toponyme) && !modeId && numeros && (
<NumerosMarkers
numeros={numeros.filter(({_id}) => _id !== editingId)}
voie={voie}
isLabelDisplayed={isLabelsDisplayed}
isContextMenuDisplayed={isContextMenuDisplayed}
setIsContextMenuDisplayed={setIsContextMenuDisplayed}
color={selectedVoieColor}
/>
)}

Expand Down
22 changes: 6 additions & 16 deletions components/map/numeros-markers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {useCallback, useContext} from 'react'
import PropTypes from 'prop-types'
import {css} from 'glamor'
import randomColor from 'randomcolor'

import {softRemoveNumero} from '@/lib/bal-api'

Expand All @@ -13,7 +12,7 @@ import useError from '@/hooks/error'

import NumeroMarker from '@/components/map/numero-marker'

function NumerosMarkers({numeros, voie, isLabelDisplayed, isContextMenuDisplayed, setIsContextMenuDisplayed}) {
function NumerosMarkers({numeros, isLabelDisplayed, isContextMenuDisplayed, setIsContextMenuDisplayed, color}) {
const [setError] = useError()

const {token} = useContext(TokenContext)
Expand All @@ -32,14 +31,7 @@ function NumerosMarkers({numeros, voie, isLabelDisplayed, isContextMenuDisplayed
}
}, [setEditingId, setIsContextMenuDisplayed, isEditing])

const colorSeed = useCallback(id => {
return id ? randomColor({
luminosity: 'dark',
seed: id
}) : '#1070ca'
}, [])

const markerStyle = useCallback(colorSeed => css({
const markerStyle = useCallback(color => css({
borderRadius: 20,
marginTop: -10,
marginLeft: -10,
Expand All @@ -50,7 +42,7 @@ function NumerosMarkers({numeros, voie, isLabelDisplayed, isContextMenuDisplayed

'&:before': {
content: ' ',
backgroundColor: colorSeed,
backgroundColor: color,
border: '1px solid white',
display: 'inline-block',
width: 8,
Expand Down Expand Up @@ -91,7 +83,7 @@ function NumerosMarkers({numeros, voie, isLabelDisplayed, isContextMenuDisplayed
<NumeroMarker
key={numero._id}
numero={numero}
style={markerStyle(colorSeed(numero.voie?._id || voie?._id))}
style={markerStyle(color)}
isContextMenuDisplayed={numero._id === isContextMenuDisplayed}
removeAddress={removeAddress}
onEnableEditing={onEnableEditing}
Expand All @@ -102,12 +94,10 @@ function NumerosMarkers({numeros, voie, isLabelDisplayed, isContextMenuDisplayed

NumerosMarkers.propTypes = {
numeros: PropTypes.array.isRequired,
voie: PropTypes.shape({
_id: PropTypes.string.isRequired
}),
isLabelDisplayed: PropTypes.bool.isRequired,
isContextMenuDisplayed: PropTypes.string,
setIsContextMenuDisplayed: PropTypes.func.isRequired
setIsContextMenuDisplayed: PropTypes.func.isRequired,
color: PropTypes.string
}

export default NumerosMarkers
42 changes: 26 additions & 16 deletions components/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,40 @@ import {SideSheet, Pane, Alert} from 'evergreen-ui'
import SettingsContext from '@/contexts/settings'
import BalDataContext from '@/contexts/bal-data'

import SettingsForm from '@/components/settings/settings-form'
import BALSettingsForm from '@/components/settings/bal-settings-form'
import UserSettingsForm from '@/components/settings/user-settings-form'

const Settings = React.memo(() => {
const {isSettingsDisplayed, setIsSettingsDisplayed} = useContext(SettingsContext)
const {settingsDisplayed, setSettingsDisplayed} = useContext(SettingsContext)
const {baseLocale} = useContext(BalDataContext)

return (
<SideSheet
isShown={isSettingsDisplayed}
onCloseComplete={() => setIsSettingsDisplayed(false)}
isShown={Boolean(settingsDisplayed)}
onCloseComplete={() => setSettingsDisplayed(null)}
>
<SettingsForm baseLocale={baseLocale} />

{baseLocale.status === 'demo' && (
<Pane padding={16}>
<Alert
intent='none'
title='Version d’essai de l’éditeur de base adresse locale'
marginBottom={32}
>
Il est impossible de modifier les paramètres de la base adresse locale en version d’essai.
</Alert>
</Pane>
{settingsDisplayed === 'user-settings' && (
<UserSettingsForm baseLocale={baseLocale} />
)}

{settingsDisplayed === 'bal-settings' && (
<>
<BALSettingsForm baseLocale={baseLocale} />

{baseLocale.status === 'demo' && (
<Pane padding={16}>
<Alert
intent='none'
title='Version d’essai de l’éditeur de base adresse locale'
marginBottom={32}
>
Il est impossible de modifier les paramètres de la base adresse locale en version d’essai.
</Alert>
</Pane>
)}
</>
)}

</SideSheet>
)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const mailHasChanged = (listA, listB) => {
return !isEqual([...listA].sort(), [...listB].sort())
}

const Settings = React.memo(({baseLocale}) => {
const BALSettings = React.memo(({baseLocale}) => {
const {token, emails, reloadEmails} = useContext(TokenContext)
const {reloadBaseLocale} = useContext(BalDataContext)

Expand Down Expand Up @@ -227,12 +227,12 @@ const Settings = React.memo(({baseLocale}) => {
)
})

Settings.propTypes = {
BALSettings.propTypes = {
baseLocale: PropTypes.shape({
_id: PropTypes.string.isRequired,
status: PropTypes.string.isRequired,
nom: PropTypes.string.isRequired
}).isRequired
}

export default Settings
export default BALSettings
78 changes: 78 additions & 0 deletions components/settings/user-settings-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {useContext, useState} from 'react'
import LocalStorageContext from '@/contexts/local-storage'
import PropTypes from 'prop-types'
import {
Pane,
Heading,
Button,
Checkbox,
toaster
} from 'evergreen-ui'

import FormContainer from '@/components/form-container'
import FormInput from '@/components/form-input'

function UserSettings() {
const {userSettings, setUserSettings} = useContext(LocalStorageContext)
const [userSettingsForm, setUserSettingsForm] = useState(userSettings)

const hasChanged = () => JSON.stringify(userSettingsForm) !== JSON.stringify(userSettings)

const onSubmit = e => {
e.preventDefault()
setUserSettings(userSettingsForm)
toaster.success('Les préférences utilisateurs ont été enregistrées avec succès !')
}

return (
<Pane>
<Pane
flexShrink={0}
elevation={0}
background='white'
padding={16}
display='flex'
alignItems='center'
minHeight={64}
>
<Pane>
<Heading>Préférences utilisateur</Heading>
</Pane>
</Pane>

<Pane
display='flex'
flex={1}
flexDirection='column'
overflowY='scroll'
>
<FormContainer onSubmit={onSubmit}>
<FormInput>
<Checkbox
name='colorblind-mode'
id='colorblind-mode'
label='Activer le mode daltonien'
checked={userSettingsForm?.colorblindMode}
onChange={() => setUserSettingsForm(settings => ({...settings, colorblindMode: !settings?.colorblindMode}))}
/>
</FormInput>

<Button height={40} marginTop={8} type='submit' appearance='primary' disabled={!hasChanged()}>
Enregistrer les changements
</Button>

</FormContainer>
</Pane>
</Pane>
)
}

UserSettings.propTypes = {
baseLocale: PropTypes.shape({
_id: PropTypes.string.isRequired,
status: PropTypes.string.isRequired,
nom: PropTypes.string.isRequired
}).isRequired
}

export default UserSettings
27 changes: 15 additions & 12 deletions components/sub-header/settings-menu.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {useContext} from 'react'
import PropTypes from 'prop-types'
import {Popover, Menu, Position, Button, CogIcon, DownloadIcon, TrashIcon} from 'evergreen-ui'
import {Popover, Menu, Position, Button, CogIcon, DownloadIcon, TrashIcon, SettingsIcon} from 'evergreen-ui'

import SettingsContext from '@/contexts/settings'

function SettingsMenu({isAdmin, csvBalUrl, csvVoiesUrl, setIsTrashOpen}) {
const {isSettingsDisplayed, setIsSettingsDisplayed} = useContext(SettingsContext)
const {setSettingsDisplayed} = useContext(SettingsContext)

return (
<Popover
Expand All @@ -16,8 +16,6 @@ function SettingsMenu({isAdmin, csvBalUrl, csvVoiesUrl, setIsTrashOpen}) {
<Menu.Item icon={DownloadIcon} is='a' href={csvBalUrl} color='inherit' textDecoration='none'>
Télécharger Base Locale CSV
</Menu.Item>
</Menu.Group>
<Menu.Group>
<Menu.Item icon={DownloadIcon} is='a' href={csvVoiesUrl} color='inherit' textDecoration='none'>
Télécharger liste des voies CSV
</Menu.Item>
Expand All @@ -30,14 +28,19 @@ function SettingsMenu({isAdmin, csvBalUrl, csvVoiesUrl, setIsTrashOpen}) {
Voir la corbeille
</Menu.Item>
</Menu.Group>
<Menu.Divider />
<Menu.Group>
<Menu.Item icon={CogIcon} onSelect={() => setIsSettingsDisplayed(!isSettingsDisplayed)}>
Gérer les droits
</Menu.Item>
</Menu.Group>
</>
)}
</>)}
<Menu.Divider />
<Menu.Group>
<Menu.Item icon={SettingsIcon} onSelect={() => setSettingsDisplayed('user-settings')}>
Préférences utilisateur
</Menu.Item>
{isAdmin && (
<Menu.Item icon={CogIcon} onSelect={() => setSettingsDisplayed('bal-settings')}>
Gérer les droits
</Menu.Item>
)}
</Menu.Group>

</Menu>
}
>
Expand Down
12 changes: 10 additions & 2 deletions contexts/local-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ const WELCOMED_KEY = 'was-welcomed'
const RECOVERY_EMAIL = 'recovery-email-sent'
const CERTIFICATION_AUTO_KEY = 'certificationAutoAlert'
const VISIBILITY_KEY = 'hidden-bal'
const USER_SETTINGS = 'user-settings'

export function LocalStorageContextProvider(props) {
const [balAccess, , getBalToken, addBalAccess, removeBalAccess] = useLocalStorage(STORAGE_KEY) // Do not assign a default value
const [wasWelcomed, setWasWelcomed] = useLocalStorage(WELCOMED_KEY)
const [recoveryEmailSent, setRecoveryEmailSent] = useLocalStorage(RECOVERY_EMAIL)
const [informedAboutCertification, , getInformedAboutCertification, addInformedAboutCertification] = useLocalStorage(CERTIFICATION_AUTO_KEY)
const [hiddenBal, setHiddenBal, getHiddenBal, addHiddenBal, removeHiddenBal] = useLocalStorage(VISIBILITY_KEY)
const [userSettings, setUserSettings, getUserSettings, addUserSettings, removeUserSettings] = useLocalStorage(USER_SETTINGS)

const removeBAL = useCallback(async balId => {
const token = getBalToken(balId)
Expand All @@ -30,7 +32,8 @@ export function LocalStorageContextProvider(props) {
wasWelcomed, setWasWelcomed,
recoveryEmailSent, setRecoveryEmailSent,
informedAboutCertification, getInformedAboutCertification, addInformedAboutCertification,
hiddenBal, setHiddenBal, getHiddenBal, addHiddenBal, removeHiddenBal
hiddenBal, setHiddenBal, getHiddenBal, addHiddenBal, removeHiddenBal,
userSettings, setUserSettings, getUserSettings, addUserSettings, removeUserSettings
}), [
balAccess,
getBalToken,
Expand All @@ -47,7 +50,12 @@ export function LocalStorageContextProvider(props) {
setHiddenBal,
getHiddenBal,
addHiddenBal,
removeHiddenBal
removeHiddenBal,
userSettings,
setUserSettings,
getUserSettings,
addUserSettings,
removeUserSettings
])

return (
Expand Down
Loading

0 comments on commit ad25161

Please sign in to comment.