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
5 changes: 4 additions & 1 deletion src/components/BathroomResourceForm/BathroomResourceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type BathroomResourceFormProps = {
defaultValues?: ResourceEntry | null;
onSubmit: (values: FormValues) => void;
onGoBack?: VoidFunction;
onClose?: VoidFunction;
isSubmitting?: boolean;
};

Expand All @@ -30,13 +31,15 @@ const BathroomResourceForm = ({
defaultValues,
isSubmitting,
onSubmit,
onGoBack
onGoBack,
onClose: onCloseProp
}: BathroomResourceFormProps) => {
const { setToolbarModal } = useToolbarContext();
const onClose = () => {
if (onGoBack) {
onGoBack();
}
onCloseProp?.();

setToolbarModal(null);
};
Expand Down
8 changes: 8 additions & 0 deletions src/components/EditResourceForm/EditResourceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,37 @@ const EditResourceForm = () => {
const resourceForms = {
[ResourceType.WATER]: (
<WaterResourceForm
key={resourceEditCandidate.id}
defaultValues={resourceEditCandidate}
isSubmitting={isPending}
onClose={() => setResourceEditCandidate(null)}
onSubmit={onSubmit}
/>
),
[ResourceType.FOOD]: (
<FoodResourceForm
key={resourceEditCandidate.id}
defaultValues={resourceEditCandidate}
isSubmitting={isPending}
onClose={() => setResourceEditCandidate(null)}
onSubmit={onSubmit}
/>
),
[ResourceType.FORAGE]: (
<ForageResourceForm
key={resourceEditCandidate.id}
defaultValues={resourceEditCandidate}
isSubmitting={isPending}
onClose={() => setResourceEditCandidate(null)}
onSubmit={onSubmit}
/>
),
[ResourceType.BATHROOM]: (
<BathroomResourceForm
key={resourceEditCandidate.id}
defaultValues={resourceEditCandidate}
isSubmitting={isPending}
onClose={() => setResourceEditCandidate(null)}
onSubmit={onSubmit}
/>
)
Expand Down
3 changes: 3 additions & 0 deletions src/components/FoodResourceForm/FoodResourceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type FoodResourceFormProps = {
defaultValues?: ResourceEntry | null;
onSubmit: (values: FormValues) => void;
onGoBack?: VoidFunction;
onClose?: VoidFunction;
isSubmitting?: boolean;
};

Expand All @@ -36,13 +37,15 @@ const FoodResourceForm = ({
defaultValues = null,
isSubmitting = false,
onGoBack,
onClose: onCloseProp,
onSubmit
}: FoodResourceFormProps) => {
const { setToolbarModal } = useToolbarContext();
const onClose = () => {
if (onGoBack) {
onGoBack();
}
onCloseProp?.();

setToolbarModal(null);
};
Expand Down
5 changes: 4 additions & 1 deletion src/components/ForageResourceForm/ForageResourceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ForageResourceFormProps = {
defaultValues?: ResourceEntry | null;
onSubmit: (values: FormValues) => void;
onGoBack?: VoidFunction;
onClose?: VoidFunction;
isSubmitting?: boolean;
};

Expand All @@ -30,13 +31,15 @@ const ForageResourceForm = ({
defaultValues,
isSubmitting,
onSubmit,
onGoBack
onGoBack,
onClose: onCloseProp
}: ForageResourceFormProps) => {
const { setToolbarModal } = useToolbarContext();
const onClose = () => {
if (onGoBack) {
onGoBack();
}
onCloseProp?.();

setToolbarModal(null);
};
Expand Down
3 changes: 3 additions & 0 deletions src/components/WaterResourceForm/WaterResourceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type WaterResourceFormProps = {
defaultValues?: ResourceEntry | null;
onSubmit: (values: FormValues) => void;
onGoBack?: VoidFunction;
onClose?: VoidFunction;
isSubmitting?: boolean;
};

Expand All @@ -31,13 +32,15 @@ const WaterResourceForm = ({
defaultValues = null,
isSubmitting = false,
onGoBack,
onClose: onCloseProp,
onSubmit
}: WaterResourceFormProps) => {
const { setToolbarModal } = useToolbarContext();
const onClose = () => {
if (onGoBack) {
onGoBack();
}
onCloseProp?.();

setToolbarModal(null);
};
Expand Down
62 changes: 42 additions & 20 deletions src/components/forms/FormAddressField/FormResourceAddressField.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Autocomplete, TextField } from '@mui/material';
import { Autocomplete, Box, TextField } from '@mui/material';
import { toLatLngLiteral } from '@vis.gl/react-google-maps';
import useGooglePlacesAutocomplete from 'hooks/useGooglePlacesAutocomplete';
import useAddressFormControllers from 'hooks/useAddressFormControllers';
import UseMyLocationButton from 'components/UseMyLocationButton/UseMyLocationButton';
import getNormalizedAddressComponents from 'utils/getNormalizedAddressComponents';

const LOCATION_NOT_FOUND_ERROR =
"We couldn't find your location, please select an option from the search";

type FormResourceAddressFieldProps = {
label?: string;
fullWidth?: boolean;
Expand All @@ -14,10 +17,16 @@ const FormResourceAddressField = ({
label = 'Address',
fullWidth = false
}: FormResourceAddressFieldProps) => {
const { suggestions, isFetching, onChange, onDebouncedChange } =
const { suggestions, isFetching, onDebouncedChange } =
useGooglePlacesAutocomplete();
const { inputRef, error, onClear, setAddressError, setAddressValues } =
useAddressFormControllers();
const {
inputRef,
addressValue,
error,
onClear,
setAddressError,
setAddressValues
} = useAddressFormControllers();

const onSelect = async (place: google.maps.places.Place) => {
const googlePlacesId = place.id;
Expand Down Expand Up @@ -66,30 +75,36 @@ const FormResourceAddressField = ({

const { places } = await google.maps.places.Place.searchNearby({
locationRestriction: circle,
fields: ['formattedAddress']
fields: ['id', 'formattedAddress']
});

const firstPlace = places.at(0);
if (!firstPlace?.formattedAddress) {
return setAddressError(
"We couldn't find your location, please select an option from the search"
);
return setAddressError(LOCATION_NOT_FOUND_ERROR);
}

onChange(firstPlace.formattedAddress);
await onSelect(firstPlace);
};

return (
<Autocomplete
<Autocomplete<google.maps.places.PlacePrediction | string>
openOnFocus
options={suggestions}
fullWidth={fullWidth}
onInputChange={(_event, value) => {
value={addressValue || null}
onInputChange={(_event, value, reason) => {
if (reason !== 'input') {
return;
}
onDebouncedChange(value);
}}
loading={isFetching}
getOptionKey={option => option.placeId}
getOptionLabel={option => option.text.text}
getOptionKey={option =>
typeof option === 'string' ? option : option.placeId
}
getOptionLabel={option =>
typeof option === 'string' ? option : option.text.text
}
onChange={(_event, value, reason) => {
if (reason === 'clear') {
return onClear();
Expand All @@ -99,7 +114,7 @@ const FormResourceAddressField = ({
return;
}

if (!value) {
if (!value || typeof value === 'string') {
return;
}

Expand All @@ -120,12 +135,19 @@ const FormResourceAddressField = ({
inputRef={inputRef}
error={Boolean(error)}
helperText={
error?.message || (
<UseMyLocationButton
onError={setAddressError}
onSuccess={onGetMyLocationSuccess}
/>
)
<>
{error?.message && (
<Box component="span" sx={{ display: 'block' }}>
{error.message}
</Box>
)}
{error?.message !== LOCATION_NOT_FOUND_ERROR && (
<UseMyLocationButton
onError={setAddressError}
onSuccess={onGetMyLocationSuccess}
/>
)}
</>
}
/>
)}
Expand Down
16 changes: 13 additions & 3 deletions src/hooks/useAddressFormControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type ResourceAddressField =
| 'zip_code';

const useAddressFormControllers = () => {
const { control, setError, resetField } = useFormContext();
const { control, setError } = useFormContext();
const addressController = useController({ name: 'address', control });
const cityController = useController({ name: 'city', control });
const stateController = useController({ name: 'state', control });
Expand Down Expand Up @@ -39,12 +39,22 @@ const useAddressFormControllers = () => {
};

const onClear = () => {
controllers.forEach(controller => resetField(controller.field.name));
setAddressValues({
address: '',
city: '',
state: '',
gp_id: '',
latitude: Number.NaN,
longitude: Number.NaN,
zip_code: ''
});
};

return {
inputRef: addressController.field.ref,
error: addressController.fieldState.error,
addressValue: addressController.field.value,
error:
addressController.fieldState.error ?? latitudeController.fieldState.error,
setAddressValues,
setAddressError,
onClear
Expand Down
25 changes: 19 additions & 6 deletions src/schemas/baseResourceSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ const baseResourceSchema = z.object({
version: z.number().optional().default(1),
name: z.string().nonempty('Name is required').default(''),
address: z.string().nonempty('Address is required').default(''),
gp_id: z.string().nonempty('Google Places ID is required').default(''),
gp_id: z.string().default(''),
city: z.string().default(''),
state: z.string().default(''),
zip_code: z.string().default(''),
latitude: z.number().default(Number.NaN),
longitude: z.number().default(Number.NaN),
latitude: z
.number({ message: 'Please select an address from the list' })
.default(Number.NaN),
longitude: z
.number({ message: 'Please select an address from the list' })
.default(Number.NaN),
date_created: z.iso.datetime().default(() => new Date().toISOString()),
last_modifier: z.string().default('phlask_app'),
last_modified: z.iso.datetime().default(() => new Date().toISOString()),
Expand All @@ -30,15 +34,18 @@ const baseResourceSchema = z.object({
verification: z
.object({
verified: z.boolean().default(false),
last_modified: z.iso.datetime().default(() => new Date().toISOString()),
last_modified: z.iso.datetime().catch(() => new Date().toISOString()),
verifier: z.string().default('')
})
.default(() => ({
verified: false,
last_modified: new Date().toISOString(),
verifier: ''
})),
images: z.array(z.string()).default([]),
images: z
.array(z.string().nullable())
.default([])
.transform(images => images.filter(image => image !== null)),
guidelines: z.string().default(''),
resource_type: z.enum(
[
Expand All @@ -50,7 +57,13 @@ const baseResourceSchema = z.object({
{ message: 'Resource type is required' }
),
status: z
.enum(['OPERATIONAL', 'TEMPORARILY_CLOSED', 'PERMANENTLY_CLOSED', 'HIDDEN'])
.enum([
'OPERATIONAL',
'TEMPORARILY_CLOSED',
'PERMANENTLY_CLOSED',
'HIDDEN',
'NONOPERATIONAL'
])
.default('OPERATIONAL')
});

Expand Down
22 changes: 12 additions & 10 deletions src/schemas/bathroomResourceSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ const bathroomResourceSchema = baseResourceSchema.extend({
.default(ResourceType.BATHROOM),
bathroom: z
.object({
tags: z.array(
z.enum([
'WHEELCHAIR_ACCESSIBLE',
'GENDER_NEUTRAL',
'CHANGING_TABLE',
'SINGLE_OCCUPANCY',
'HAS_FOUNTAIN',
'FAMILY'
])
)
tags: z
.array(
z.enum([
'WHEELCHAIR_ACCESSIBLE',
'GENDER_NEUTRAL',
'CHANGING_TABLE',
'SINGLE_OCCUPANCY',
'HAS_FOUNTAIN',
'FAMILY'
])
)
.default([])
})
.default({ tags: [] })
});
Expand Down
Loading
Loading