front-hub/src/pages/Payment/Payment.tsx

207 lines
6.7 KiB
TypeScript
Raw Normal View History

import { Box, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import CustomButton from "@components/CustomButton";
import SectionWrapper from "@components/SectionWrapper";
2022-11-22 14:43:59 +00:00
import PaymentMethodCard from "./PaymentMethodCard";
2022-12-24 12:32:19 +00:00
import mastercardLogo from "../../assets/bank-logo/logo-mastercard.png";
import visaLogo from "../../assets/bank-logo/logo-visa.png";
import qiwiLogo from "../../assets/bank-logo/logo-qiwi.png";
import mirLogo from "../../assets/bank-logo/logo-mir.png";
import tinkoffLogo from "../../assets/bank-logo/logo-tinkoff.png";
2023-08-22 10:28:22 +00:00
import { cardShadow } from "@root/utils/theme";
2023-07-22 11:31:49 +00:00
import { useEffect, useState } from "react";
2023-07-07 13:53:08 +00:00
import InputTextfield from "@root/components/InputTextfield";
import { sendPayment } from "@root/api/wallet";
import { getMessageFromFetchError } from "@frontend/kitui";
import { enqueueSnackbar } from "notistack";
2023-07-22 11:31:49 +00:00
import { currencyFormatter } from "@root/utils/currencyFormatter";
import { useLocation } from "react-router-dom";
import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker";
2023-07-07 13:53:08 +00:00
const paymentMethods = [
2023-08-01 11:16:27 +00:00
{ name: "Mastercard", image: mastercardLogo },
{ name: "Visa", image: visaLogo },
{ name: "QIWI Кошелек", image: qiwiLogo },
{ name: "Мир", image: mirLogo },
{ name: "Тинькофф", image: tinkoffLogo },
2023-07-07 13:53:08 +00:00
] as const;
2023-08-01 11:16:27 +00:00
type PaymentMethod = (typeof paymentMethods)[number]["name"];
2022-11-22 14:43:59 +00:00
export default function Payment() {
2023-08-01 11:16:27 +00:00
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<PaymentMethod | null>(null);
2023-08-01 11:16:27 +00:00
const [paymentValueField, setPaymentValueField] = useState<string>("0");
const [paymentLink, setPaymentLink] = useState<string>("");
const location = useLocation();
const notEnoughMoneyAmount = (location.state?.notEnoughMoneyAmount as number) ?? 0;
2023-07-22 11:31:49 +00:00
2023-08-01 11:16:27 +00:00
useEffect(() => {
setPaymentValueField((notEnoughMoneyAmount / 100).toString());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
2023-07-22 11:31:49 +00:00
2023-08-01 11:16:27 +00:00
useEffect(() => {
setPaymentLink("");
}, [selectedPaymentMethod]);
2023-07-22 11:31:49 +00:00
2023-08-01 11:16:27 +00:00
const paymentValue = parseFloat(paymentValueField) * 100;
2022-11-22 14:43:59 +00:00
2023-08-01 11:16:27 +00:00
function handleChoosePaymentClick() {
if (Number(paymentValueField) !== 0) {
sendPayment()
.then((result) => {
setPaymentLink(result.link);
})
.catch((error) => {
const message = getMessageFromFetchError(error);
if (message) enqueueSnackbar(message);
2023-07-07 13:53:08 +00:00
});
}
2023-08-01 11:16:27 +00:00
}
2023-07-07 13:53:08 +00:00
const handleCustomBackNavigation = useHistoryTracker();
2023-08-01 11:16:27 +00:00
return (
<SectionWrapper
maxWidth="lg"
sx={{
mt: "25px",
mb: "70px",
}}
>
<Box
sx={{
mt: "20px",
mb: "40px",
display: "flex",
gap: "10px",
}}
>
{!upMd && (
<IconButton onClick={handleCustomBackNavigation} sx={{ p: 0, height: "28px", width: "28px", color: "black" }}>
2023-08-01 11:16:27 +00:00
<ArrowBackIcon />
</IconButton>
)}
<Typography variant="h4">Способ оплаты</Typography>
</Box>
{!upMd && (
<Typography variant="body2" mb="30px">
Выберите способ оплаты
</Typography>
)}
<Box
sx={{
backgroundColor: upMd ? "white" : undefined,
display: "flex",
flexDirection: upMd ? "row" : "column",
borderRadius: "12px",
boxShadow: upMd ? cardShadow : undefined,
}}
>
<Box
sx={{
width: upMd ? "68.5%" : undefined,
p: upMd ? "20px" : undefined,
display: "flex",
flexDirection: upSm ? "row" : "column",
flexWrap: "wrap",
gap: upMd ? "14px" : "20px",
alignContent: "start",
}}
>
{paymentMethods.map((method) => (
<PaymentMethodCard
isSelected={selectedPaymentMethod === method.name}
key={method.name}
name={method.name}
image={method.image}
onClick={() => setSelectedPaymentMethod(method.name)}
/>
))}
</Box>
<Box
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: "start",
2023-08-22 10:28:22 +00:00
color: theme.palette.gray.dark,
2023-08-01 11:16:27 +00:00
width: upMd ? "31.5%" : undefined,
p: upMd ? "20px" : undefined,
pl: upMd ? "33px" : undefined,
mt: upMd ? undefined : "30px",
2023-08-22 10:28:22 +00:00
borderLeft: upMd ? `1px solid ${theme.palette.gray.main}` : undefined,
2023-08-01 11:16:27 +00:00
}}
>
<Box
sx={{
2023-08-01 11:16:27 +00:00
display: "flex",
flexDirection: "column",
maxWidth: "85%",
}}
2023-08-01 11:16:27 +00:00
>
{upMd && <Typography mb="56px">Выберите способ оплаты</Typography>}
<Typography mb="20px">К оплате</Typography>
{paymentLink ? (
<Typography
2023-07-07 13:53:08 +00:00
sx={{
2023-08-01 11:16:27 +00:00
fontWeight: 500,
fontSize: "20px",
lineHeight: "48px",
mb: "28px",
2023-07-07 13:53:08 +00:00
}}
2023-08-01 11:16:27 +00:00
>
{currencyFormatter.format(paymentValue / 100)}
</Typography>
) : (
<InputTextfield
TextfieldProps={{
placeholder: "К оплате",
value: paymentValueField,
type: "number",
2023-07-07 13:53:08 +00:00
}}
2023-08-01 11:16:27 +00:00
onChange={(e) => setPaymentValueField(e.target.value)}
id="payment-amount"
gap={upMd ? "16px" : "10px"}
color={"#F2F3F7"}
FormInputSx={{ mb: "28px" }}
/>
)}
</Box>
{paymentLink ? (
<CustomButton
component="a"
href={paymentLink}
variant={"contained"}
sx={{
2023-08-22 10:28:22 +00:00
borderColor: theme.palette.purple.main,
backgroundColor: theme.palette.purple.main,
2023-08-01 11:16:27 +00:00
mt: "auto",
}}
>
Оплатить
</CustomButton>
) : (
<CustomButton
disabled={!isFinite(paymentValue)}
variant={"outlined"}
onClick={handleChoosePaymentClick}
sx={{
2023-08-22 10:28:22 +00:00
borderColor: theme.palette.purple.main,
2023-08-01 11:16:27 +00:00
backgroundColor: "",
mt: "auto",
}}
2023-07-07 13:53:08 +00:00
>
2023-08-01 11:16:27 +00:00
Выбрать
</CustomButton>
)}
</Box>
</Box>
</SectionWrapper>
);
}