Skip to content

Commit

Permalink
feat: add geolocation modal (#1112)
Browse files Browse the repository at this point in the history
* refactor: add geolocation modal

* refactor: add translations

* refactor: update fr trans

* refactor: upgrade query client
  • Loading branch information
pyphilia authored Mar 26, 2024
1 parent 4cef3af commit efcda2e
Show file tree
Hide file tree
Showing 7 changed files with 347 additions and 114 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.0",
"@graasp/chatbox": "3.1.0",
"@graasp/map": "1.4.0",
"@graasp/query-client": "3.0.1",
"@graasp/sdk": "4.2.1",
"@graasp/map": "1.5.0",
"@graasp/query-client": "3.2.0",
"@graasp/sdk": "4.3.1",
"@graasp/translations": "1.25.3",
"@graasp/ui": "4.11.0",
"@graasp/ui": "4.12.1",
"@mui/icons-material": "5.15.11",
"@mui/lab": "5.0.0-alpha.166",
"@mui/material": "5.15.11",
Expand Down
156 changes: 156 additions & 0 deletions src/components/item/settings/GeolocationModalButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { useRef, useState } from 'react';

import {
DialogActions,
DialogContent,
DialogContentText,
Stack,
TextField,
} from '@mui/material';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';

import { CountryForm } from '@graasp/map';
import { DiscriminatedItem } from '@graasp/sdk';
import { COMMON } from '@graasp/translations';
import { Button } from '@graasp/ui';

import { useBuilderTranslation, useCommonTranslation } from '@/config/i18n';
import notifier from '@/config/notifier';
import { hooks, mutations } from '@/config/queryClient';
import { BUILDER } from '@/langs/constants';

type Props = {
item: DiscriminatedItem;
};

export const GeolocationModalButton = ({ item }: Props): JSX.Element => {
const { t } = useBuilderTranslation();
const { t: commonT } = useCommonTranslation();
const [open, setOpen] = useState(false);
const { data: geoloc } = hooks.useItemGeolocation(item.id);
const { mutate: saveGeoloc } = mutations.usePutItemGeolocation();

const helperLabelRef = useRef<HTMLInputElement>(null);
const addressLabelRef = useRef<HTMLInputElement>(null);
const latRef = useRef<HTMLInputElement>(null);
const lngRef = useRef<HTMLInputElement>(null);
const [country, setCountry] = useState<string>();

const handleClickOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

const onSave = () => {
const lat = latRef.current?.value ?? geoloc?.lat;
const lng = lngRef.current?.value ?? geoloc?.lng;

if (!lat || !lng) {
notifier({
type: 'PUT_GEOLOCATION_ERROR',
payload: {
error: new Error(t(BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_ERROR)),
},
});
return;
}

saveGeoloc({
itemId: item.id,
geolocation: {
helperLabel: helperLabelRef.current?.value ?? geoloc?.helperLabel,
addressLabel: addressLabelRef.current?.value ?? geoloc?.addressLabel,
country: country ?? geoloc?.country,
lat: +lat,
lng: +lng,
},
});
setOpen(false);
};

return (
<>
<Button variant="text" onClick={handleClickOpen}>
{t(BUILDER.ITEM_GEOLOCATION_ADVANCED_BUTTON)}
</Button>
<Dialog onClose={handleClose} open={open} scroll="body">
<DialogTitle>
{t(BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_TITLE)}
</DialogTitle>

<DialogContent>
<Stack gap={2}>
<Stack>
<DialogContentText>
{t(BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_DESCRIPTION)}
</DialogContentText>
</Stack>
<Stack direction="row" gap={2}>
<Stack flexGrow={1}>
<TextField
inputRef={latRef}
defaultValue={geoloc?.lat}
label={t(
BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_LATITUDE_LABEL,
)}
type="number"
/>
</Stack>
<Stack flexGrow={1}>
<TextField
inputRef={lngRef}
defaultValue={geoloc?.lng}
label={t(
BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_LONGITUDE_LABEL,
)}
type="number"
/>
</Stack>
</Stack>
<Stack>
<TextField
inputRef={addressLabelRef}
label={t(BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_ADDRESS_LABEL)}
multiline
defaultValue={geoloc?.addressLabel ?? undefined}
/>
</Stack>
<Stack>
<TextField
inputRef={helperLabelRef}
defaultValue={geoloc?.helperLabel ?? undefined}
multiline
label={t(
BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_LABEL,
)}
placeholder={t(
BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_PLACEHOLDER,
)}
/>
</Stack>
<Stack>
<CountryForm
label={t(BUILDER.ITEM_GEOLOCATION_ADVANCED_MODAL_COUNTRY_LABEL)}
initialValue={geoloc?.country ?? undefined}
onChange={(e) => {
// eslint-disable-next-line no-console
setCountry(e.alpha2);
}}
/>
</Stack>
</Stack>
</DialogContent>
<DialogActions>
<Button variant="text">{commonT(COMMON.CANCEL_BUTTON)}</Button>
<Button onClick={onSave}>{commonT(COMMON.SAVE_BUTTON)}</Button>
</DialogActions>
</Dialog>
</>
);
};

export default GeolocationModalButton;
61 changes: 33 additions & 28 deletions src/components/item/settings/GeolocationPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { useBuilderTranslation } from '@/config/i18n';
import { hooks, mutations } from '@/config/queryClient';
import { BUILDER } from '@/langs/constants';

import GeolocationModalButton from './GeolocationModalButton';

const GeolocationPicker = ({
item,
}: {
Expand Down Expand Up @@ -48,37 +50,40 @@ const GeolocationPicker = ({
const isDisabled = Boolean(geoloc && geoloc?.item?.id !== item.id);

return (
<Stack mt={2}>
<Stack>
<Typography variant="h6">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_TITLE)}
</Typography>
<Typography variant="subtitle1">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_EXPLANATION)}
</Typography>
</Stack>
<Stack direction="row" alignItems="center">
<Stack flexGrow={1}>
<MapGeolocationPicker
onChangeOption={onChangeOption}
initialValue={geoloc?.addressLabel ?? undefined}
useSuggestionsForAddress={hooks.useSuggestionsForAddress}
/>
</Stack>
<>
<Stack mt={2} gap={2}>
<Stack>
<Tooltip title={t(BUILDER.ITEM_SETTINGS_CLEAR_GEOLOCATION)}>
<IconButton onClick={clearGeoloc}>
<Clear />
</IconButton>
</Tooltip>
<Typography variant="h6">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_TITLE)}
</Typography>
<Typography variant="subtitle1">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_EXPLANATION)}
</Typography>
</Stack>
<Stack direction="row" alignItems="center">
<Stack flexGrow={1}>
<MapGeolocationPicker
onChangeOption={onChangeOption}
initialValue={geoloc?.addressLabel ?? undefined}
useSuggestionsForAddress={hooks.useSuggestionsForAddress}
/>
</Stack>
<Stack>
<Tooltip title={t(BUILDER.ITEM_SETTINGS_CLEAR_GEOLOCATION)}>
<IconButton onClick={clearGeoloc}>
<Clear />
</IconButton>
</Tooltip>
</Stack>
</Stack>
{isDisabled && (
<Typography variant="caption">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_INHERITED_EXPLANATION)}
</Typography>
)}
</Stack>
{isDisabled && (
<Typography variant="caption">
{t(BUILDER.ITEM_SETTINGS_GEOLOCATION_INHERITED_EXPLANATION)}
</Typography>
)}
</Stack>
<GeolocationModalButton item={item} />
</>
);
};

Expand Down
19 changes: 19 additions & 0 deletions src/langs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,4 +420,23 @@ export const BUILDER = {
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW',
ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE:
'ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE',
ITEM_GEOLOCATION_ADVANCED_BUTTON: 'ITEM_GEOLOCATION_ADVANCED_BUTTON',
ITEM_GEOLOCATION_ADVANCED_MODAL_TITLE:
'ITEM_GEOLOCATION_ADVANCED_MODAL_TITLE',
ITEM_GEOLOCATION_ADVANCED_MODAL_DESCRIPTION:
'ITEM_GEOLOCATION_ADVANCED_MODAL_DESCRIPTION',
ITEM_GEOLOCATION_ADVANCED_MODAL_LATITUDE_LABEL:
'ITEM_GEOLOCATION_ADVANCED_MODAL_LATITUDE_LABEL',
ITEM_GEOLOCATION_ADVANCED_MODAL_LONGITUDE_LABEL:
'ITEM_GEOLOCATION_ADVANCED_MODAL_LONGITUDE_LABEL',
ITEM_GEOLOCATION_ADVANCED_MODAL_ADDRESS_LABEL:
'ITEM_GEOLOCATION_ADVANCED_MODAL_ADDRESS_LABEL',
ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_LABEL:
'ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_LABEL',
ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_PLACEHOLDER:
'ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_PLACEHOLDER',
ITEM_GEOLOCATION_ADVANCED_MODAL_COUNTRY_LABEL:
'ITEM_GEOLOCATION_ADVANCED_MODAL_COUNTRY_LABEL',
ITEM_GEOLOCATION_ADVANCED_MODAL_ERROR:
'ITEM_GEOLOCATION_ADVANCED_MODAL_ERROR',
};
12 changes: 11 additions & 1 deletion src/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,15 @@
"ITEM_SETTINGS_IS_COLLAPSED_TITLE": "Collapse item",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Above the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "Below the content",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement of the description"
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement of the description",
"ITEM_GEOLOCATION_ADVANCED_BUTTON": "Advanced Location",
"ITEM_GEOLOCATION_ADVANCED_MODAL_TITLE": "Geolocation Advanced Settings",
"ITEM_GEOLOCATION_ADVANCED_MODAL_DESCRIPTION": "Any information submitted with this form won't be validated. You are responsible for the accuracy of the data.",
"ITEM_GEOLOCATION_ADVANCED_MODAL_LATITUDE_LABEL": "Latitude",
"ITEM_GEOLOCATION_ADVANCED_MODAL_LONGITUDE_LABEL": "Longitude",
"ITEM_GEOLOCATION_ADVANCED_MODAL_ADDRESS_LABEL": "Address",
"ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_LABEL": "Complementary information (optional)",
"ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_PLACEHOLDER": "red door on the right, ...",
"ITEM_GEOLOCATION_ADVANCED_MODAL_COUNTRY_LABEL": "Country",
"ITEM_GEOLOCATION_ADVANCED_MODAL_ERROR": "Latitude and longitude have to be defined"
}
12 changes: 11 additions & 1 deletion src/langs/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -340,5 +340,15 @@
"ITEM_SETTINGS_IS_COLLAPSED_TITLE": "Minifier un élément",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_ABOVE": "Au-dessus du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_BELOW": "En-dessous du contenu",
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement de la description"
"ITEM_SETTINGS_DESCRIPTION_PLACEMENT_TITLE": "Placement de la description",
"ITEM_GEOLOCATION_ADVANCED_BUTTON": "Localisation avancée",
"ITEM_GEOLOCATION_ADVANCED_MODAL_TITLE": "Paramètres avancés pour la localisation",
"ITEM_GEOLOCATION_ADVANCED_MODAL_DESCRIPTION": "Les informations fournies via ce formulaire ne sont pas validées. Vérifiez l'exactitude des données.",
"ITEM_GEOLOCATION_ADVANCED_MODAL_LATITUDE_LABEL": "Latitude",
"ITEM_GEOLOCATION_ADVANCED_MODAL_LONGITUDE_LABEL": "Longitude",
"ITEM_GEOLOCATION_ADVANCED_MODAL_ADDRESS_LABEL": "Adresse",
"ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_LABEL": "Informations complémentaires (optionel)",
"ITEM_GEOLOCATION_ADVANCED_MODAL_SECONDARY_ADDRESS_PLACEHOLDER": "porte rouge sur la droite, ...",
"ITEM_GEOLOCATION_ADVANCED_MODAL_COUNTRY_LABEL": "Pays",
"ITEM_GEOLOCATION_ADVANCED_MODAL_ERROR": "La latitude et longitude doivent être définies"
}
Loading

0 comments on commit efcda2e

Please sign in to comment.