add apply promocode button
This commit is contained in:
parent
3ffa3418c0
commit
82e2f550c7
32
src/api/promocode.ts
Normal file
32
src/api/promocode.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { makeRequest } from "@frontend/kitui";
|
||||||
|
import { isAxiosError } from "axios";
|
||||||
|
|
||||||
|
|
||||||
|
const apiUrl = process.env.REACT_APP_DOMAIN + "/codeword/promocode";
|
||||||
|
|
||||||
|
export async function activatePromocode(promocode: string) {
|
||||||
|
try {
|
||||||
|
const response = await makeRequest<{
|
||||||
|
codeword: string;
|
||||||
|
} | {
|
||||||
|
fastLink: string;
|
||||||
|
}, {
|
||||||
|
greetings: string;
|
||||||
|
}>({
|
||||||
|
url: apiUrl + "/activate",
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
codeword: promocode,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.greetings;
|
||||||
|
} catch (error) {
|
||||||
|
let message = "Неизвестная ошибка";
|
||||||
|
if (isAxiosError(error) && error.status === 404) {
|
||||||
|
message = "Промокод не найден";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(message);
|
||||||
|
}
|
||||||
|
}
|
26
src/components/icons/SimpleArrowDown.tsx
Normal file
26
src/components/icons/SimpleArrowDown.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { Box, SxProps, Theme } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
sx?: SxProps<Theme>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function SimpleArrowDown({ sx }: Props) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{
|
||||||
|
width: "14px",
|
||||||
|
height: "9px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
flexShrink: 0,
|
||||||
|
...sx,
|
||||||
|
}}>
|
||||||
|
<svg width="14" height="9" viewBox="0 0 14 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13 1.48535L7 7.48535" stroke="#7E2AEA" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
<path d="M1 1.48535L7 7.48535" stroke="#7E2AEA" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
</svg>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
IconButton,
|
Collapse,
|
||||||
Typography,
|
Grow,
|
||||||
useMediaQuery,
|
IconButton,
|
||||||
useTheme,
|
Typography,
|
||||||
|
useMediaQuery,
|
||||||
|
useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||||
import SectionWrapper from "@components/SectionWrapper";
|
import SectionWrapper from "@components/SectionWrapper";
|
||||||
@ -28,314 +30,374 @@ import { useUserStore } from "@root/stores/user";
|
|||||||
import { VerificationStatus } from "@root/model/account";
|
import { VerificationStatus } from "@root/model/account";
|
||||||
import { WarnModal } from "./WarnModal";
|
import { WarnModal } from "./WarnModal";
|
||||||
import { SorryModal } from "./SorryModal";
|
import { SorryModal } from "./SorryModal";
|
||||||
|
import SimpleArrowDown from "@root/components/icons/SimpleArrowDown";
|
||||||
|
import PromocodeTextField from "./PromocodeTextField";
|
||||||
|
import { activatePromocode } from "@root/api/promocode";
|
||||||
|
|
||||||
type PaymentMethod = {
|
type PaymentMethod = {
|
||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
image: string;
|
image: string;
|
||||||
unpopular?: boolean;
|
unpopular?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const paymentMethods: PaymentMethod[] = [
|
const paymentMethods: PaymentMethod[] = [
|
||||||
{ label: "Тинькофф", name: "tinkoffBank", image: tinkoffLogo },
|
{ label: "Тинькофф", name: "tinkoffBank", image: tinkoffLogo },
|
||||||
{ label: "СБП", name: "sbp", image: spbLogo },
|
{ label: "СБП", name: "sbp", image: spbLogo },
|
||||||
{ label: "SberPay", name: "sberbank", image: sberpayLogo },
|
{ label: "SberPay", name: "sberbank", image: sberpayLogo },
|
||||||
{ label: "B2B Сбербанк", name: "b2bSberbank", image: b2bLogo },
|
{ label: "B2B Сбербанк", name: "b2bSberbank", image: b2bLogo },
|
||||||
{ label: "ЮMoney", name: "yoomoney", image: umoneyLogo },
|
{ label: "ЮMoney", name: "yoomoney", image: umoneyLogo },
|
||||||
];
|
];
|
||||||
|
|
||||||
type PaymentMethodType = (typeof paymentMethods)[number]["name"];
|
type PaymentMethodType = (typeof paymentMethods)[number]["name"];
|
||||||
|
|
||||||
export default function Payment() {
|
export default function Payment() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
|
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
const [promocodeField, setPromocodeField] = useState<string>("");
|
||||||
|
const [isPromocodeFieldOpen, setIsPromocodeFieldOpen] = useState<boolean>(false);
|
||||||
|
const [selectedPaymentMethod, setSelectedPaymentMethod] =
|
||||||
|
useState<PaymentMethodType | null>("");
|
||||||
|
const [warnModalOpen, setWarnModalOpen] = useState<boolean>(false);
|
||||||
|
const [sorryModalOpen, setSorryModalOpen] = useState<boolean>(false);
|
||||||
|
const [paymentValueField, setPaymentValueField] = useState<string>("0");
|
||||||
|
const [paymentLink, setPaymentLink] = useState<string>("");
|
||||||
|
const [fromSquiz, setIsFromSquiz] = useState<boolean>(false);
|
||||||
|
const location = useLocation();
|
||||||
|
const verificationStatus = useUserStore((state) => state.verificationStatus);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const handleCustomBackNavigation = useHistoryTracker();
|
||||||
|
|
||||||
const [selectedPaymentMethod, setSelectedPaymentMethod] =
|
const notEnoughMoneyAmount =
|
||||||
useState<PaymentMethodType | null>("");
|
(location.state?.notEnoughMoneyAmount as number) ?? 0;
|
||||||
const [warnModalOpen, setWarnModalOpen] = useState<boolean>(false);
|
|
||||||
const [sorryModalOpen, setSorryModalOpen] = useState<boolean>(false);
|
|
||||||
const [paymentValueField, setPaymentValueField] = useState<string>("0");
|
|
||||||
const [paymentLink, setPaymentLink] = useState<string>("");
|
|
||||||
const [fromSquiz, setIsFromSquiz] = useState<boolean>(false);
|
|
||||||
const location = useLocation();
|
|
||||||
const verificationStatus = useUserStore((state) => state.verificationStatus);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const handleCustomBackNavigation = useHistoryTracker();
|
|
||||||
|
|
||||||
const notEnoughMoneyAmount =
|
const paymentValue = parseFloat(paymentValueField) * 100;
|
||||||
(location.state?.notEnoughMoneyAmount as number) ?? 0;
|
|
||||||
|
|
||||||
const paymentValue = parseFloat(paymentValueField) * 100;
|
useLayoutEffect(() => {
|
||||||
|
setPaymentValueField((notEnoughMoneyAmount / 100).toString());
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const fromSquiz = params.get("action");
|
||||||
|
if (fromSquiz === "squizpay") {
|
||||||
|
setIsFromSquiz(true);
|
||||||
|
setPaymentValueField((Number(params.get("dif") || "0") / 100).toString());
|
||||||
|
}
|
||||||
|
history.pushState(null, document.title, "/payment");
|
||||||
|
console.log(fromSquiz);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
async function handleChoosePaymentClick() {
|
||||||
setPaymentValueField((notEnoughMoneyAmount / 100).toString());
|
if (!selectedPaymentMethod) {
|
||||||
const params = new URLSearchParams(window.location.search);
|
enqueueSnackbar("Введите метод оплаты");
|
||||||
const fromSquiz = params.get("action");
|
return;
|
||||||
if (fromSquiz === "squizpay") {
|
}
|
||||||
setIsFromSquiz(true);
|
|
||||||
setPaymentValueField((Number(params.get("dif") || "0") / 100).toString());
|
|
||||||
}
|
|
||||||
history.pushState(null, document.title, "/payment");
|
|
||||||
console.log(fromSquiz);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
if (Number(paymentValueField) === 0) {
|
||||||
setPaymentLink("");
|
enqueueSnackbar("Введите сумму");
|
||||||
}, [selectedPaymentMethod]);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
async function handleChoosePaymentClick() {
|
if (selectedPaymentMethod !== "rspay") {
|
||||||
if (!selectedPaymentMethod) {
|
const [sendPaymentResponse, sendPaymentError] = await sendPayment({
|
||||||
enqueueSnackbar("Введите метод оплаты")
|
fromSquiz,
|
||||||
return;
|
body: {
|
||||||
}
|
type: selectedPaymentMethod,
|
||||||
|
amount: Number(paymentValueField) * 100,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (Number(paymentValueField) === 0) {
|
if (selectedPaymentMethod === "rspay") {
|
||||||
enqueueSnackbar("Введите сумму")
|
if (verificationStatus !== VerificationStatus.VERIFICATED) {
|
||||||
return;
|
setWarnModalOpen(true);
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedPaymentMethod !== "rspay") {
|
return;
|
||||||
const [sendPaymentResponse, sendPaymentError] = await sendPayment({
|
}
|
||||||
fromSquiz,
|
console.log(paymentValueField);
|
||||||
body: {
|
if (Number(paymentValueField) < 900) {
|
||||||
type: selectedPaymentMethod,
|
enqueueSnackbar("Минимальная сумма 900р");
|
||||||
amount: Number(paymentValueField) * 100,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (selectedPaymentMethod === "rspay") {
|
return;
|
||||||
if (verificationStatus !== VerificationStatus.VERIFICATED) {
|
}
|
||||||
setWarnModalOpen(true);
|
|
||||||
|
|
||||||
return;
|
const sendRSPaymentError = await sendRSPayment(Number(paymentValueField));
|
||||||
}
|
|
||||||
console.log(paymentValueField)
|
|
||||||
if (Number(paymentValueField) < 900){
|
|
||||||
enqueueSnackbar("Минимальная сумма 900р")
|
|
||||||
|
|
||||||
return;
|
if (sendRSPaymentError) {
|
||||||
}
|
return enqueueSnackbar(sendRSPaymentError);
|
||||||
|
}
|
||||||
|
|
||||||
const sendRSPaymentError = await sendRSPayment(Number(paymentValueField));
|
enqueueSnackbar(
|
||||||
|
"Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг."
|
||||||
|
);
|
||||||
|
|
||||||
if (sendRSPaymentError) {
|
navigate("/settings");
|
||||||
return enqueueSnackbar(sendRSPaymentError);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
enqueueSnackbar(
|
if (sendPaymentError) {
|
||||||
"Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг."
|
return enqueueSnackbar(sendPaymentError);
|
||||||
);
|
}
|
||||||
|
|
||||||
navigate("/settings");
|
if (sendPaymentResponse) {
|
||||||
}
|
setPaymentLink(sendPaymentResponse.link);
|
||||||
|
}
|
||||||
|
|
||||||
if (sendPaymentError) {
|
return;
|
||||||
return enqueueSnackbar(sendPaymentError);
|
} else {
|
||||||
}
|
if (verificationStatus !== VerificationStatus.VERIFICATED) {
|
||||||
|
setWarnModalOpen(true);
|
||||||
|
|
||||||
if (sendPaymentResponse) {
|
return;
|
||||||
setPaymentLink(sendPaymentResponse.link);
|
}
|
||||||
}
|
console.log(paymentValueField);
|
||||||
|
if (Number(paymentValueField) < 900) {
|
||||||
|
enqueueSnackbar("Минимальная сумма 900р");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
if (verificationStatus !== VerificationStatus.VERIFICATED) {
|
|
||||||
setWarnModalOpen(true);
|
|
||||||
|
|
||||||
return;
|
const sendRSPaymentError = await sendRSPayment(Number(paymentValueField));
|
||||||
}
|
|
||||||
console.log(paymentValueField)
|
|
||||||
if (Number(paymentValueField) < 900){
|
|
||||||
enqueueSnackbar("Минимальная сумма 900р")
|
|
||||||
|
|
||||||
return;
|
if (sendRSPaymentError) {
|
||||||
}
|
return enqueueSnackbar(sendRSPaymentError);
|
||||||
|
}
|
||||||
|
|
||||||
const sendRSPaymentError = await sendRSPayment(Number(paymentValueField));
|
enqueueSnackbar(
|
||||||
|
"Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг."
|
||||||
|
);
|
||||||
|
|
||||||
if (sendRSPaymentError) {
|
navigate("/settings");
|
||||||
return enqueueSnackbar(sendRSPaymentError);
|
|
||||||
}
|
|
||||||
|
|
||||||
enqueueSnackbar(
|
}
|
||||||
"Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг."
|
|
||||||
);
|
|
||||||
|
|
||||||
navigate("/settings");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
function handleApplyPromocode() {
|
||||||
|
if (!promocodeField) return;
|
||||||
|
|
||||||
|
activatePromocode(promocodeField).then(response => {
|
||||||
|
enqueueSnackbar(response);
|
||||||
|
}).catch(error => {
|
||||||
|
enqueueSnackbar(error.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionWrapper
|
<SectionWrapper
|
||||||
maxWidth="lg"
|
maxWidth="lg"
|
||||||
sx={{
|
|
||||||
mt: "25px",
|
|
||||||
mb: "70px",
|
|
||||||
px: isTablet ? (upMd ? "40px" : "18px") : "20px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
mt: "20px",
|
|
||||||
mb: "40px",
|
|
||||||
display: "flex",
|
|
||||||
gap: "10px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!upMd && (
|
|
||||||
<IconButton
|
|
||||||
onClick={handleCustomBackNavigation}
|
|
||||||
sx={{ p: 0, height: "28px", width: "28px", color: "black" }}
|
|
||||||
>
|
|
||||||
<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(({ name, label, image, unpopular = false }) => (
|
|
||||||
<PaymentMethodCard
|
|
||||||
isSelected={selectedPaymentMethod === name}
|
|
||||||
key={name}
|
|
||||||
label={label}
|
|
||||||
image={image}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedPaymentMethod(name)
|
|
||||||
}}
|
|
||||||
unpopular={false}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<PaymentMethodCard
|
|
||||||
isSelected={selectedPaymentMethod === "rspay"}
|
|
||||||
label={"Расчётный счёт"}
|
|
||||||
image={rsPayLogo}
|
|
||||||
onClick={async() => {
|
|
||||||
setSelectedPaymentMethod("rspay")
|
|
||||||
}}
|
|
||||||
unpopular={false}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "start",
|
|
||||||
color: theme.palette.gray.dark,
|
|
||||||
width: upMd ? "31.5%" : undefined,
|
|
||||||
p: upMd ? "20px" : undefined,
|
|
||||||
pl: upMd ? "33px" : undefined,
|
|
||||||
mt: upMd ? undefined : "30px",
|
|
||||||
borderLeft: upMd
|
|
||||||
? `1px solid ${theme.palette.gray.main}`
|
|
||||||
: undefined,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
mt: "25px",
|
||||||
flexDirection: "column",
|
mb: "70px",
|
||||||
maxWidth: "85%",
|
px: isTablet ? (upMd ? "40px" : "18px") : "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{upMd && <Typography mb="56px">Выберите способ оплаты</Typography>}
|
<Box
|
||||||
<Typography mb="20px">К оплате</Typography>
|
|
||||||
{paymentLink ? (
|
|
||||||
<Typography
|
|
||||||
sx={{
|
sx={{
|
||||||
fontWeight: 500,
|
mt: "20px",
|
||||||
fontSize: "20px",
|
mb: "40px",
|
||||||
lineHeight: "48px",
|
display: "flex",
|
||||||
mb: "28px",
|
gap: "10px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{currencyFormatter.format(paymentValue / 100)}
|
{!upMd && (
|
||||||
</Typography>
|
<IconButton
|
||||||
) : (
|
onClick={handleCustomBackNavigation}
|
||||||
<InputTextfield
|
sx={{ p: 0, height: "28px", width: "28px", color: "black" }}
|
||||||
TextfieldProps={{
|
>
|
||||||
placeholder: "К оплате",
|
<ArrowBackIcon />
|
||||||
value: paymentValueField,
|
</IconButton>
|
||||||
type: "number",
|
)}
|
||||||
}}
|
<Typography variant="h4">Способ оплаты</Typography>
|
||||||
onChange={(e) => setPaymentValueField(e.target.value.replace(/^0+(?=\d\.)/, ''))}
|
</Box>
|
||||||
id="payment-amount"
|
{!upMd && (
|
||||||
gap={upMd ? "16px" : "10px"}
|
<Typography variant="body2" mb="30px">
|
||||||
color={"#F2F3F7"}
|
Выберите способ оплаты
|
||||||
FormInputSx={{ mb: "28px" }}
|
</Typography>
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</Box>
|
<Box
|
||||||
{paymentLink ? (
|
sx={{
|
||||||
<Button
|
backgroundColor: upMd ? "white" : undefined,
|
||||||
variant="pena-outlined-light"
|
display: "flex",
|
||||||
component="a"
|
flexDirection: upMd ? "row" : "column",
|
||||||
href={paymentLink}
|
borderRadius: "12px",
|
||||||
sx={{
|
boxShadow: upMd ? cardShadow : undefined,
|
||||||
mt: "auto",
|
}}
|
||||||
color: "black",
|
|
||||||
border: `1px solid ${theme.palette.purple.main}`,
|
|
||||||
"&:hover": {
|
|
||||||
backgroundColor: theme.palette.purple.dark,
|
|
||||||
border: `1px solid ${theme.palette.purple.dark}`,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Оплатить
|
<Box
|
||||||
</Button>
|
sx={{
|
||||||
) : (
|
width: upMd ? "68.5%" : undefined,
|
||||||
<Button
|
p: upMd ? "20px" : undefined,
|
||||||
variant="pena-outlined-light"
|
display: "flex",
|
||||||
disabled={!isFinite(paymentValue)}
|
flexDirection: "column",
|
||||||
onClick={handleChoosePaymentClick}
|
alignItems: "start",
|
||||||
sx={{
|
gap: "40px",
|
||||||
mt: "auto",
|
}}
|
||||||
color: "black",
|
>
|
||||||
border: `1px solid ${theme.palette.purple.main}`,
|
<Box
|
||||||
"&:hover": {
|
sx={{
|
||||||
color: "white",
|
width: "100%",
|
||||||
},
|
display: "flex",
|
||||||
"&:active": {
|
flexDirection: upSm ? "row" : "column",
|
||||||
color: "white",
|
flexWrap: "wrap",
|
||||||
},
|
gap: upMd ? "14px" : "20px",
|
||||||
}}
|
alignContent: "start",
|
||||||
>
|
}}
|
||||||
Выбрать
|
>
|
||||||
</Button>
|
{paymentMethods.map(({ name, label, image, unpopular = false }) => (
|
||||||
)}
|
<PaymentMethodCard
|
||||||
</Box>
|
isSelected={selectedPaymentMethod === name}
|
||||||
</Box>
|
key={name}
|
||||||
<WarnModal open={warnModalOpen} setOpen={setWarnModalOpen} />
|
label={label}
|
||||||
<SorryModal open={sorryModalOpen} setOpen={setSorryModalOpen} />
|
image={image}
|
||||||
</SectionWrapper>
|
onClick={() => {
|
||||||
);
|
setSelectedPaymentMethod(name);
|
||||||
|
setPaymentLink("");
|
||||||
|
}}
|
||||||
|
unpopular={false}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
<PaymentMethodCard
|
||||||
|
isSelected={selectedPaymentMethod === "rspay"}
|
||||||
|
label={"Расчётный счёт"}
|
||||||
|
image={rsPayLogo}
|
||||||
|
onClick={async () => {
|
||||||
|
setSelectedPaymentMethod("rspay");
|
||||||
|
setPaymentLink("");
|
||||||
|
}}
|
||||||
|
unpopular={false}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box sx={{
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "start",
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
variant="pena-text"
|
||||||
|
onClick={() => setIsPromocodeFieldOpen(p => !p)}
|
||||||
|
sx={{
|
||||||
|
fontWeight: 400,
|
||||||
|
fontSize: "18px",
|
||||||
|
lineHeight: "21.33px",
|
||||||
|
textUnderlineOffset: "1px",
|
||||||
|
".MuiButton-endIcon": {
|
||||||
|
mr: 0,
|
||||||
|
ml: "15px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
endIcon={
|
||||||
|
<SimpleArrowDown sx={{
|
||||||
|
transform: isPromocodeFieldOpen ? "scaleY(-1)" : undefined,
|
||||||
|
transition: "transform 0.3s ease",
|
||||||
|
}} />
|
||||||
|
}
|
||||||
|
>У меня есть промокод</Button>
|
||||||
|
<Collapse
|
||||||
|
in={isPromocodeFieldOpen}
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PromocodeTextField
|
||||||
|
value={promocodeField}
|
||||||
|
onChange={e => setPromocodeField(e.target.value)}
|
||||||
|
onApplyClick={handleApplyPromocode}
|
||||||
|
/>
|
||||||
|
</Collapse>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "start",
|
||||||
|
color: theme.palette.gray.dark,
|
||||||
|
width: upMd ? "31.5%" : undefined,
|
||||||
|
p: upMd ? "20px" : undefined,
|
||||||
|
pl: upMd ? "33px" : undefined,
|
||||||
|
mt: upMd ? undefined : "30px",
|
||||||
|
borderLeft: upMd
|
||||||
|
? `1px solid ${theme.palette.gray.main}`
|
||||||
|
: undefined,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
maxWidth: "85%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{upMd && <Typography mb="56px">Выберите способ оплаты</Typography>}
|
||||||
|
<Typography mb="20px">К оплате</Typography>
|
||||||
|
{paymentLink ? (
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontWeight: 500,
|
||||||
|
fontSize: "20px",
|
||||||
|
lineHeight: "48px",
|
||||||
|
mb: "28px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currencyFormatter.format(paymentValue / 100)}
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<InputTextfield
|
||||||
|
TextfieldProps={{
|
||||||
|
placeholder: "К оплате",
|
||||||
|
value: paymentValueField,
|
||||||
|
type: "number",
|
||||||
|
}}
|
||||||
|
onChange={(e) => setPaymentValueField(e.target.value.replace(/^0+(?=\d\.)/, ""))}
|
||||||
|
id="payment-amount"
|
||||||
|
gap={upMd ? "16px" : "10px"}
|
||||||
|
color={"#F2F3F7"}
|
||||||
|
FormInputSx={{ mb: "28px" }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
{paymentLink ? (
|
||||||
|
<Button
|
||||||
|
variant="pena-outlined-light"
|
||||||
|
component="a"
|
||||||
|
href={paymentLink}
|
||||||
|
sx={{
|
||||||
|
mt: "auto",
|
||||||
|
color: "black",
|
||||||
|
border: `1px solid ${theme.palette.purple.main}`,
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: theme.palette.purple.dark,
|
||||||
|
border: `1px solid ${theme.palette.purple.dark}`,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Оплатить
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
variant="pena-outlined-light"
|
||||||
|
disabled={!isFinite(paymentValue)}
|
||||||
|
onClick={handleChoosePaymentClick}
|
||||||
|
sx={{
|
||||||
|
mt: "auto",
|
||||||
|
color: "black",
|
||||||
|
border: `1px solid ${theme.palette.purple.main}`,
|
||||||
|
"&:hover": {
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
"&:active": {
|
||||||
|
color: "white",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Выбрать
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<WarnModal open={warnModalOpen} setOpen={setWarnModalOpen} />
|
||||||
|
<SorryModal open={sorryModalOpen} setOpen={setSorryModalOpen} />
|
||||||
|
</SectionWrapper>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
78
src/pages/Payment/PromocodeTextField.tsx
Normal file
78
src/pages/Payment/PromocodeTextField.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { Box, Button, TextField, useMediaQuery, useTheme } from "@mui/material";
|
||||||
|
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value?: string;
|
||||||
|
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => void;
|
||||||
|
onApplyClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PromocodeTextField({ value, onChange, onApplyClick }: Props) {
|
||||||
|
const theme = useTheme();
|
||||||
|
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: upSm ? "407px" : "100%",
|
||||||
|
mt: "20px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: upSm ? "row" : "column",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
placeholder="Введите промокод"
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
sx={{
|
||||||
|
height: "48px",
|
||||||
|
"& .MuiInputBase-root": {
|
||||||
|
height: "100%",
|
||||||
|
borderRadius: "8px",
|
||||||
|
border: "1px solid #9A9AAF",
|
||||||
|
...(upSm ? {
|
||||||
|
borderTopRightRadius: 0,
|
||||||
|
borderBottomRightRadius: 0,
|
||||||
|
} : {
|
||||||
|
borderBottomLeftRadius: 0,
|
||||||
|
borderBottomRightRadius: 0,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
sx: {
|
||||||
|
color: "#7E2AEA",
|
||||||
|
backgroundColor: "#7E2AEA1A",
|
||||||
|
height: "100%",
|
||||||
|
boxSizing: "border-box",
|
||||||
|
borderRadius: "8px",
|
||||||
|
py: 0,
|
||||||
|
...(upSm ? {
|
||||||
|
borderTopRightRadius: 0,
|
||||||
|
borderBottomRightRadius: 0,
|
||||||
|
} : {
|
||||||
|
borderBottomLeftRadius: 0,
|
||||||
|
borderBottomRightRadius: 0,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant="pena-contained-dark"
|
||||||
|
onClick={onApplyClick}
|
||||||
|
sx={{
|
||||||
|
px: "25px",
|
||||||
|
minWidth: 0,
|
||||||
|
...(upSm ? {
|
||||||
|
borderTopLeftRadius: 0,
|
||||||
|
borderBottomLeftRadius: 0,
|
||||||
|
} : {
|
||||||
|
borderTopLeftRadius: 0,
|
||||||
|
borderTopRightRadius: 0,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
>Применить</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user