All files / src/sections/PayBuilder/Checkout/hooks useCustomFieldsEditGuard.tsx

65.38% Statements 17/26
75% Branches 3/4
50% Functions 4/8
65.38% Lines 17/26

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 108 109 110 111                          45x 8x 8x               45x                                                             45x 52x 52x   52x 8x             5x 5x     3x 3x                               1x 1x                   1x               52x        
import NiceModal from "@ebay/nice-modal-react";
import { useRef, useState } from "react";
import { Stack } from "@mui/material";
import GiveCheckbox from "@shared/GiveCheckbox/GiveCheckbox";
import GiveText from "@shared/Text/GiveText";
import { GIVE_CONFIRMATION_POP_UP } from "modals/modal_names";
import {
  CUSTOM_FIELDS_EDIT_WARNING_BODY,
  CUSTOM_FIELDS_EDIT_WARNING_TITLE,
  CUSTOM_FIELDS_WARNING_SUPPRESS_KEY,
  shouldWarnOnCustomFieldsEdit,
} from "../customFields.helpers";
 
const isSuppressed = (): boolean => {
  try {
    return (
      window.localStorage.getItem(CUSTOM_FIELDS_WARNING_SUPPRESS_KEY) === "true"
    );
  } catch {
    return false;
  }
};
 
const DontShowAgainOption = ({
  onChange,
}: {
  onChange: (v: boolean) => void;
}) => {
  const [checked, setChecked] = useState(false);
  return (
    <Stack direction="row" spacing={1} alignItems="center">
      <GiveCheckbox
        checked={checked}
        onChange={(e) => {
          setChecked(e.target.checked);
          onChange(e.target.checked);
        }}
        data-testid="custom-fields-dont-show-again"
      />
      <GiveText variant="bodyS">Don&apos;t show again</GiveText>
    </Stack>
  );
};
 
/**
 * PAY-Builder016 (AC017) — guard structural custom-field edits on a *published*
 * form behind the "Modifying Custom Fields" warning. Fires once per session (or
 * never, if the merchant ticked "Don't show again"). On a draft form, or once
 * dismissed, the action runs immediately.
 *
 * Note: the story's "duplicate the form on continue" (AC018) has no BE endpoint
 * yet (open Q-A); historical submissions are already protected by the
 * per-transaction snapshot (AC019), so on continue the edit is applied in place.
 */
export const useCustomFieldsEditGuard = (isPublished: boolean) => {
  const shownThisSessionRef = useRef(false);
  const dontShowAgainRef = useRef(false);
 
  const guardEdit = (action: () => void) => {
    if (
      !shouldWarnOnCustomFieldsEdit(
        isPublished,
        isSuppressed(),
        shownThisSessionRef.current,
      )
    ) {
      action();
      return;
    }
 
    dontShowAgainRef.current = false;
    NiceModal.show(GIVE_CONFIRMATION_POP_UP, {
      modalType: "warning-info",
      title: CUSTOM_FIELDS_EDIT_WARNING_TITLE,
      description: CUSTOM_FIELDS_EDIT_WARNING_BODY,
      customSubmitBtnText: "Yes, Continue",
      customCancelBtnText: "Discard",
      leftActionComponent: (
        <DontShowAgainOption
          onChange={(v) => {
            dontShowAgainRef.current = v;
          }}
        />
      ),
      actions: {
        handleSuccess: {
          onClick: () => {
            shownThisSessionRef.current = true;
            Iif (dontShowAgainRef.current) {
              try {
                window.localStorage.setItem(
                  CUSTOM_FIELDS_WARNING_SUPPRESS_KEY,
                  "true",
                );
              } catch {
                /* localStorage unavailable — warn again next time */
              }
            }
            action();
          },
        },
        handleCancel: { onClick: () => undefined },
      },
    });
  };
 
  return { guardEdit };
};
 
export default useCustomFieldsEditGuard;