diff --git a/src/api/tariff.ts b/src/api/tariff.ts index 0ddaceee..a1b4ea3d 100644 --- a/src/api/tariff.ts +++ b/src/api/tariff.ts @@ -21,3 +21,28 @@ export const getTariffs = async ( 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}`]; + } +} \ No newline at end of file diff --git a/src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx b/src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx index 3ef074bb..3216435f 100644 --- a/src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx +++ b/src/pages/IntegrationsPage/IntegrationsModal/Amo/index.tsx @@ -81,39 +81,38 @@ export const AmoCRMModal: FC = ({ isModalOpen, handleClo }} > - - - Интеграция с {companyName ? companyName : "партнером"} - - - - - + + Интеграция с {companyName ? companyName : "партнером"} + + + + + ; +} +export default function CloseIcon({ sx }: Props) { const location = useLocation(); return ( 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 ( + + {title} + {desc && {desc}} + + + ) +} + +export const ModalRequestCreate = ({ + open, + onClose +}: Props) => { + const theme = useTheme() + const isMobile = useMediaQuery(theme.breakpoints.down(650)); + + + return ( + + + + + + Заполните форму, чтобы оставить заявку на создание квиза + + + + + + + + { + 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 }) => (<> +
+ setFieldValue("name", target.value)} + + /> + setFieldValue("dogiebusiness", target.value)} + + /> + setFieldValue("contact", target.value)} + desc="(Telegram, WhatsApp, номер телефона)" + /> + setFieldValue("imagination", target.value)} + rows={2} + /> + + + Во сколько вам можно позвонить? + Москва (GMT+3) + setFieldValue("time", e)} + views={['hours', 'minutes']} format="hh:mm" + ampm={false} + /> + + + + + + + +
+ )} +
+
+
+
+ ) +} diff --git a/src/pages/Tariffs/Tabs.tsx b/src/pages/Tariffs/Tabs.tsx index 005e8640..bcfeec11 100644 --- a/src/pages/Tariffs/Tabs.tsx +++ b/src/pages/Tariffs/Tabs.tsx @@ -4,7 +4,7 @@ import { CustomTab } from "./CustomTab"; type TabsProps = { names: string[]; items: string[]; - selectedItem: "day" | "count" | "dop"; + selectedItem: "day" | "count" | "dop" | "hide" | "create"; setSelectedItem: (num: "day" | "count" | "dop") => void; }; @@ -25,7 +25,46 @@ export const Tabs = ({ scrollButtons={false} > {items.map((item, index) => ( - + ))} ); diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index 1660f131..b100d181 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -38,6 +38,8 @@ import { getUser } from "@api/user"; import { getTariffs } from "@api/tariff"; import type { Discount } from "@model/discounts"; +import { Other } from "./pages/Other"; +import { ModalRequestCreate } from "./ModalRequestCreate"; const StepperText: Record = { day: "Тарифы на время", @@ -46,6 +48,7 @@ const StepperText: Record = { }; function TariffPage() { + const userPrivilegies = useUserStore(store => store.userAccount?.privileges); const theme = useTheme(); const token = useToken(); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); @@ -55,11 +58,10 @@ function TariffPage() { const [tariffs, setTariffs] = useState([]); const [user, setUser] = useState(); const [discounts, setDiscounts] = useState([]); + const [isRequestCreate, setIsRequestCreate] = useState(false); const [openModal, setOpenModal] = useState({}); const { cashString, cashCop, cashRub } = useWallet(); - const [selectedItem, setSelectedItem] = useState<"count" | "day" | "dop">( - "day", - ); + const [selectedItem, setSelectedItem] = useState("day"); const { isTestServer } = useDomainDefine(); const [promocodeField, setPromocodeField] = useState(""); @@ -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) => { return tariff.privileges[0].privilegeId !== "squizHideBadge"; }); @@ -215,6 +209,10 @@ function TariffPage() { } } + const startRequestCreate = () => { + setIsRequestCreate(true) + } + return ( <> setSelectedItem("dop")} /> @@ -318,29 +316,29 @@ function TariffPage() { discounts, openModalHC, )} - {selectedItem === "dop" && ( - <> - Убрать логотип "PenaQuiz" - - {createTariffElements( - filteredBadgeTariffs, - false, - user, - discounts, - openModalHC, - )} - - - )} + {(selectedItem === "dop" || selectedItem === "hide" || selectedItem === "create") + && ( + setSelectedItem("hide") + }, + { + title: "Создать квиз на заказ", + onClick: () => setSelectedItem("create") + }, + ]} + + tariffs={tariffs} + user={user} + discounts={discounts} + openModalHC={openModalHC} + userPrivilegies={userPrivilegies} + startRequestCreate={startRequestCreate} + /> + )} 0} @@ -373,6 +371,7 @@ function TariffPage() { + setIsRequestCreate(false)} /> ); } @@ -383,7 +382,7 @@ export const Tariffs = withErrorBoundary(TariffPage, { Ошибка загрузки тарифов ), - onError: () => {}, + onError: () => { }, }); const LoadingPage = () => ( @@ -426,20 +425,20 @@ export const inCart = () => { const outCart = (cart: string[]) => { //Сделаем муторно и подольше, зато при прерывании сессии данные потеряются минимально if (cart.length > 0) { - cart.forEach(async (id: string) => { - const [_, deleteError] = await cartApi.delete(id); + cart.forEach(async (id: string) => { + const [_, deleteError] = await cartApi.delete(id); - if (deleteError) { - console.error(deleteError); + if (deleteError) { + console.error(deleteError); - return; - } + return; + } - let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]") || []; - if (!Array.isArray(saveCart)) saveCart = [] - saveCart = saveCart.push(id); - localStorage.setItem("saveCart", JSON.stringify(saveCart)); - }); + let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]") || []; + if (!Array.isArray(saveCart)) saveCart = [] + saveCart = saveCart.push(id); + localStorage.setItem("saveCart", JSON.stringify(saveCart)); + }); } }; diff --git a/src/pages/Tariffs/components/NavCard.tsx b/src/pages/Tariffs/components/NavCard.tsx new file mode 100644 index 00000000..74a6ed7f --- /dev/null +++ b/src/pages/Tariffs/components/NavCard.tsx @@ -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 ( + + {title} + + + + ) +} \ No newline at end of file diff --git a/src/pages/Tariffs/pages/HideLogo.tsx b/src/pages/Tariffs/pages/HideLogo.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/pages/Tariffs/pages/Other.tsx b/src/pages/Tariffs/pages/Other.tsx new file mode 100644 index 00000000..a9a7dec7 --- /dev/null +++ b/src/pages/Tariffs/pages/Other.tsx @@ -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 + {createTariffElements( + filteredBadgeTariffs, + false, + user, + discounts, + openModalHC, + )} + + 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 + {createTariffElements( + filteredCreateTariffs, + false, + user, + discounts, + openModalHC, + sendRequestToCreate + )} + + default: + return + {content.map(data => )} + + } +} \ No newline at end of file diff --git a/src/pages/Tariffs/tariffsUtils/TariffCard.tsx b/src/pages/Tariffs/tariffsUtils/TariffCard.tsx index 205e7a23..165e144f 100644 --- a/src/pages/Tariffs/tariffsUtils/TariffCard.tsx +++ b/src/pages/Tariffs/tariffsUtils/TariffCard.tsx @@ -23,6 +23,7 @@ interface Props { text?: string; }; price?: ReactNode; + sendRequestToCreate?: () => void } export default function TariffCard({ @@ -33,6 +34,7 @@ export default function TariffCard({ price, buttonProps, discount, + sendRequestToCreate, }: Props) { text = Array.isArray(text) ? text : [text]; const theme = useTheme(); @@ -132,12 +134,20 @@ export default function TariffCard({ ))}
+ + {buttonProps && ( + )} +
); } diff --git a/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx b/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx index f0ea9d54..3d58e531 100644 --- a/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx +++ b/src/pages/Tariffs/tariffsUtils/createTariffElements.tsx @@ -11,6 +11,7 @@ export const createTariffElements = ( user: any, discounts: any, onclick: any, + sendRequestToCreate?: () => void ) => { const tariffElements = filteredTariffs .filter((tariff) => tariff.privileges.length > 0) @@ -43,13 +44,14 @@ export const createTariffElements = ( /> } buttonProps={{ - text: "Выбрать", + text: "Купить", onClick: () => onclick({ id: tariff._id, price: Math.trunc(priceAfterDiscounts) / 100, }), }} + sendRequestToCreate={sendRequestToCreate} headerText={tariff.name} text={tariff.description} price={ diff --git a/src/pages/Tariffs/types.ts b/src/pages/Tariffs/types.ts new file mode 100644 index 00000000..fd6c0dea --- /dev/null +++ b/src/pages/Tariffs/types.ts @@ -0,0 +1 @@ +type TypePages = "count" | "day" | "dop" | "hide" | "create" \ No newline at end of file diff --git a/src/utils/parse-error.ts b/src/utils/parse-error.ts index af94459d..7191006d 100644 --- a/src/utils/parse-error.ts +++ b/src/utils/parse-error.ts @@ -70,6 +70,9 @@ export const parseAxiosError = (nativeError: unknown): [string, number?] => { case 403: return ["Доступ ограничен.", error.status]; + + case 429: + return ["Слишком частые запросы", error.status]; case 401: return ["Ошибка авторизации.", error.status];