разделение доп тарифов
This commit is contained in:
parent
9bee2da343
commit
fbd5783061
@ -21,3 +21,28 @@ export const getTariffs = async (
|
|||||||
return [null, `Ошибка при получении списка тарифов. ${error}`];
|
return [null, `Ошибка при получении списка тарифов. ${error}`];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
|
||||||
|
const apiUrl = process.env.REACT_APP_DOMAIN + "/requestquiz";
|
||||||
|
|
||||||
|
export async function sendContactFormRequest(body: {
|
||||||
|
contact: string;
|
||||||
|
whoami: string;
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
const a = await axios(apiUrl + "/callme", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
data: body,
|
||||||
|
});
|
||||||
|
return [a];
|
||||||
|
} catch (nativeError) {
|
||||||
|
const [error] = parseAxiosError(nativeError);
|
||||||
|
|
||||||
|
return [null, `Ошибка при отправке запроса. ${error}`];
|
||||||
|
}
|
||||||
|
}
|
@ -81,39 +81,38 @@ export const AmoCRMModal: FC<IntegrationsModalProps> = ({ isModalOpen, handleClo
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box>
|
<Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
height: "68px",
|
|
||||||
backgroundColor: theme.palette.background.default,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography
|
|
||||||
sx={{
|
sx={{
|
||||||
fontSize: isMobile ? "20px" : "24px",
|
width: "100%",
|
||||||
fontWeight: "500",
|
height: "68px",
|
||||||
padding: "20px",
|
backgroundColor: theme.palette.background.default,
|
||||||
color: theme.palette.grey2.main,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Интеграция с {companyName ? companyName : "партнером"}
|
<Typography
|
||||||
</Typography>
|
sx={{
|
||||||
</Box>
|
fontSize: isMobile ? "20px" : "24px",
|
||||||
<IconButton
|
fontWeight: "500",
|
||||||
onClick={handleCloseModal}
|
padding: "20px",
|
||||||
sx={{
|
color: theme.palette.grey2.main,
|
||||||
width: "12px",
|
}}
|
||||||
height: "12px",
|
>
|
||||||
position: "absolute",
|
Интеграция с {companyName ? companyName : "партнером"}
|
||||||
right: "15px",
|
</Typography>
|
||||||
top: "15px",
|
</Box>
|
||||||
}}
|
<IconButton
|
||||||
>
|
onClick={handleCloseModal}
|
||||||
<CloseIcon sx={{ width: "12px", height: "12px", transform: "scale(1.5)" }} />
|
sx={{
|
||||||
</IconButton>
|
width: "12px",
|
||||||
|
height: "12px",
|
||||||
|
position: "absolute",
|
||||||
|
right: "15px",
|
||||||
|
top: "15px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CloseIcon sx={{ width: "12px", height: "12px", transform: "scale(1.5)" }} />
|
||||||
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
className="родитель"
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { Box } from "@mui/material";
|
import { Box, SxProps, Theme } from "@mui/material";
|
||||||
|
|
||||||
export default function CloseIcon() {
|
interface Props {
|
||||||
|
sx?: SxProps<Theme>;
|
||||||
|
}
|
||||||
|
export default function CloseIcon({ sx }: Props) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -15,6 +18,7 @@ export default function CloseIcon() {
|
|||||||
"&:hover path": {
|
"&:hover path": {
|
||||||
stroke: "#7E2AEA",
|
stroke: "#7E2AEA",
|
||||||
},
|
},
|
||||||
|
...sx
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
260
src/pages/Tariffs/ModalRequestCreate.tsx
Normal file
260
src/pages/Tariffs/ModalRequestCreate.tsx
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
import { Box, Button, IconButton, Modal, Typography, useMediaQuery, useTheme } from "@mui/material"
|
||||||
|
import CloseIcon from "../Landing/images/icons/CloseIcon"
|
||||||
|
import InputTextfield from "@/ui_kit/InputTextfield"
|
||||||
|
import { Form, Formik, useFormik } from "formik"
|
||||||
|
import CustomTextField from "@/ui_kit/CustomTextField"
|
||||||
|
import Info from "@icons/Info";
|
||||||
|
import { sendContactFormRequest } from "@/api/tariff"
|
||||||
|
import { TimePicker } from "@mui/x-date-pickers"
|
||||||
|
import moment, { Moment } from "moment"
|
||||||
|
import { enqueueSnackbar } from "notistack"
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface Values {
|
||||||
|
contact: string;
|
||||||
|
dogiebusiness: string;
|
||||||
|
imagination: string;
|
||||||
|
name: string;
|
||||||
|
time: Moment | null;
|
||||||
|
}
|
||||||
|
const initialValues: Values = {
|
||||||
|
contact: "",//phone number
|
||||||
|
// whoami: {},
|
||||||
|
dogiebusiness: "",
|
||||||
|
imagination: "",
|
||||||
|
name: "",
|
||||||
|
time: null
|
||||||
|
};
|
||||||
|
|
||||||
|
interface FP {
|
||||||
|
title: string
|
||||||
|
desc?: string
|
||||||
|
placeholder: string
|
||||||
|
value: string
|
||||||
|
onChange: any
|
||||||
|
rows?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const Field = ({
|
||||||
|
title,
|
||||||
|
desc,
|
||||||
|
placeholder,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
rows,
|
||||||
|
}: FP) => {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
m: "15px 0"
|
||||||
|
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "18px",
|
||||||
|
fontWeight: 500,
|
||||||
|
lineHeight: "21.33px",
|
||||||
|
mb: "10px",
|
||||||
|
}}
|
||||||
|
>{title}</Typography>
|
||||||
|
{desc && <Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "18px",
|
||||||
|
mb: "10px",
|
||||||
|
color: "#9A9AAF"
|
||||||
|
}}
|
||||||
|
>{desc}</Typography>}
|
||||||
|
<CustomTextField
|
||||||
|
value={value}
|
||||||
|
placeholder={placeholder}
|
||||||
|
maxLength={200}
|
||||||
|
onChange={onChange}
|
||||||
|
rows={rows || 0}
|
||||||
|
sx={rows !== undefined ? { height: "68px" } : {}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ModalRequestCreate = ({
|
||||||
|
open,
|
||||||
|
onClose
|
||||||
|
}: Props) => {
|
||||||
|
const theme = useTheme()
|
||||||
|
const isMobile = useMediaQuery(theme.breakpoints.down(650));
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
open={open}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<Box sx={{
|
||||||
|
position: 'absolute' as 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
boxShadow: 24,
|
||||||
|
width: isMobile ? "344px" : "620px",
|
||||||
|
borderRadius: "10px"
|
||||||
|
}}>
|
||||||
|
<Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
height: "68px",
|
||||||
|
backgroundColor: theme.palette.background.default,
|
||||||
|
borderRadius: "10px 10px 0 0"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "18px",
|
||||||
|
padding: "20px",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
borderRadius: "10px 10px 0 0"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Заполните форму, чтобы оставить заявку на создание квиза
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<IconButton
|
||||||
|
onClick={onClose}
|
||||||
|
sx={{
|
||||||
|
width: "12px",
|
||||||
|
height: "12px",
|
||||||
|
position: "absolute",
|
||||||
|
right: "15px",
|
||||||
|
top: "15px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CloseIcon sx={{ width: "12px", height: "12px", transform: "scale(1.5)" }} />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: "15px 70px 50px 50px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Formik
|
||||||
|
initialValues={initialValues}
|
||||||
|
onSubmit={async (values, formikHelpers) => {
|
||||||
|
if (values.contact.length < 8) return enqueueSnackbar("Пожалуйста, оставьте контактные данные")
|
||||||
|
const resp = await sendContactFormRequest({
|
||||||
|
contact: values.contact,
|
||||||
|
whoami: JSON.stringify({
|
||||||
|
dogiebusiness: values.dogiebusiness,
|
||||||
|
imagination: values.imagination,
|
||||||
|
name: values.name,
|
||||||
|
time: moment(values.time).format("hh:mm")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log(resp)
|
||||||
|
if (resp[0]?.status === 200) {
|
||||||
|
enqueueSnackbar("Запрос успешно отправлен")
|
||||||
|
onClose()
|
||||||
|
}
|
||||||
|
if (resp[1]) {
|
||||||
|
enqueueSnackbar(resp[1])
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ values, isSubmitting, setFieldValue }) => (<>
|
||||||
|
<Form>
|
||||||
|
<Field
|
||||||
|
title="Ваше имя"
|
||||||
|
placeholder="Иван"
|
||||||
|
value={values.name}
|
||||||
|
onChange={({ target }: any) => setFieldValue("name", target.value)}
|
||||||
|
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
title="Какой у вас бизнес?"
|
||||||
|
placeholder="Логистика"
|
||||||
|
value={values.dogiebusiness}
|
||||||
|
onChange={({ target }: any) => setFieldValue("dogiebusiness", target.value)}
|
||||||
|
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
title="Ваши контактные данные"
|
||||||
|
placeholder="Не менее 8 символов"
|
||||||
|
value={values.contact}
|
||||||
|
onChange={({ target }: any) => setFieldValue("contact", target.value)}
|
||||||
|
desc="(Telegram, WhatsApp, номер телефона)"
|
||||||
|
/>
|
||||||
|
<Field
|
||||||
|
title="Ваши пожелания к квизу"
|
||||||
|
placeholder="Введите свой текст здесь"
|
||||||
|
value={values.imagination}
|
||||||
|
onChange={({ target }: any) => setFieldValue("imagination", target.value)}
|
||||||
|
rows={2}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
m: "15px 0"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "18px",
|
||||||
|
fontWeight: 500,
|
||||||
|
lineHeight: "21.33px",
|
||||||
|
mb: "10px",
|
||||||
|
}}
|
||||||
|
>Во сколько вам можно позвонить? </Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontSize: "18px",
|
||||||
|
mb: "10px",
|
||||||
|
color: "#9A9AAF"
|
||||||
|
}}
|
||||||
|
>Москва (GMT+3)</Typography>
|
||||||
|
<TimePicker value={values.time}
|
||||||
|
onChange={(e) => setFieldValue("time", e)}
|
||||||
|
views={['hours', 'minutes']} format="hh:mm"
|
||||||
|
ampm={false}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex"
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
fullWidth
|
||||||
|
type="submit"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
sx={{
|
||||||
|
py: "12px",
|
||||||
|
"&:hover": {
|
||||||
|
backgroundColor: "#581CA7",
|
||||||
|
},
|
||||||
|
"&:active": {
|
||||||
|
color: "white",
|
||||||
|
backgroundColor: "black",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>Отправить</Button>
|
||||||
|
<Info sx={{
|
||||||
|
ml: "15px",
|
||||||
|
width: "48px"
|
||||||
|
}} />
|
||||||
|
</Box>
|
||||||
|
</Form>
|
||||||
|
</>)}
|
||||||
|
</Formik>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Modal >
|
||||||
|
)
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { CustomTab } from "./CustomTab";
|
|||||||
type TabsProps = {
|
type TabsProps = {
|
||||||
names: string[];
|
names: string[];
|
||||||
items: string[];
|
items: string[];
|
||||||
selectedItem: "day" | "count" | "dop";
|
selectedItem: "day" | "count" | "dop" | "hide" | "create";
|
||||||
setSelectedItem: (num: "day" | "count" | "dop") => void;
|
setSelectedItem: (num: "day" | "count" | "dop") => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,7 +25,46 @@ export const Tabs = ({
|
|||||||
scrollButtons={false}
|
scrollButtons={false}
|
||||||
>
|
>
|
||||||
{items.map((item, index) => (
|
{items.map((item, index) => (
|
||||||
<CustomTab key={item + index} value={item} label={names[index]} />
|
<CustomTab key={item + index} value={item}
|
||||||
|
sx={{
|
||||||
|
textUnderlinePosition: "under",
|
||||||
|
color:
|
||||||
|
selectedItem === "create" && item === "dop" ?
|
||||||
|
"#7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === "hide" && item === "dop" ?
|
||||||
|
"#7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === item ? "#7e2aea" : "black",
|
||||||
|
textDecoration:
|
||||||
|
selectedItem === "create" && item === "dop" ?
|
||||||
|
"underline #7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === "hide" && item === "dop" ?
|
||||||
|
"underline #7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === item ? "underline #7e2aea" : "none",
|
||||||
|
"&.Mui-selected": {
|
||||||
|
textDecoration:
|
||||||
|
selectedItem === "create" && item === "dop" ?
|
||||||
|
"underline #7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === "hide" && item === "dop" ?
|
||||||
|
"underline #7e2aea"
|
||||||
|
:
|
||||||
|
selectedItem === item ? "underline #7e2aea" : "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
|
||||||
|
label={
|
||||||
|
selectedItem === "create" && item === "dop" ?
|
||||||
|
"Доп. услуги — Создать квиз на заказ"
|
||||||
|
:
|
||||||
|
selectedItem === "hide" && item === "dop" ?
|
||||||
|
"Доп. услуги — Убрать логотип “PenaQuiz”"
|
||||||
|
:
|
||||||
|
names[index]
|
||||||
|
} />
|
||||||
))}
|
))}
|
||||||
</MuiTabs>
|
</MuiTabs>
|
||||||
);
|
);
|
||||||
|
@ -38,6 +38,8 @@ import { getUser } from "@api/user";
|
|||||||
import { getTariffs } from "@api/tariff";
|
import { getTariffs } from "@api/tariff";
|
||||||
|
|
||||||
import type { Discount } from "@model/discounts";
|
import type { Discount } from "@model/discounts";
|
||||||
|
import { Other } from "./pages/Other";
|
||||||
|
import { ModalRequestCreate } from "./ModalRequestCreate";
|
||||||
|
|
||||||
const StepperText: Record<string, string> = {
|
const StepperText: Record<string, string> = {
|
||||||
day: "Тарифы на время",
|
day: "Тарифы на время",
|
||||||
@ -46,6 +48,7 @@ const StepperText: Record<string, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function TariffPage() {
|
function TariffPage() {
|
||||||
|
const userPrivilegies = useUserStore(store => store.userAccount?.privileges);
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const token = useToken();
|
const token = useToken();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
@ -55,11 +58,10 @@ function TariffPage() {
|
|||||||
const [tariffs, setTariffs] = useState<Tariff[]>([]);
|
const [tariffs, setTariffs] = useState<Tariff[]>([]);
|
||||||
const [user, setUser] = useState();
|
const [user, setUser] = useState();
|
||||||
const [discounts, setDiscounts] = useState<Discount[]>([]);
|
const [discounts, setDiscounts] = useState<Discount[]>([]);
|
||||||
|
const [isRequestCreate, setIsRequestCreate] = useState(false);
|
||||||
const [openModal, setOpenModal] = useState({});
|
const [openModal, setOpenModal] = useState({});
|
||||||
const { cashString, cashCop, cashRub } = useWallet();
|
const { cashString, cashCop, cashRub } = useWallet();
|
||||||
const [selectedItem, setSelectedItem] = useState<"count" | "day" | "dop">(
|
const [selectedItem, setSelectedItem] = useState<TypePages>("day");
|
||||||
"day",
|
|
||||||
);
|
|
||||||
const { isTestServer } = useDomainDefine();
|
const { isTestServer } = useDomainDefine();
|
||||||
const [promocodeField, setPromocodeField] = useState<string>("");
|
const [promocodeField, setPromocodeField] = useState<string>("");
|
||||||
|
|
||||||
@ -174,15 +176,7 @@ function TariffPage() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const filteredBadgeTariffs = tariffs.filter((tariff) => {
|
|
||||||
return (
|
|
||||||
tariff.privileges[0].serviceKey === "squiz" &&
|
|
||||||
!tariff.isDeleted &&
|
|
||||||
!tariff.isCustom &&
|
|
||||||
tariff.privileges[0].privilegeId === "squizHideBadge" &&
|
|
||||||
tariff.privileges[0]?.type === "day"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
const filteredBaseTariffs = filteredTariffs.filter((tariff) => {
|
const filteredBaseTariffs = filteredTariffs.filter((tariff) => {
|
||||||
return tariff.privileges[0].privilegeId !== "squizHideBadge";
|
return tariff.privileges[0].privilegeId !== "squizHideBadge";
|
||||||
});
|
});
|
||||||
@ -215,6 +209,10 @@ function TariffPage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startRequestCreate = () => {
|
||||||
|
setIsRequestCreate(true)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Container
|
<Container
|
||||||
@ -288,6 +286,7 @@ function TariffPage() {
|
|||||||
items={Object.keys(StepperText)}
|
items={Object.keys(StepperText)}
|
||||||
selectedItem={selectedItem}
|
selectedItem={selectedItem}
|
||||||
setSelectedItem={setSelectedItem}
|
setSelectedItem={setSelectedItem}
|
||||||
|
toDop={() => setSelectedItem("dop")}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
@ -296,9 +295,8 @@ function TariffPage() {
|
|||||||
display: selectedItem === "dop" ? "flex" : "grid",
|
display: selectedItem === "dop" ? "flex" : "grid",
|
||||||
gap: "40px",
|
gap: "40px",
|
||||||
p: "20px",
|
p: "20px",
|
||||||
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${
|
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px"
|
||||||
isTablet ? "436px" : "360px"
|
}))`,
|
||||||
}))`,
|
|
||||||
flexDirection: selectedItem === "dop" ? "column" : undefined,
|
flexDirection: selectedItem === "dop" ? "column" : undefined,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -318,29 +316,29 @@ function TariffPage() {
|
|||||||
discounts,
|
discounts,
|
||||||
openModalHC,
|
openModalHC,
|
||||||
)}
|
)}
|
||||||
{selectedItem === "dop" && (
|
{(selectedItem === "dop" || selectedItem === "hide" || selectedItem === "create")
|
||||||
<>
|
&& (
|
||||||
<Typography fontWeight={500}>Убрать логотип "PenaQuiz"</Typography>
|
<Other
|
||||||
<Box
|
selectedItem={selectedItem}
|
||||||
sx={{
|
content={[
|
||||||
justifyContent: "left",
|
{
|
||||||
display: "grid",
|
title: `Убрать логотип “PenaQuiz”`,
|
||||||
gap: "40px",
|
onClick: () => setSelectedItem("hide")
|
||||||
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${
|
},
|
||||||
isTablet ? "436px" : "360px"
|
{
|
||||||
}))`,
|
title: "Создать квиз на заказ",
|
||||||
}}
|
onClick: () => setSelectedItem("create")
|
||||||
>
|
},
|
||||||
{createTariffElements(
|
]}
|
||||||
filteredBadgeTariffs,
|
|
||||||
false,
|
tariffs={tariffs}
|
||||||
user,
|
user={user}
|
||||||
discounts,
|
discounts={discounts}
|
||||||
openModalHC,
|
openModalHC={openModalHC}
|
||||||
)}
|
userPrivilegies={userPrivilegies}
|
||||||
</Box>
|
startRequestCreate={startRequestCreate}
|
||||||
</>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Modal
|
<Modal
|
||||||
open={Object.values(openModal).length > 0}
|
open={Object.values(openModal).length > 0}
|
||||||
@ -373,6 +371,7 @@ function TariffPage() {
|
|||||||
</Button>
|
</Button>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
<ModalRequestCreate open={isRequestCreate} onClose={() => setIsRequestCreate(false)} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -383,7 +382,7 @@ export const Tariffs = withErrorBoundary(TariffPage, {
|
|||||||
Ошибка загрузки тарифов
|
Ошибка загрузки тарифов
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
onError: () => {},
|
onError: () => { },
|
||||||
});
|
});
|
||||||
|
|
||||||
const LoadingPage = () => (
|
const LoadingPage = () => (
|
||||||
@ -426,20 +425,20 @@ export const inCart = () => {
|
|||||||
const outCart = (cart: string[]) => {
|
const outCart = (cart: string[]) => {
|
||||||
//Сделаем муторно и подольше, зато при прерывании сессии данные потеряются минимально
|
//Сделаем муторно и подольше, зато при прерывании сессии данные потеряются минимально
|
||||||
if (cart.length > 0) {
|
if (cart.length > 0) {
|
||||||
cart.forEach(async (id: string) => {
|
cart.forEach(async (id: string) => {
|
||||||
const [_, deleteError] = await cartApi.delete(id);
|
const [_, deleteError] = await cartApi.delete(id);
|
||||||
|
|
||||||
if (deleteError) {
|
if (deleteError) {
|
||||||
console.error(deleteError);
|
console.error(deleteError);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]") || [];
|
let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]") || [];
|
||||||
if (!Array.isArray(saveCart)) saveCart = []
|
if (!Array.isArray(saveCart)) saveCart = []
|
||||||
saveCart = saveCart.push(id);
|
saveCart = saveCart.push(id);
|
||||||
localStorage.setItem("saveCart", JSON.stringify(saveCart));
|
localStorage.setItem("saveCart", JSON.stringify(saveCart));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
38
src/pages/Tariffs/components/NavCard.tsx
Normal file
38
src/pages/Tariffs/components/NavCard.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import SimpleArrowDown from "@/ui_kit/SimpleArrowDown";
|
||||||
|
import { Box, ButtonBase, Typography } from "@mui/material"
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title: string;
|
||||||
|
onClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NavCard = ({
|
||||||
|
title,
|
||||||
|
onClick
|
||||||
|
}: Props) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ButtonBase onClick={onClick}
|
||||||
|
sx={{
|
||||||
|
maxWidth: "570px",
|
||||||
|
height: "70px",
|
||||||
|
borderRadius: "12px",
|
||||||
|
bgcolor: "white",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
p: "0 20px 0 30px",
|
||||||
|
m: "10px",
|
||||||
|
minWidth: "343px",
|
||||||
|
width: "100%"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography>{title}</Typography>
|
||||||
|
|
||||||
|
<SimpleArrowDown
|
||||||
|
sx={{
|
||||||
|
transform: "rotate(270deg)"
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ButtonBase>
|
||||||
|
)
|
||||||
|
}
|
0
src/pages/Tariffs/pages/HideLogo.tsx
Normal file
0
src/pages/Tariffs/pages/HideLogo.tsx
Normal file
95
src/pages/Tariffs/pages/Other.tsx
Normal file
95
src/pages/Tariffs/pages/Other.tsx
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import { Box, useMediaQuery, useTheme } from "@mui/material"
|
||||||
|
import { NavCard } from "../components/NavCard"
|
||||||
|
import { createTariffElements } from "../tariffsUtils/createTariffElements"
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
content: {
|
||||||
|
title: string,
|
||||||
|
onClick: () => void
|
||||||
|
}[]
|
||||||
|
selectedItem: TypePages
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Other = ({
|
||||||
|
content,
|
||||||
|
selectedItem,
|
||||||
|
|
||||||
|
tariffs,
|
||||||
|
user,
|
||||||
|
discounts,
|
||||||
|
openModalHC,
|
||||||
|
userPrivilegies,
|
||||||
|
startRequestCreate
|
||||||
|
}: any) => {
|
||||||
|
const theme = useTheme()
|
||||||
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
const sendRequestToCreate = userPrivilegies?.quizManual.amount > 0 ? startRequestCreate : undefined
|
||||||
|
console.log("sendRequestToCreate")
|
||||||
|
console.log(sendRequestToCreate)
|
||||||
|
switch (selectedItem) {
|
||||||
|
case "hide":
|
||||||
|
const filteredBadgeTariffs = tariffs.filter((tariff) => {
|
||||||
|
return (
|
||||||
|
tariff.privileges[0].serviceKey === "squiz" &&
|
||||||
|
!tariff.isDeleted &&
|
||||||
|
!tariff.isCustom &&
|
||||||
|
tariff.privileges[0].privilegeId === "squizHideBadge" &&
|
||||||
|
tariff.privileges[0]?.type === "day"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return <Box
|
||||||
|
sx={{
|
||||||
|
justifyContent: "left",
|
||||||
|
display: "grid",
|
||||||
|
gap: "40px",
|
||||||
|
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px"
|
||||||
|
}))`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{createTariffElements(
|
||||||
|
filteredBadgeTariffs,
|
||||||
|
false,
|
||||||
|
user,
|
||||||
|
discounts,
|
||||||
|
openModalHC,
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
case "create":
|
||||||
|
const filteredCreateTariffs = tariffs.filter((tariff) => {
|
||||||
|
return (
|
||||||
|
tariff.privileges[0].serviceKey === "squiz" &&
|
||||||
|
!tariff.isDeleted &&
|
||||||
|
!tariff.isCustom &&
|
||||||
|
tariff.privileges[0].privilegeId === "quizManual" &&
|
||||||
|
tariff.privileges[0]?.type === "count"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return <Box
|
||||||
|
sx={{
|
||||||
|
justifyContent: "left",
|
||||||
|
display: "grid",
|
||||||
|
gap: "40px",
|
||||||
|
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px"
|
||||||
|
}))`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{createTariffElements(
|
||||||
|
filteredCreateTariffs,
|
||||||
|
false,
|
||||||
|
user,
|
||||||
|
discounts,
|
||||||
|
openModalHC,
|
||||||
|
sendRequestToCreate
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
default:
|
||||||
|
return <Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
width: "100%"
|
||||||
|
}}>
|
||||||
|
{content.map(data => <NavCard {...data} key={data.title} />)}
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ interface Props {
|
|||||||
text?: string;
|
text?: string;
|
||||||
};
|
};
|
||||||
price?: ReactNode;
|
price?: ReactNode;
|
||||||
|
sendRequestToCreate?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TariffCard({
|
export default function TariffCard({
|
||||||
@ -33,6 +34,7 @@ export default function TariffCard({
|
|||||||
price,
|
price,
|
||||||
buttonProps,
|
buttonProps,
|
||||||
discount,
|
discount,
|
||||||
|
sendRequestToCreate,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
text = Array.isArray(text) ? text : [text];
|
text = Array.isArray(text) ? text : [text];
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -132,12 +134,20 @@ export default function TariffCard({
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<Box
|
||||||
|
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
width: "100%",
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
|
|
||||||
{buttonProps && (
|
{buttonProps && (
|
||||||
<Button
|
<Button
|
||||||
onClick={buttonProps.onClick}
|
onClick={buttonProps.onClick}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{
|
sx={{
|
||||||
mt: "10px",
|
// mt: "10px",
|
||||||
color: "#7e2aea",
|
color: "#7e2aea",
|
||||||
minWidth: "180px",
|
minWidth: "180px",
|
||||||
background: "transparent",
|
background: "transparent",
|
||||||
@ -157,6 +167,17 @@ export default function TariffCard({
|
|||||||
{buttonProps.text}
|
{buttonProps.text}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{Boolean(sendRequestToCreate) && (
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
ml: "30px"
|
||||||
|
}}
|
||||||
|
onClick={sendRequestToCreate}
|
||||||
|
>
|
||||||
|
Запросить
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
</Box >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ export const createTariffElements = (
|
|||||||
user: any,
|
user: any,
|
||||||
discounts: any,
|
discounts: any,
|
||||||
onclick: any,
|
onclick: any,
|
||||||
|
sendRequestToCreate?: () => void
|
||||||
) => {
|
) => {
|
||||||
const tariffElements = filteredTariffs
|
const tariffElements = filteredTariffs
|
||||||
.filter((tariff) => tariff.privileges.length > 0)
|
.filter((tariff) => tariff.privileges.length > 0)
|
||||||
@ -43,13 +44,14 @@ export const createTariffElements = (
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
buttonProps={{
|
buttonProps={{
|
||||||
text: "Выбрать",
|
text: "Купить",
|
||||||
onClick: () =>
|
onClick: () =>
|
||||||
onclick({
|
onclick({
|
||||||
id: tariff._id,
|
id: tariff._id,
|
||||||
price: Math.trunc(priceAfterDiscounts) / 100,
|
price: Math.trunc(priceAfterDiscounts) / 100,
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
|
sendRequestToCreate={sendRequestToCreate}
|
||||||
headerText={tariff.name}
|
headerText={tariff.name}
|
||||||
text={tariff.description}
|
text={tariff.description}
|
||||||
price={
|
price={
|
||||||
|
1
src/pages/Tariffs/types.ts
Normal file
1
src/pages/Tariffs/types.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
type TypePages = "count" | "day" | "dop" | "hide" | "create"
|
@ -70,6 +70,9 @@ export const parseAxiosError = (nativeError: unknown): [string, number?] => {
|
|||||||
|
|
||||||
case 403:
|
case 403:
|
||||||
return ["Доступ ограничен.", error.status];
|
return ["Доступ ограничен.", error.status];
|
||||||
|
|
||||||
|
case 429:
|
||||||
|
return ["Слишком частые запросы", error.status];
|
||||||
|
|
||||||
case 401:
|
case 401:
|
||||||
return ["Ошибка авторизации.", error.status];
|
return ["Ошибка авторизации.", error.status];
|
||||||
|
Loading…
Reference in New Issue
Block a user