Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Donation/donation-modal-body.tsx (TypeScript)

Code before:

  useEffect(() => {
    buttonRef.current?.focus();
  }, []);

  return (
    <div className='no-delay-fade-in'>
      <div className='donation-icon-container'>
        <Illustration />
      </div>
      <ModalHeader
        recentlyClaimedBlock={recentlyClaimedBlock}
        showHeaderAndFooter={showHeaderAndFooter}
        donationAttempted={donationAttempted}
        showForm={showForm}
      />
      <Spacer size='small' />
      {showForm ? (
        <MultiTierDonationForm
          setShowHeaderAndFooter={setShowHeaderAndFooter}
          handleProcessing={handleProcessing}
          paymentContext={PaymentContext.Modal}
          isMinimalForm={true}
        />
      ) : (
        <Benefits setShowForm={setShowForm} ref={buttonRef} />
      )}
      {(showHeaderAndFooter || donationAttempted) && (
        <CloseButtonRow
          closeDonationModal={closeDonationModal}
          donationAttempted={donationAttempted}
        />
      )}
    </div>
  );
};

function DonationModalBody({
  closeDonationModal,
  recentlyClaimedBlock,
  setCanClose
}: DonationModalBodyProps): JSX.Element {
  const [donationAttempted, setDonationAttempted] = useState(false);
  const [showHeaderAndFooter, setShowHeaderAndFooter] = useState(true);
  const [isAnimationVisible, setIsAnimationVisible] = useState(true);
  const [showForm, setShowForm] = useState(false);
  const [secondsRemaining, setSecondsRemaining] = useState(20);

  const handleProcessing = () => {
    setDonationAttempted(true);
  };

Review comment (suggestion):
We can just create the button ref internally in the `Benefits` component body. But since `BecomeASupporterConfirmation` is the outermost component of the modal's second part, and we have buttons in other components as well (`CloseButtonRow`), I thought the focus management should be kept in this layer so that it's easier to follow.

I'm not sure if I'm overthinking here and we should just move the focus management into `Benefits` instead.

Code after:
        recentlyClaimedBlock={recentlyClaimedBlock}
        showHeaderAndFooter={showHeaderAndFooter}
        donationAttempted={donationAttempted}
        showForm={showForm}
      />
      <Spacer size='small' />
      {showForm ? (
        <MultiTierDonationForm
          setShowHeaderAndFooter={setShowHeaderAndFooter}
          handleProcessing={handleProcessing}
          paymentContext={PaymentContext.Modal}
          isMinimalForm={true}
        />
      ) : (
        <Benefits setShowForm={setShowForm} />
      )}
      {(showHeaderAndFooter || donationAttempted) && (
        <CloseButtonRow
          closeDonationModal={closeDonationModal}
          donationAttempted={donationAttempted}
        />
      )}
    </div>
  );
};

function DonationModalBody({
  closeDonationModal,
  recentlyClaimedBlock,
  setCanClose
}: DonationModalBodyProps): JSX.Element {
  const [donationAttempted, setDonationAttempted] = useState(false);
  const [showHeaderAndFooter, setShowHeaderAndFooter] = useState(true);
  const [isAnimationVisible, setIsAnimationVisible] = useState(true);
  const [showForm, setShowForm] = useState(false);
  const [secondsRemaining, setSecondsRemaining] = useState(20);

  const handleProcessing = () => {
    setDonationAttempted(true);
  };

  useEffect(() => {
    const interval = setInterval(() => {
      setSecondsRemaining(prevSeconds => {
        if (prevSeconds > 0) {
          return prevSeconds - 1;
        } else {
          setIsAnimationVisible(false);
          clearInterval(interval);
          return 0;
        }