File size: 2,814 Bytes
b59aa07
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from "react";
import { useTranslation } from "react-i18next";
import { useCreateStripeCheckoutSession } from "#/hooks/mutation/stripe/use-create-stripe-checkout-session";
import { useBalance } from "#/hooks/query/use-balance";
import { cn } from "#/utils/utils";
import MoneyIcon from "#/icons/money.svg?react";
import { SettingsInput } from "../settings/settings-input";
import { BrandButton } from "../settings/brand-button";
import { LoadingSpinner } from "#/components/shared/loading-spinner";
import { amountIsValid } from "#/utils/amount-is-valid";
import { I18nKey } from "#/i18n/declaration";

export function PaymentForm() {
  const { t } = useTranslation();
  const { data: balance, isLoading } = useBalance();
  const { mutate: addBalance, isPending } = useCreateStripeCheckoutSession();

  const [buttonIsDisabled, setButtonIsDisabled] = React.useState(true);

  const billingFormAction = async (formData: FormData) => {
    const amount = formData.get("top-up-input")?.toString();

    if (amount?.trim()) {
      if (!amountIsValid(amount)) return;

      const intValue = parseInt(amount, 10);
      addBalance({ amount: intValue });
    }

    setButtonIsDisabled(true);
  };

  const handleTopUpInputChange = (value: string) => {
    setButtonIsDisabled(!amountIsValid(value));
  };

  return (
    <form
      action={billingFormAction}
      data-testid="billing-settings"
      className="flex flex-col gap-6 px-11 py-9"
    >
      <div
        className={cn(
          "flex items-center justify-between w-[680px] bg-[#7F7445] rounded px-3 py-2",
          "text-[28px] leading-8 -tracking-[0.02em] font-bold",
        )}
      >
        <div className="flex items-center gap-2">
          <MoneyIcon width={22} height={14} />
          <span>{t(I18nKey.PAYMENT$MANAGE_CREDITS)}</span>
        </div>
        {!isLoading && (
          <span data-testid="user-balance">${Number(balance).toFixed(2)}</span>
        )}
        {isLoading && <LoadingSpinner size="small" />}
      </div>

      <div className="flex flex-col gap-3">
        <SettingsInput
          testId="top-up-input"
          name="top-up-input"
          onChange={handleTopUpInputChange}
          type="number"
          label={t(I18nKey.PAYMENT$ADD_FUNDS)}
          placeholder="Specify an amount in USD to add - min $10"
          className="w-[680px]"
          min={10}
          max={25000}
          step={1}
        />

        <div className="flex items-center w-[680px] gap-2">
          <BrandButton
            variant="primary"
            type="submit"
            isDisabled={isPending || buttonIsDisabled}
          >
            {t(I18nKey.PAYMENT$ADD_CREDIT)}
          </BrandButton>
          {isPending && <LoadingSpinner size="small" />}
        </div>
      </div>
    </form>
  );
}