Merge branch 'dev' into 'staging'
Dev See merge request frontend/marketplace!228
This commit is contained in:
commit
841352a698
@ -19,6 +19,7 @@
|
||||
"@frontend/kitui": "^1.0.85",
|
||||
"@mui/icons-material": "^5.10.14",
|
||||
"@mui/material": "^5.10.14",
|
||||
"@mui/x-date-pickers": "^7.13.0",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"axios": "^1.4.0",
|
||||
"buffer": "^6.0.3",
|
||||
|
@ -8,6 +8,7 @@ import type {
|
||||
} from "@root/model/privilege";
|
||||
import type { GetTariffsResponse } from "@root/model/tariff";
|
||||
import { removeTariffFromCart } from "@root/stores/user";
|
||||
import axios from "axios";
|
||||
|
||||
interface CreateTariffBody {
|
||||
name: string;
|
||||
@ -134,3 +135,24 @@ export const getTariffArray = async (tariffIds: string[] | undefined) => {
|
||||
|
||||
return tariffs;
|
||||
};
|
||||
|
||||
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}`];
|
||||
}
|
||||
}
|
@ -23,12 +23,20 @@ export const sendPayment = async ({
|
||||
body,
|
||||
fromSquiz,
|
||||
paymentPurpose,
|
||||
cc
|
||||
}: {
|
||||
userId: string;
|
||||
body: PaymentBody;
|
||||
fromSquiz: boolean;
|
||||
paymentPurpose: "paycart" | "replenishwallet";
|
||||
cc?: boolean
|
||||
}): Promise<[SendPaymentResponse | null, string?]> => {
|
||||
|
||||
let returnLink = `${isLocalhost ? "localhost:3000" : `https://${isStaging}hub.pena.digital`}/afterpay?from=${
|
||||
fromSquiz ? "quiz" : "hub"
|
||||
}&purpose=${paymentPurpose}&userid=${userId}`
|
||||
if (cc) returnLink = returnLink + "&cc=true"
|
||||
|
||||
const reqeustBody = {
|
||||
currency: "RUB",
|
||||
bankCard: {
|
||||
@ -40,9 +48,7 @@ export const sendPayment = async ({
|
||||
},
|
||||
phoneNumber: "79000000000",
|
||||
login: "login_test",
|
||||
returnUrl: `${isLocalhost ? "localhost:3000" : `https://${isStaging}hub.pena.digital`}/afterpay?from=${
|
||||
fromSquiz ? "quiz" : "hub"
|
||||
}&purpose=${paymentPurpose}&userid=${userId}`,
|
||||
returnUrl: returnLink,
|
||||
...body,
|
||||
};
|
||||
|
||||
|
38
src/assets/Icons/CloseIcon.tsx
Normal file
38
src/assets/Icons/CloseIcon.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { Box, SxProps, Theme } from "@mui/material";
|
||||
|
||||
interface Props {
|
||||
sx?: SxProps<Theme>;
|
||||
}
|
||||
export default function CloseIcon({ sx }: Props) {
|
||||
const location = useLocation();
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "30px",
|
||||
height: "30px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flexShrink: 0,
|
||||
"&:hover path": {
|
||||
stroke: "#7E2AEA",
|
||||
},
|
||||
...sx
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="26"
|
||||
height="26"
|
||||
viewBox="0 0 26 26"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1 1L25 25M1 25L25 1"
|
||||
stroke={location.pathname === "/" ? "white" : "black"}
|
||||
/>
|
||||
</svg>
|
||||
</Box>
|
||||
);
|
||||
}
|
152
src/components/CustomTextField.tsx
Executable file
152
src/components/CustomTextField.tsx
Executable file
@ -0,0 +1,152 @@
|
||||
import type { ChangeEvent, FocusEvent, KeyboardEvent } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import type { InputProps, SxProps, Theme } from "@mui/material";
|
||||
import {
|
||||
Box,
|
||||
FormControl,
|
||||
Input,
|
||||
InputLabel,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
|
||||
interface CustomTextFieldProps {
|
||||
placeholder: string;
|
||||
id?: string;
|
||||
value?: string;
|
||||
error?: string;
|
||||
emptyError?: boolean;
|
||||
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
|
||||
onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
||||
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
||||
text?: string;
|
||||
maxLength?: number;
|
||||
sx?: SxProps<Theme>;
|
||||
sxForm?: SxProps<Theme>;
|
||||
InputProps?: Partial<InputProps>;
|
||||
type?: string;
|
||||
rows?: number;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export default function CustomTextField({
|
||||
placeholder,
|
||||
id,
|
||||
value = "",
|
||||
onChange,
|
||||
onKeyDown,
|
||||
onBlur,
|
||||
text,
|
||||
sx,
|
||||
error,
|
||||
emptyError,
|
||||
InputProps,
|
||||
maxLength = 200,
|
||||
type = "",
|
||||
rows = 0,
|
||||
sxForm,
|
||||
className,
|
||||
disabled,
|
||||
}: CustomTextFieldProps) {
|
||||
const theme = useTheme();
|
||||
|
||||
const [inputValue, setInputValue] = useState("");
|
||||
const [isInputActive, setIsInputActive] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setInputValue(value);
|
||||
}, [value]);
|
||||
|
||||
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (event.target.value.length <= maxLength) {
|
||||
const inputValue = event.target.value;
|
||||
|
||||
if (type === "number") {
|
||||
setInputValue(inputValue.replace(/\D/g, ""));
|
||||
} else {
|
||||
setInputValue(inputValue);
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleInputFocus = () => {
|
||||
setIsInputActive(true);
|
||||
};
|
||||
|
||||
const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
setIsInputActive(false);
|
||||
|
||||
if (onBlur) {
|
||||
onBlur(event);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
fullWidth
|
||||
variant="standard"
|
||||
sx={{ p: 0, ...sxForm }}
|
||||
className={className || ""}
|
||||
>
|
||||
{error && (
|
||||
<InputLabel
|
||||
sx={{
|
||||
fontSize: "13.5px",
|
||||
marginTop: "3px",
|
||||
}}
|
||||
>
|
||||
{error}
|
||||
</InputLabel>
|
||||
)}
|
||||
<Input
|
||||
id={id}
|
||||
defaultValue={text}
|
||||
fullWidth
|
||||
value={inputValue}
|
||||
placeholder={placeholder}
|
||||
onChange={handleInputChange}
|
||||
error={!!error || emptyError}
|
||||
onFocus={handleInputFocus}
|
||||
onBlur={handleInputBlur}
|
||||
onKeyDown={onKeyDown}
|
||||
multiline={rows > 0}
|
||||
rows={rows}
|
||||
disabled={disabled}
|
||||
disableUnderline
|
||||
sx={{
|
||||
maxLength: maxLength,
|
||||
borderRadius: "10px",
|
||||
fontSize: "18px",
|
||||
lineHeight: "21px",
|
||||
p: "13px",
|
||||
border: `${isInputActive ? "black 2px" : "#9A9AAF 1px"} solid`,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
height: "48px",
|
||||
...sx,
|
||||
}}
|
||||
data-cy="textfield"
|
||||
/>
|
||||
{isInputActive && inputValue.length >= maxLength - 7 && (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
marginTop: "5px",
|
||||
marginLeft: "auto",
|
||||
position: "absolute",
|
||||
bottom: "-25px",
|
||||
right: "0",
|
||||
}}
|
||||
>
|
||||
<Typography fontSize="14px">{inputValue.length}</Typography>
|
||||
<span>/</span>
|
||||
<Typography fontSize="14px">{maxLength}</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</FormControl>
|
||||
);
|
||||
}
|
50
src/components/InfoButton.tsx
Normal file
50
src/components/InfoButton.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import { IconButton, SxProps } from "@mui/material";
|
||||
|
||||
type InfoProps = {
|
||||
width?: number;
|
||||
height?: number;
|
||||
sx?: SxProps;
|
||||
onClick?: any;
|
||||
className?: string;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
export default function InfoButton({
|
||||
width = 20,
|
||||
height = 20,
|
||||
sx,
|
||||
onClick,
|
||||
className,
|
||||
color = "#7e2aea",
|
||||
}: InfoProps) {
|
||||
return (
|
||||
<IconButton sx={sx} className={className} onClick={onClick}>
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10 19C14.9706 19 19 14.9706 19 10C19 5.02944 14.9706 1 10 1C5.02944 1 1 5.02944 1 10C1 14.9706 5.02944 19 10 19Z"
|
||||
stroke={color}
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M9.25 9.25H10V14.5H10.75"
|
||||
stroke={color}
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M9.8125 7C10.4338 7 10.9375 6.49632 10.9375 5.875C10.9375 5.25368 10.4338 4.75 9.8125 4.75C9.19118 4.75 8.6875 5.25368 8.6875 5.875C8.6875 6.49632 9.19118 7 9.8125 7Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
</IconButton>
|
||||
);
|
||||
}
|
@ -72,10 +72,10 @@ export const Select = ({ items, selectedItem, setSelectedItem }: SelectProps) =>
|
||||
className="select"
|
||||
value=""
|
||||
open={opened}
|
||||
onClick={() => setOpened((isOpened) => !isOpened)}
|
||||
MenuProps={{ disablePortal: true }}
|
||||
sx={{ width: "100%",zIndex: 1, }}
|
||||
onChange={selectItem}
|
||||
onClick={() => setOpened((isOpened) => !isOpened)}
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
<MenuItem key={item + index} value={index} sx={{ padding: "12px" }}>
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
useNavigate,
|
||||
} from "react-router-dom";
|
||||
import { CssBaseline, ThemeProvider } from "@mui/material";
|
||||
import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
|
||||
import Faq from "./pages/Faq/Faq";
|
||||
import Wallet from "./pages/Wallet";
|
||||
import Payment from "./pages/Payment/Payment";
|
||||
@ -44,6 +45,7 @@ import {
|
||||
useUserFetcher,
|
||||
} from "@frontend/kitui";
|
||||
import { pdfjs } from "react-pdf";
|
||||
import { ruRU } from "@mui/x-date-pickers/locales";
|
||||
import { theme } from "./utils/theme";
|
||||
import PPofData from "@root/docs/PPofData";
|
||||
import Docs from "@root/docs/docs";
|
||||
@ -60,9 +62,12 @@ import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber";
|
||||
import moment from "moment";
|
||||
import { payCart } from "./api/cart";
|
||||
import { useAfterPay } from "./utils/hooks/useAutoPay";
|
||||
import { LocalizationProvider } from "@mui/x-date-pickers";
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`;
|
||||
|
||||
const localeText =
|
||||
ruRU.components.MuiLocalizationProvider.defaultProps.localeText;
|
||||
const App = () => {
|
||||
const location = useLocation();
|
||||
const user = useUserStore(state => state.user);
|
||||
@ -213,11 +218,17 @@ const root = ReactDOM.createRoot(
|
||||
root.render(
|
||||
// <React.StrictMode>
|
||||
<ThemeProvider theme={theme}>
|
||||
<LocalizationProvider
|
||||
dateAdapter={AdapterMoment}
|
||||
adapterLocale="ru"
|
||||
localeText={localeText}
|
||||
>
|
||||
<BrowserRouter>
|
||||
<CssBaseline />
|
||||
<SnackbarProvider />
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</LocalizationProvider>
|
||||
</ThemeProvider>
|
||||
// </React.StrictMode>
|
||||
);
|
||||
|
@ -63,10 +63,8 @@ export default function DocumentItem({
|
||||
useEffect(() => {
|
||||
if (typeof documentUrl === 'string') {
|
||||
if (!documentUrl.includes("pena.digital")) {
|
||||
console.log(documentUrl)
|
||||
fetch(documentUrl)
|
||||
.then(e => {
|
||||
console.log(e)
|
||||
setReadyShowDocument(true)
|
||||
})
|
||||
.catch(e => console.log(e))
|
||||
|
@ -43,10 +43,8 @@ export default function DocumentUploadItem({
|
||||
useEffect(() => {
|
||||
if (typeof urlOrFile === 'string') {
|
||||
if (!urlOrFile.includes("pena.digital")) {
|
||||
console.log(documentUrl)
|
||||
fetch(documentUrl)
|
||||
.then(e => {
|
||||
console.log(e)
|
||||
setReadyShowDocument(true)
|
||||
})
|
||||
.catch(e => console.log(e))
|
||||
|
@ -21,9 +21,6 @@ export default function UserFields({
|
||||
const { settingsFields, user } = useUserStore((state) => state)
|
||||
const a = useUserStore((state) => state)
|
||||
|
||||
console.log(a)
|
||||
console.log(settingsFields)
|
||||
|
||||
const textFieldProps = {
|
||||
gap: upMd ? "16px" : "10px",
|
||||
color: "#F2F3F7",
|
||||
|
@ -17,9 +17,6 @@ export default () => {
|
||||
const domain = (host.includes("s") ? "s" : "") + from;
|
||||
const pathname = from.includes("hub") ? "/tariffs" : "/list";
|
||||
|
||||
console.log(from, " from")
|
||||
console.log(`https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`)
|
||||
|
||||
document.location.href = `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`
|
||||
return <></>;
|
||||
};
|
||||
|
@ -70,9 +70,7 @@ export default function Payment() {
|
||||
const [paymentValueField, setPaymentValueField] = useState<string>("0");
|
||||
|
||||
const [fromSquiz, setIsFromSquiz] = useState<boolean>(false);
|
||||
|
||||
console.log("fromSquiz")
|
||||
console.log(fromSquiz)
|
||||
const [cc, setCC] = useState<boolean>(false);
|
||||
|
||||
|
||||
const [warnModalOpen, setWarnModalOpen] = useState<boolean>(false);
|
||||
@ -93,12 +91,8 @@ export default function Payment() {
|
||||
}
|
||||
}, [])
|
||||
|
||||
console.log(siteReadyPayCart)
|
||||
console.log(notEnoughMoneyAmount)
|
||||
//Тут записываем начальную сумму в инпут (если стоит флаг что мы в процессе покупки)
|
||||
useEffect(() => {
|
||||
console.log(siteReadyPayCart)
|
||||
console.log(notEnoughMoneyAmount)
|
||||
if (siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined && calcTimeOfReadyPayCart(siteReadyPayCart[userId]))
|
||||
setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе
|
||||
}, [notEnoughMoneyAmount, siteReadyPayCart])
|
||||
@ -108,10 +102,9 @@ export default function Payment() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const fromSquiz = params.get("action");
|
||||
const userid = params.get("user");
|
||||
console.log(fromSquiz)
|
||||
console.log(fromSquiz === "squizpay")
|
||||
console.log(userid)
|
||||
console.log(userid !== null)
|
||||
const currentCC = params.get("cc");
|
||||
if (currentCC) setCC(true)
|
||||
|
||||
if (fromSquiz === "squizpay" && userid !== null) {
|
||||
setIsFromSquiz(true);
|
||||
}
|
||||
@ -175,6 +168,7 @@ export default function Payment() {
|
||||
),
|
||||
},
|
||||
paymentPurpose: notEnoughMoneyAmount ? "paycart" : "replenishwallet",
|
||||
cc
|
||||
});
|
||||
|
||||
if (sendPaymentError) {
|
||||
|
@ -21,12 +21,12 @@ import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess } from "@stores/notEnoughMoneyAmount"
|
||||
|
||||
console.log("выясняю парамсы")
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
let action = params.get("action");
|
||||
let dif = params.get("dif");
|
||||
let token = params.get("data");
|
||||
let userId = params.get("userid");
|
||||
let currentCC = params.get("cc");
|
||||
|
||||
let first = true;
|
||||
|
||||
@ -42,7 +42,9 @@ export default function QuizPayment() {
|
||||
if (fromSquiz === "squizpay") {
|
||||
setNotEnoughMoneyAmount(Number(params.get("dif") || 0));//Сколько нехватило на квизе
|
||||
startPayCartProcess(userId)
|
||||
navigate(`/payment?action=${action}&dif=${dif}&user=${userId}`, {
|
||||
let link = `/payment?action=${action}&dif=${dif}&user=${userId}`
|
||||
if (currentCC) link = link + "&cc=true"
|
||||
navigate(link, {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
@ -53,7 +55,6 @@ export default function QuizPayment() {
|
||||
|
||||
|
||||
if (first) {
|
||||
console.log("чищу урл")
|
||||
navigate(`/quizpayment`, {
|
||||
replace: true,
|
||||
});
|
||||
@ -76,22 +77,9 @@ export default function QuizPayment() {
|
||||
}
|
||||
|
||||
|
||||
// setAuthToken(data.data.accessToken)
|
||||
console.log("собираюсь задать юзера и токен")
|
||||
setUserId(userId);
|
||||
setAuthToken(token);
|
||||
|
||||
// useUserFetcher({
|
||||
// url: process.env.REACT_APP_DOMAIN + `/user/${userId}`,
|
||||
// userId,
|
||||
// onNewUser: (user) => {
|
||||
// setUser(user)
|
||||
// navigate(`/payment?action=${action}&dif=${dif}`, { replace: true })
|
||||
|
||||
// },
|
||||
// onError: () => { },
|
||||
// })
|
||||
|
||||
return;
|
||||
})();
|
||||
} else {
|
||||
|
@ -42,8 +42,6 @@ function TariffConstructor() {
|
||||
}}
|
||||
>
|
||||
{Object.entries(customTariffs).filter(([serviceKey]) => serviceKey === "squiz").map(([serviceKey, privileges], index) => {
|
||||
console.log("privileges")
|
||||
console.log(privileges)
|
||||
return (
|
||||
<Box key={serviceKey}>
|
||||
<Box
|
||||
|
@ -53,8 +53,6 @@ export default function TariffPrivilegeSlider({ privilege }: Props) {
|
||||
);
|
||||
|
||||
function handleSliderChange(measurement: PrivilegeName) {
|
||||
console.log(measurement)
|
||||
console.log(sliderSettingsByType)
|
||||
return (value: number | number[]) => {
|
||||
|
||||
if (Number(value) < Number(sliderSettingsByType[measurement]?.min)) {
|
||||
|
316
src/pages/Tariffs/ModalRequestCreate.tsx
Normal file
316
src/pages/Tariffs/ModalRequestCreate.tsx
Normal file
@ -0,0 +1,316 @@
|
||||
import { Box, Button, IconButton, Modal, Typography, useMediaQuery, useTheme } from "@mui/material"
|
||||
|
||||
import { Form, Formik, useFormik } from "formik"
|
||||
import CustomTextField from "@components/CustomTextField"
|
||||
import InfoButton from "@components/InfoButton";
|
||||
import { sendContactFormRequest } from "@api/tariff"
|
||||
import { TimePicker } from "@mui/x-date-pickers"
|
||||
import moment, { Moment } from "moment"
|
||||
import { enqueueSnackbar } from "notistack"
|
||||
import { useState } from "react"
|
||||
import CloseIcon from "@root/assets/Icons/CloseIcon";
|
||||
|
||||
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));
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
|
||||
if (isSending) 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 ? "343px" : "418px",
|
||||
borderRadius: "10px",
|
||||
p: "50px"
|
||||
}}>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "24px",
|
||||
fontWeight: 500,
|
||||
lineHeight: "28.44px",
|
||||
textAlign: "center"
|
||||
}}
|
||||
>Спасибо за заявку!</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
lineHeight: "21.33px",
|
||||
color: "#4D4D4D",
|
||||
m: "5px 0 30px 0"
|
||||
|
||||
}}
|
||||
>С вами свяжутся в течение 24 часов</Typography>
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
onClick={onClose}
|
||||
sx={{
|
||||
py: "12px",
|
||||
"&:hover": {
|
||||
backgroundColor: "#581CA7",
|
||||
},
|
||||
"&:active": {
|
||||
color: "white",
|
||||
backgroundColor: "black",
|
||||
},
|
||||
}}
|
||||
>Ок</Button>
|
||||
|
||||
</Box>
|
||||
</Modal>
|
||||
)
|
||||
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: "#F2F3F7",
|
||||
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")
|
||||
})
|
||||
})
|
||||
//@ts-ignore
|
||||
if (resp[0]?.status === 200) {
|
||||
enqueueSnackbar("Запрос успешно отправлен")
|
||||
setIsSending(true)
|
||||
}
|
||||
if (resp[1]) {
|
||||
//@ts-ignore
|
||||
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
|
||||
onChange={(e) => setFieldValue("time", e)}
|
||||
ampm={false}
|
||||
value={values.time}
|
||||
views={['hours', 'minutes']} format="hh:mm"
|
||||
/>
|
||||
|
||||
</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>
|
||||
<InfoButton sx={{
|
||||
ml: "15px",
|
||||
width: "48px"
|
||||
}} />
|
||||
</Box>
|
||||
</Form>
|
||||
</>)}
|
||||
</Formik>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal >
|
||||
)
|
||||
}
|
@ -28,8 +28,10 @@ import TariffCard from "./TariffCard";
|
||||
import { useDiscounts } from "@root/api/price";
|
||||
import { Select } from "@components/Select";
|
||||
import { Tabs } from "@components/Tabs";
|
||||
import { ModalRequestCreate } from "./ModalRequestCreate";
|
||||
|
||||
const subPages = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"'];
|
||||
const subPagesTime = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"'];
|
||||
const subPagesVolume = ["Заявки quiz", 'Заказать создание quiz'];
|
||||
|
||||
const StepperText: Record<string, string> = {
|
||||
volume: "Тарифы на объём",
|
||||
@ -43,10 +45,13 @@ function TariffPage() {
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const location = useLocation();
|
||||
const tariffs = useTariffStore((state) => state.tariffs);
|
||||
const [selectedItem, setSelectedItem] = useState<number>(0);
|
||||
const [selectedItemTime, setSelectedItemTime] = useState<number>(0);
|
||||
const [selectedItemVolume, setSelectedItemVolume] = useState<number>(0);
|
||||
const [isRequestCreate, setIsRequestCreate] = useState(false);
|
||||
const purchasesAmount =
|
||||
useUserStore((state) => state.userAccount?.wallet.spent) ?? 0;
|
||||
const userId = useUserStore((state) => state.user?._id) ?? "";
|
||||
const userPrivilegies = useUserStore(store => store);
|
||||
const discounts = useDiscounts(userId);
|
||||
const isUserNko =
|
||||
useUserStore((state) => state.userAccount?.status) === "nko";
|
||||
@ -68,25 +73,14 @@ function TariffPage() {
|
||||
}
|
||||
|
||||
const filteredTariffs = tariffs.filter((tariff) => {
|
||||
if (tariff.privileges[0] === undefined) return false;
|
||||
if (
|
||||
(tariff.privileges[0].type === "day") === (unit === "time") &&
|
||||
!tariff.isDeleted &&
|
||||
!tariff.isCustom
|
||||
) {
|
||||
if (
|
||||
((selectedItem === 0 && unit === "time") || unit !== "time") &&
|
||||
tariff.privileges[0].serviceKey === "squiz" &&
|
||||
tariff.privileges[0].privilegeId !== "squizHideBadge"
|
||||
)
|
||||
return true;
|
||||
if (tariff.privileges[0] === undefined || tariff.isDeleted || tariff.isCustom) return false;
|
||||
if (unit === "time") {
|
||||
if (selectedItemTime === 0 && tariff.privileges[0].privilegeId === "quizUnlimTime") return true
|
||||
if (selectedItemTime === 1 && tariff.privileges[0].privilegeId === "squizHideBadge") return true
|
||||
}
|
||||
if (
|
||||
selectedItem === 1 &&
|
||||
unit === "time" &&
|
||||
tariff.privileges[0].privilegeId === "squizHideBadge"
|
||||
) {
|
||||
return true;
|
||||
if (unit === "volume") {
|
||||
if (selectedItemVolume === 0 && tariff.privileges[0].privilegeId === "quizCnt") return true
|
||||
if (selectedItemVolume === 1 && tariff.privileges[0].privilegeId === "quizManual") return true
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@ -206,15 +200,32 @@ function TariffPage() {
|
||||
<>
|
||||
{isMobile ? (
|
||||
<Select
|
||||
items={subPages}
|
||||
selectedItem={selectedItem}
|
||||
setSelectedItem={setSelectedItem}
|
||||
items={subPagesTime}
|
||||
selectedItem={selectedItemTime}
|
||||
setSelectedItem={setSelectedItemTime}
|
||||
/>
|
||||
) : (
|
||||
<Tabs
|
||||
items={subPages}
|
||||
selectedItem={selectedItem}
|
||||
setSelectedItem={setSelectedItem}
|
||||
items={subPagesTime}
|
||||
selectedItem={selectedItemTime}
|
||||
setSelectedItem={setSelectedItemTime}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{unit === "volume" && (
|
||||
<>
|
||||
{isMobile ? (
|
||||
<Select
|
||||
items={subPagesVolume}
|
||||
selectedItem={selectedItemVolume}
|
||||
setSelectedItem={setSelectedItemVolume}
|
||||
/>
|
||||
) : (
|
||||
<Tabs
|
||||
items={subPagesVolume}
|
||||
selectedItem={selectedItemVolume}
|
||||
setSelectedItem={setSelectedItemVolume}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
@ -247,6 +258,7 @@ function TariffPage() {
|
||||
{/* <Slider items={createTariffElements(recentlyPurchased)} />*/}
|
||||
{/* </>*/}
|
||||
{/*)}*/}
|
||||
<ModalRequestCreate open={isRequestCreate} onClose={() => setIsRequestCreate(false)}/>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ export const useAfterPay = () => {
|
||||
|
||||
//Проверяем можем ли мы оплатить корзину здесь и сейчас
|
||||
const [, payCartError] = await payCart();
|
||||
console.log("попытка оплаты не удалась")
|
||||
|
||||
if (payCartError) {
|
||||
//Не получилось купить корзину. Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты
|
||||
@ -54,7 +53,6 @@ export const useAfterPay = () => {
|
||||
|
||||
//Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.
|
||||
(async () => {
|
||||
console.log("Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.")
|
||||
const [, payCartError] = await payCart();
|
||||
|
||||
if (!payCartError) {
|
||||
|
@ -6,9 +6,5 @@ export default function PrivateRoute() {
|
||||
const location = useLocation()
|
||||
const user = useUserStore(state => state.user)
|
||||
|
||||
console.log("1 я рассуждаю кого выкинуть отсюда")
|
||||
console.log(user)
|
||||
console.log(location)
|
||||
console.log("2 я рассуждаю кого выкинуть отсюда")
|
||||
return user ? <Outlet /> : <Navigate to="/" replace />
|
||||
}
|
||||
|
82
yarn.lock
82
yarn.lock
@ -1138,6 +1138,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.25.0":
|
||||
version "7.25.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb"
|
||||
integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/template@^7.22.15", "@babel/template@^7.24.0", "@babel/template@^7.3.3":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50"
|
||||
@ -2203,6 +2210,15 @@
|
||||
"@mui/utils" "^5.15.14"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/private-theming@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.6.tgz#547671e7ae3f86b68d1289a0b90af04dfcc1c8c9"
|
||||
integrity sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/utils" "^5.16.6"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^5.15.14":
|
||||
version "5.15.14"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.14.tgz#168b154c4327fa4ccc1933a498331d53f61c0de2"
|
||||
@ -2213,6 +2229,16 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/styled-engine@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.6.tgz#60110c106dd482dfdb7e2aa94fd6490a0a3f8852"
|
||||
integrity sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@emotion/cache" "^11.11.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/system@^5.15.15":
|
||||
version "5.15.15"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.15.tgz#658771b200ce3c4a0f28e58169f02e5e718d1c53"
|
||||
@ -2227,11 +2253,30 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/system@^5.16.5":
|
||||
version "5.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.7.tgz#4583ca5bf3b38942e02c15a1e622ba869ac51393"
|
||||
integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/private-theming" "^5.16.6"
|
||||
"@mui/styled-engine" "^5.16.6"
|
||||
"@mui/types" "^7.2.15"
|
||||
"@mui/utils" "^5.16.6"
|
||||
clsx "^2.1.0"
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/types@^7.2.14":
|
||||
version "7.2.14"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.14.tgz#8a02ac129b70f3d82f2f9b76ded2c8d48e3fc8c9"
|
||||
integrity sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==
|
||||
|
||||
"@mui/types@^7.2.15":
|
||||
version "7.2.15"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.15.tgz#dadd232fe9a70be0d526630675dff3b110f30b53"
|
||||
integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==
|
||||
|
||||
"@mui/utils@^5.15.14":
|
||||
version "5.15.14"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.15.14.tgz#e414d7efd5db00bfdc875273a40c0a89112ade3a"
|
||||
@ -2242,6 +2287,31 @@
|
||||
prop-types "^15.8.1"
|
||||
react-is "^18.2.0"
|
||||
|
||||
"@mui/utils@^5.16.5", "@mui/utils@^5.16.6":
|
||||
version "5.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.6.tgz#905875bbc58d3dcc24531c3314a6807aba22a711"
|
||||
integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.9"
|
||||
"@mui/types" "^7.2.15"
|
||||
"@types/prop-types" "^15.7.12"
|
||||
clsx "^2.1.1"
|
||||
prop-types "^15.8.1"
|
||||
react-is "^18.3.1"
|
||||
|
||||
"@mui/x-date-pickers@^7.13.0":
|
||||
version "7.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-7.13.0.tgz#1afe20dc7ee30c9c1f91c232f3c61f94d2b8427b"
|
||||
integrity sha512-cmpAfkzOjUgL4I8WenU4elm1QJO8vWpGmIPCezT3Q9wFjGL1QApQhJ5gMZ+X4tM6Gha9AhIWNQX5eXHKbSoyFQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.25.0"
|
||||
"@mui/system" "^5.16.5"
|
||||
"@mui/utils" "^5.16.5"
|
||||
"@types/react-transition-group" "^4.4.10"
|
||||
clsx "^2.1.1"
|
||||
prop-types "^15.8.1"
|
||||
react-transition-group "^4.4.5"
|
||||
|
||||
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
||||
version "5.1.1-v1"
|
||||
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
|
||||
@ -2873,7 +2943,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f"
|
||||
integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
|
||||
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.11":
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.11", "@types/prop-types@^15.7.12":
|
||||
version "15.7.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
|
||||
integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==
|
||||
@ -4449,6 +4519,11 @@ clsx@^2.0.0, clsx@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
|
||||
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
|
||||
|
||||
clsx@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
|
||||
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
@ -10334,6 +10409,11 @@ react-is@^18.0.0, react-is@^18.2.0:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react-is@^18.3.1:
|
||||
version "18.3.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
|
||||
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
|
||||
|
||||
react-pdf@^7.1.2:
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-7.7.1.tgz#8f5c4716a8ca65a0889825ef01e3a37956291334"
|
||||
|
Loading…
Reference in New Issue
Block a user