function AddImage()

in frontend/src/containers/AddImage.tsx [34:307]


function AddImage() {
  const history = useHistory();
  const { t } = useTranslation();
  const { dashboardId } = useParams<PathParams>();
  const { dashboard, loading } = useDashboard(dashboardId);
  const { register, errors, handleSubmit } = useForm<FormValues>();
  const [imageFile, setImageFile] = useState<File | undefined>(undefined);
  const [title, setTitle] = useState("");
  const [altText, setAltText] = useState("");
  const [summary, setSummary] = useState("");
  const [showTitle, setShowTitle] = useState(true);
  const [summaryBelow, setSummaryBelow] = useState(false);
  const [imageUploading, setImageUploading] = useState(false);

  const supportedImageFileTypes = Object.values(StorageService.imageFileTypes);

  const { fullPreview, fullPreviewButton } = useFullPreview();

  const onSubmit = async (values: FormValues) => {
    try {
      if (!imageFile) {
        throw new Error(t("AddImageScreen.ImageFileNotSpecified"));
      }
      setImageUploading(true);
      const s3Key = await StorageService.uploadImage(imageFile);

      await BackendService.createWidget(
        dashboardId,
        values.title,
        WidgetType.Image,
        values.showTitle,
        {
          title: title,
          s3Key: {
            raw: s3Key,
          },
          fileName: imageFile.name,
          imageAltText: altText,
          summary: summary,
          summaryBelow: summaryBelow,
        }
      );
      setImageUploading(false);

      history.push(`/admin/dashboard/edit/${dashboardId}`, {
        alert: {
          type: "success",
          message: t("AddImageScreen.ImageAddedSuccessfully", {
            title: values.title,
          }),
        },
      });
    } catch (err) {
      console.log(t("AddContentFailure"), err);
      setImageUploading(false);
    }
  };

  const goBack = () => {
    history.push(`/admin/dashboard/${dashboardId}/add-content`);
  };

  const onCancel = () => {
    history.push(`/admin/dashboard/edit/${dashboardId}`);
  };

  const handleChangeTitle = (event: React.FormEvent<HTMLInputElement>) => {
    setTitle((event.target as HTMLInputElement).value);
  };

  const handleAltTextChange = (event: React.FormEvent<HTMLInputElement>) => {
    setAltText((event.target as HTMLInputElement).value);
  };

  const handleSummaryChange = (event: React.FormEvent<HTMLTextAreaElement>) => {
    setSummary((event.target as HTMLTextAreaElement).value);
  };

  const handleSummaryBelowChange = (
    event: React.FormEvent<HTMLInputElement>
  ) => {
    setSummaryBelow((event.target as HTMLInputElement).checked);
  };

  const handleShowTitleChange = (event: React.FormEvent<HTMLInputElement>) => {
    setShowTitle((event.target as HTMLInputElement).checked);
  };

  const onFileProcessed = (data: File) => {
    if (data) {
      setImageFile(data);
    }
  };

  const crumbs = [
    {
      label: t("Dashboards"),
      url: "/admin/dashboards",
    },
    {
      label: dashboard?.name,
      url: `/admin/dashboard/edit/${dashboardId}`,
    },
  ];

  useChangeBackgroundColor();

  if (!loading) {
    crumbs.push({
      label: t("AddImageScreen.AddImage"),
      url: "",
    });
  }

  return (
    <>
      <Breadcrumbs crumbs={crumbs} />
      <div className="grid-row width-desktop grid-gap">
        <div className="grid-col-6" hidden={fullPreview}>
          <PrimaryActionBar>
            <h1 className="margin-top-0">{t("AddImageScreen.AddImage")}</h1>

            <div className="margin-y-1 text-semibold display-inline-block font-sans-lg">
              {t("AddImageScreen.ConfigureImage")}
            </div>
            <form
              className="usa-form usa-form--large"
              onSubmit={handleSubmit(onSubmit)}
            >
              <fieldset className="usa-fieldset">
                {errors.title || errors.altText ? (
                  <Alert
                    type="error"
                    message={t("AddImageScreen.ResolveError")}
                    slim
                  ></Alert>
                ) : (
                  ""
                )}
                <TextField
                  id="title"
                  name="title"
                  label={t("AddImageScreen.Title")}
                  hint={t("AddImageScreen.Hint")}
                  error={errors.title && t("AddImageScreen.TitleError")}
                  onChange={handleChangeTitle}
                  required
                  register={register}
                />

                <div className="usa-checkbox">
                  <input
                    className="usa-checkbox__input"
                    id="display-title"
                    type="checkbox"
                    name="showTitle"
                    defaultChecked={true}
                    onChange={handleShowTitleChange}
                    ref={register()}
                  />
                  <label
                    className="usa-checkbox__label"
                    htmlFor="display-title"
                  >
                    {t("AddImageScreen.ShowTitle")}
                  </label>
                </div>

                <div>
                  <FileInput
                    id="dataset"
                    name="dataset"
                    label={t("AddImageScreen.FileUpload")}
                    accept={supportedImageFileTypes.toString()}
                    loading={imageUploading}
                    register={register}
                    required
                    hint={<span>{t("AddImageScreen.FileHint")}</span>}
                    fileName={imageFile && imageFile.name}
                    onFileProcessed={onFileProcessed}
                  />
                </div>

                <div>
                  <div hidden={!imageFile}>
                    <TextField
                      id="altText"
                      name="altText"
                      label={t("AddImageScreen.AltText")}
                      hint={t("AddImageScreen.TextHint")}
                      register={register}
                      error={errors.altText && t("AddImageScreen.TextError")}
                      required
                      onChange={handleAltTextChange}
                      multiline
                      rows={1}
                    />

                    <TextField
                      id="summary"
                      name="summary"
                      label={t("AddImageScreen.SummaryLabel")}
                      hint={
                        <>
                          {t("AddImageScreen.SummaryHint")}{" "}
                          <Link target="_blank" to={"/admin/markdown"} external>
                            {t("AddImageScreen.MarkdownLink")}
                          </Link>
                        </>
                      }
                      register={register}
                      onChange={handleSummaryChange}
                      multiline
                      rows={5}
                    />
                    <div className="usa-checkbox">
                      <input
                        className="usa-checkbox__input"
                        id="summary-below"
                        type="checkbox"
                        name="summaryBelow"
                        defaultChecked={false}
                        onChange={handleSummaryBelowChange}
                        ref={register()}
                      />
                      <label
                        className="usa-checkbox__label"
                        htmlFor="summary-below"
                      >
                        {t("AddImageScreen.ToggleSummary")}
                      </label>
                    </div>
                  </div>
                </div>
              </fieldset>
              <br />
              <hr />
              <Button variant="outline" type="button" onClick={goBack}>
                {t("AddImageScreen.Back")}
              </Button>
              <Button
                disabled={!imageFile || imageUploading}
                type="submit"
                disabledToolTip={t("AddImageScreen.DisabledToolTip")}
              >
                {t("AddImageScreen.AddImage")}
              </Button>
              <Button
                variant="unstyled"
                className="text-base-dark hover:text-base-darker active:text-base-darkest"
                type="button"
                onClick={onCancel}
              >
                {t("AddImageScreen.Cancel")}
              </Button>
            </form>
          </PrimaryActionBar>
        </div>
        <div className={fullPreview ? "grid-col-12" : "grid-col-6"}>
          <div className="sticky-preview">
            {fullPreviewButton}
            <ImageWidget
              title={showTitle ? title : ""}
              summary={summary}
              file={imageFile}
              summaryBelow={summaryBelow}
              altText={altText}
            />
          </div>
        </div>
      </div>
    </>
  );
}