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,6 +1,8 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Collapse,
|
||||
Grow,
|
||||
IconButton,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
@ -28,6 +30,9 @@ import { useUserStore } from "@root/stores/user";
|
||||
import { VerificationStatus } from "@root/model/account";
|
||||
import { WarnModal } from "./WarnModal";
|
||||
import { SorryModal } from "./SorryModal";
|
||||
import SimpleArrowDown from "@root/components/icons/SimpleArrowDown";
|
||||
import PromocodeTextField from "./PromocodeTextField";
|
||||
import { activatePromocode } from "@root/api/promocode";
|
||||
|
||||
type PaymentMethod = {
|
||||
label: string;
|
||||
@ -51,7 +56,8 @@ export default function Payment() {
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
|
||||
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);
|
||||
@ -81,18 +87,14 @@ export default function Payment() {
|
||||
console.log(fromSquiz);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setPaymentLink("");
|
||||
}, [selectedPaymentMethod]);
|
||||
|
||||
async function handleChoosePaymentClick() {
|
||||
if (!selectedPaymentMethod) {
|
||||
enqueueSnackbar("Введите метод оплаты")
|
||||
enqueueSnackbar("Введите метод оплаты");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Number(paymentValueField) === 0) {
|
||||
enqueueSnackbar("Введите сумму")
|
||||
enqueueSnackbar("Введите сумму");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -111,9 +113,9 @@ export default function Payment() {
|
||||
|
||||
return;
|
||||
}
|
||||
console.log(paymentValueField)
|
||||
console.log(paymentValueField);
|
||||
if (Number(paymentValueField) < 900) {
|
||||
enqueueSnackbar("Минимальная сумма 900р")
|
||||
enqueueSnackbar("Минимальная сумма 900р");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -146,9 +148,9 @@ export default function Payment() {
|
||||
|
||||
return;
|
||||
}
|
||||
console.log(paymentValueField)
|
||||
console.log(paymentValueField);
|
||||
if (Number(paymentValueField) < 900) {
|
||||
enqueueSnackbar("Минимальная сумма 900р")
|
||||
enqueueSnackbar("Минимальная сумма 900р");
|
||||
|
||||
return;
|
||||
}
|
||||
@ -169,6 +171,15 @@ export default function Payment() {
|
||||
|
||||
}
|
||||
|
||||
function handleApplyPromocode() {
|
||||
if (!promocodeField) return;
|
||||
|
||||
activatePromocode(promocodeField).then(response => {
|
||||
enqueueSnackbar(response);
|
||||
}).catch(error => {
|
||||
enqueueSnackbar(error.message);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionWrapper
|
||||
@ -216,6 +227,15 @@ export default function Payment() {
|
||||
width: upMd ? "68.5%" : undefined,
|
||||
p: upMd ? "20px" : undefined,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "start",
|
||||
gap: "40px",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: upSm ? "row" : "column",
|
||||
flexWrap: "wrap",
|
||||
gap: upMd ? "14px" : "20px",
|
||||
@ -229,7 +249,8 @@ export default function Payment() {
|
||||
label={label}
|
||||
image={image}
|
||||
onClick={() => {
|
||||
setSelectedPaymentMethod(name)
|
||||
setSelectedPaymentMethod(name);
|
||||
setPaymentLink("");
|
||||
}}
|
||||
unpopular={false}
|
||||
/>
|
||||
@ -239,11 +260,52 @@ export default function Payment() {
|
||||
label={"Расчётный счёт"}
|
||||
image={rsPayLogo}
|
||||
onClick={async () => {
|
||||
setSelectedPaymentMethod("rspay")
|
||||
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",
|
||||
@ -287,7 +349,7 @@ export default function Payment() {
|
||||
value: paymentValueField,
|
||||
type: "number",
|
||||
}}
|
||||
onChange={(e) => setPaymentValueField(e.target.value.replace(/^0+(?=\d\.)/, ''))}
|
||||
onChange={(e) => setPaymentValueField(e.target.value.replace(/^0+(?=\d\.)/, ""))}
|
||||
id="payment-amount"
|
||||
gap={upMd ? "16px" : "10px"}
|
||||
color={"#F2F3F7"}
|
||||
|
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