Skip to content

Commit

Permalink
add offline support for location fields
Browse files Browse the repository at this point in the history
  • Loading branch information
dylmye committed Apr 14, 2023
1 parent c65b263 commit be8efc0
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 70 deletions.
36 changes: 9 additions & 27 deletions src/components/AddTripItemCard/AddEditTripItemForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import {
CardActions,
Divider,
Grid,
TextFieldProps,
ToggleButton,
} from "@mui/material";
import { GooglePlacesAutocompleteField } from "@dylmye/mui-google-places-autocomplete";

import TripItemTypeAdornment from "../TripItemTypeAdornment";
import LocationField from "../fields/LocationField";
import IntlPriceField from "../fields/IntlPriceField";
import AutocompleteField from "../fields/AutocompleteField";
import {
Expand All @@ -32,9 +31,6 @@ import {
tripItemExtraFields,
} from "../../helpers/tripItems";
import { butcherDatetimeTimezone } from "../../helpers/dates";
import { useCustomTheme } from "../../contexts/CustomTheme";
import poweredByGoogleLightMode from "../../assets/images/powered_by_google_light_mode.png";
import poweredByGoogleDarkMode from "../../assets/images/powered_by_google_dark_mode.png";
import styles from "./styles.module.css";

export interface AddEditTripItemFormProps {
Expand All @@ -53,21 +49,8 @@ const AddEditTripItemForm = ({
}: AddEditTripItemFormProps) => {
const { isSubmitting, setFieldValue, values, errors } =
useFormikContext<TripItemDraft>();
const { theme } = useCustomTheme();
const currentFieldSettings = customFieldSettings(values.type);

const googleAttributionHelperText: TextFieldProps = {
helperText: (
<img
src={
theme === "light" ? poweredByGoogleLightMode : poweredByGoogleDarkMode
}
alt="This location search field uses Google APIs."
className={styles.googleAttribution}
/>
),
};

const fieldIsRequired = (value: string): string | null =>
!value ? "This field is required" : null;

Expand Down Expand Up @@ -214,12 +197,11 @@ const AddEditTripItemForm = ({
{currentFieldSettings.hasOrigin && (
<Grid item xs={12} md={6}>
<FastField
component={GooglePlacesAutocompleteField}
component={LocationField}
name={
values.category === "travel" ? "originLocation" : "location"
}
label={currentFieldSettings.originLocationLabel ?? "Location"}
inputProps={googleAttributionHelperText}
autocompletionRequest={
values.type === TripItemType.Plane && {
types: ["airport"],
Expand All @@ -231,19 +213,19 @@ const AddEditTripItemForm = ({
{values.category === "travel" && (
<Grid item xs={12} md={6}>
<Field
component={GooglePlacesAutocompleteField}
component={LocationField}
name="destinationLocation"
label={currentFieldSettings.destinationLocationLabel}
disabled={
(!values.originLocation && !values.destinationLocation) ||
isSubmitting
}
inputProps={{
helperText:
errors?.destinationLocation ??
googleAttributionHelperText.helperText,
error: !!errors?.destinationLocation,
}}
inputProps={
errors && {
helperText: errors?.destinationLocation,
error: !!errors?.destinationLocation,
}
}
validate={(value: string) => {
if (!!values.originLocation && !value) {
return "Destination required";
Expand Down
53 changes: 16 additions & 37 deletions src/components/AddTripModal/FormStepOne.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,24 @@
import React from "react";
import { TextField } from "formik-mui";
import { FastField } from "formik";
import { TextFieldProps } from "@mui/material";
import { GooglePlacesAutocompleteField } from "@dylmye/mui-google-places-autocomplete";

import { useCustomTheme } from "../../contexts/CustomTheme";
import poweredByGoogleLightMode from "../../assets/images/powered_by_google_light_mode.png";
import poweredByGoogleDarkMode from "../../assets/images/powered_by_google_dark_mode.png";
import LocationField from "../fields/LocationField";
import styles from "./styles.module.css";

const FormStepOne = () => {
const { theme } = useCustomTheme();

const googleAttributionHelperText: TextFieldProps = {
helperText: (
<img
src={
theme === "light" ? poweredByGoogleLightMode : poweredByGoogleDarkMode
}
alt="This location search field uses Google APIs."
className={styles.googleAttribution}
/>
),
};

return (
<div className={styles.formFieldsContainer}>
<FastField
component={TextField}
fullWidth
name="title"
label="Name of your trip"
/>
<FastField
component={GooglePlacesAutocompleteField}
name="location"
label="Where are you going?"
inputProps={googleAttributionHelperText}
/>
</div>
);
};
const FormStepOne = () => (
<div className={styles.formFieldsContainer}>
<FastField
component={TextField}
fullWidth
name="title"
label="Name of your trip"
/>
<FastField
component={LocationField}
name="location"
label="Where are you going?"
/>
</div>
);

export default FormStepOne;
14 changes: 10 additions & 4 deletions src/components/dialogs/EditTripDetailsModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import dayjs from "dayjs";
import CardActions from "@mui/material/CardActions";
import { Box, Button, Modal, SxProps, Theme, Typography } from "@mui/material";
import { Check } from "@mui/icons-material";
import { GooglePlacesAutocompleteField } from "@dylmye/mui-google-places-autocomplete";

import LocationField from "../../fields/LocationField";
import BetterSwitchField from "../../fields/BetterSwitchField";
import TripDetails from "../../../types/TripDetails";
import ModalProps from "../../../types/ModalProps";
import { useUpdateTrip } from "../../../store/features/trips";
import { useIsLoggedIn } from "../../../store/features/auth";
import { useOnlineStatus } from "../../../contexts/OnlineStatus";
import styles from "./styles.module.css";

export interface EditTripDetailsModalProps extends ModalProps {
Expand Down Expand Up @@ -42,6 +43,7 @@ const EditTripDetailsModal = ({
const updateTrip = useUpdateTrip();
const { enqueueSnackbar } = useSnackbar();
const isLoggedIn = useIsLoggedIn();
const { online: isOnline } = useOnlineStatus();
const {
title,
location,
Expand Down Expand Up @@ -86,7 +88,7 @@ const EditTripDetailsModal = ({
fullWidth
/>
<FastField
component={GooglePlacesAutocompleteField}
component={LocationField}
name="location"
label="Location"
/>
Expand Down Expand Up @@ -122,9 +124,13 @@ const EditTripDetailsModal = ({
component={BetterSwitchField}
name="public"
label={`Share this trip with others${
!isLoggedIn ? " (requires an account)" : ""
!isLoggedIn
? " (requires an account)"
: !isOnline
? " (go online to change)"
: ""
}`}
disabled={!isLoggedIn}
disabled={!isLoggedIn || !isOnline}
/>
<CardActions sx={{ justifyContent: "right" }}>
<Button
Expand Down
56 changes: 56 additions & 0 deletions src/components/fields/LocationField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from "react";
import { TextField } from "formik-mui";
import { FieldProps } from "formik";
import { TextFieldProps } from "@mui/material";
import { GooglePlacesAutocompleteField } from "@dylmye/mui-google-places-autocomplete";

import { useOnlineStatus } from "../../../contexts/OnlineStatus";
import { useCustomTheme } from "../../../contexts/CustomTheme";
import poweredByGoogleLightMode from "../../../assets/images/powered_by_google_light_mode.png";
import poweredByGoogleDarkMode from "../../../assets/images/powered_by_google_dark_mode.png";
import styles from "./styles.module.css";

interface LocationFieldProps extends FieldProps {
inputProps?: TextFieldProps;
}

/** A wrapper around GooglePlacesAutocompleteField with an offline fallback */
const LocationField = ({
inputProps = {},
...props
}: LocationFieldProps & any) => {
const { theme } = useCustomTheme();
const { online: isOnline } = useOnlineStatus();

const googleAttributionHelperText: TextFieldProps = {
helperText: (
<img
src={
theme === "light" ? poweredByGoogleLightMode : poweredByGoogleDarkMode
}
alt="This location search field uses Google APIs."
className={styles.googleAttribution}
/>
),
};

if (isOnline) {
return (
<GooglePlacesAutocompleteField
inputProps={{ ...googleAttributionHelperText, ...inputProps }}
{...props}
/>
);
}

return (
<TextField
fullWidth
{...props}
helperText="Location suggestions aren't available offline"
{...inputProps}
/>
);
};

export default LocationField;
4 changes: 4 additions & 0 deletions src/components/fields/LocationField/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.googleAttribution {
height: 13px;
width: auto;
}
4 changes: 2 additions & 2 deletions src/helpers/tripItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
Theaters,
Tour,
} from "@mui/icons-material";
import { GooglePlacesAutocompleteField } from "@dylmye/mui-google-places-autocomplete";

import {
ActivityTypes,
Expand All @@ -38,6 +37,7 @@ import TripItem from "../types/Tripitem";
import GoogleMapsTravelMode from "../types/GoogleMapsTravelMode";
import ExtraText from "../types/ExtraText";
import CustomFieldSettings from "../types/CustomFieldSettings";
import LocationField from "../components/fields/LocationField";
import BetterSwitchField from "../components/fields/BetterSwitchField";
import AirlineAutocompleteField from "../components/fields/AirlineAutocompleteField";
import CopyToClipboardButton from "../components/CopyToClipboardButton";
Expand Down Expand Up @@ -442,7 +442,7 @@ export const renderExtraField = (
case "connected-dropdown:places": {
return (
<FastField
component={GooglePlacesAutocompleteField}
component={LocationField}
name={field}
label={fieldNameToLabel(field)}
/>
Expand Down

0 comments on commit be8efc0

Please sign in to comment.