All files / app/features/auth/jail LocationSection.tsx

0% Statements 0/33
0% Branches 0/14
0% Functions 0/4
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                                                                                                                                                                                                     
import { Typography } from "@material-ui/core";
import Alert from "components/Alert";
import Button from "components/Button";
import EditLocationMap, {
  ApproximateLocation,
} from "components/EditLocationMap";
import TextBody from "components/TextBody";
import { useTranslation } from "i18n";
import { AUTH, GLOBAL } from "i18n/namespaces";
import Sentry from "platform/sentry";
import React, { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { service } from "service";
import isGrpcError from "service/utils/isGrpcError";
 
interface LocationInfo {
  location: ApproximateLocation;
}
 
interface LocationSectionProps {
  updateJailed: () => void;
  className?: string;
}
 
export default function LocationSection({
  updateJailed,
  className,
}: LocationSectionProps) {
  const { t } = useTranslation([AUTH, GLOBAL]);
  const [completed, setCompleted] = useState(false);
  const [error, setError] = useState("");
 
  const { control, handleSubmit } = useForm<LocationInfo>({
    defaultValues: { location: {} },
  });
 
  const save = handleSubmit(async ({ location }) => {
    try {
      const { address, lat, lng, radius } = location;
      if (address === "") {
        setError(t("auth:location.validation_error"));
      } else {
        const info = await service.jail.setLocation(address, lat, lng, radius);
        if (!info.isJailed) {
          updateJailed();
        } else {
          //if user is no longer jailed, this component will be unmounted anyway
          setCompleted(true);
        }
      }
    } catch (e) {
      Sentry.captureException(e, {
        tags: {
          featureArea: "auth/jail/locationField",
        },
      });
      setError(isGrpcError(e) ? e.message : t("global:error.fatal_message"));
    }
  });
 
  return (
    <>
      <Typography variant="h2">
        {t("auth:jail.location_section.title")}
      </Typography>
      <div className={className}>
        {error && <Alert severity="error">{error}</Alert>}
        <Controller
          name="location"
          control={control}
          render={({ onChange }) => (
            <EditLocationMap
              updateLocation={(location) => {
                if (location) {
                  onChange({
                    address: location.address,
                    lat: location.lat,
                    lng: location.lng,
                    radius: location.radius,
                  });
                } else {
                  onChange({
                    address: "",
                  });
                }
              }}
            />
          )}
        />
 
        <TextBody>
          <Button onClick={save} disabled={completed}>
            {!completed
              ? t("auth:jail.location_section.submit_button.active_text")
              : t("auth:jail.location_section.submit_button.inactive_text")}
          </Button>
          {completed && (
            <Button component="a" onClick={save}>
              {t("auth:jail.location_section.resubmit_button_text")}
            </Button>
          )}
        </TextBody>
      </div>
    </>
  );
}