wrap components with error boundaries, minox fixes
This commit is contained in:
parent
ebecee8a49
commit
4490536276
@ -30,8 +30,11 @@ import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
|
|||||||
import { payCart } from "@root/api/cart";
|
import { payCart } from "@root/api/cart";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
||||||
|
|
||||||
export default function Drawers() {
|
function Drawers() {
|
||||||
const [openNotificationsModal, setOpenNotificationsModal] =
|
const [openNotificationsModal, setOpenNotificationsModal] =
|
||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
@ -324,3 +327,15 @@ export default function Drawers() {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(Drawers, {
|
||||||
|
fallback: (
|
||||||
|
<Box sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
}}>
|
||||||
|
<ErrorOutlineIcon color="error" />
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -13,8 +13,10 @@ import { getMessageFromFetchError } from "@frontend/kitui";
|
|||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
import { VerificationStatus } from "@root/model/account";
|
import { VerificationStatus } from "@root/model/account";
|
||||||
import { verify } from "./helper";
|
import { verify } from "./helper";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
export default function AccountSettings() {
|
function AccountSettings() {
|
||||||
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"));
|
||||||
@ -37,12 +39,6 @@ export default function AccountSettings() {
|
|||||||
bold: true,
|
bold: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const verificationStatusData: Record<VerificationStatus, { text: string; color: string }> = {
|
|
||||||
verificated: { text: "Верификация пройдена", color: "#0D9F00" },
|
|
||||||
waiting: { text: "В ожидании верификации", color: "#F18956" },
|
|
||||||
notVerificated: { text: "Не верифицирован", color: "#E02C2C" },
|
|
||||||
};
|
|
||||||
|
|
||||||
function handleSendDataClick() {
|
function handleSendDataClick() {
|
||||||
sendUserData()
|
sendUserData()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -54,32 +50,6 @@ export default function AccountSettings() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function VerificationIndicator({
|
|
||||||
verificationStatus,
|
|
||||||
sx,
|
|
||||||
}: {
|
|
||||||
verificationStatus: VerificationStatus;
|
|
||||||
sx?: SxProps<Theme>;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
py: "14px",
|
|
||||||
px: "8.5px",
|
|
||||||
borderWidth: "1px",
|
|
||||||
borderStyle: "solid",
|
|
||||||
color: verificationStatusData[verificationStatus].color,
|
|
||||||
borderColor: verificationStatusData[verificationStatus].color,
|
|
||||||
borderRadius: "8px",
|
|
||||||
textAlign: "center",
|
|
||||||
...sx,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography lineHeight="100%">{verificationStatusData[verificationStatus].text}</Typography>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionWrapper
|
<SectionWrapper
|
||||||
maxWidth="lg"
|
maxWidth="lg"
|
||||||
@ -266,3 +236,40 @@ export default function AccountSettings() {
|
|||||||
</SectionWrapper>
|
</SectionWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(AccountSettings, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка при отображении настроек аккаунта</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
|
||||||
|
const verificationStatusData: Record<VerificationStatus, { text: string; color: string; }> = {
|
||||||
|
verificated: { text: "Верификация пройдена", color: "#0D9F00" },
|
||||||
|
waiting: { text: "В ожидании верификации", color: "#F18956" },
|
||||||
|
notVerificated: { text: "Не верифицирован", color: "#E02C2C" },
|
||||||
|
};
|
||||||
|
|
||||||
|
function VerificationIndicator({
|
||||||
|
verificationStatus,
|
||||||
|
sx,
|
||||||
|
}: {
|
||||||
|
verificationStatus: VerificationStatus;
|
||||||
|
sx?: SxProps<Theme>;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
py: "14px",
|
||||||
|
px: "8.5px",
|
||||||
|
borderWidth: "1px",
|
||||||
|
borderStyle: "solid",
|
||||||
|
color: verificationStatusData[verificationStatus].color,
|
||||||
|
borderColor: verificationStatusData[verificationStatus].color,
|
||||||
|
borderRadius: "8px",
|
||||||
|
textAlign: "center",
|
||||||
|
...sx,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography lineHeight="100%">{verificationStatusData[verificationStatus].text}</Typography>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -6,8 +6,10 @@ import CustomWrapper from "./CustomWrapper";
|
|||||||
import { useCart } from "@root/utils/hooks/useCart";
|
import { useCart } from "@root/utils/hooks/useCart";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
|
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
|
||||||
export default function Cart() {
|
function Cart() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(550));
|
const isMobile = useMediaQuery(theme.breakpoints.down(550));
|
||||||
@ -71,3 +73,8 @@ export default function Cart() {
|
|||||||
</SectionWrapper>
|
</SectionWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(Cart, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка при отображении корзины</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -5,8 +5,10 @@ import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker";
|
|||||||
import SaveWrapper from "./SaveWrapper";
|
import SaveWrapper from "./SaveWrapper";
|
||||||
import { useTariffStore } from "@root/stores/tariffs";
|
import { useTariffStore } from "@root/stores/tariffs";
|
||||||
import { type Tariff } from "@frontend/kitui";
|
import { type Tariff } from "@frontend/kitui";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
export default function SavedTariffs() {
|
function SavedTariffs() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(550));
|
const isMobile = useMediaQuery(theme.breakpoints.down(550));
|
||||||
@ -65,3 +67,8 @@ export default function SavedTariffs() {
|
|||||||
</SectionWrapper>
|
</SectionWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(SavedTariffs, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка при отображении сохраненных тарифов</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -35,8 +35,10 @@ import {
|
|||||||
useTicketMessages,
|
useTicketMessages,
|
||||||
} from "@frontend/kitui";
|
} from "@frontend/kitui";
|
||||||
import { shownMessage, sendTicketMessage } from "@root/api/ticket";
|
import { shownMessage, sendTicketMessage } from "@root/api/ticket";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
export default function SupportChat() {
|
function SupportChat() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.up(460));
|
const isMobile = useMediaQuery(theme.breakpoints.up(460));
|
||||||
@ -128,7 +130,7 @@ export default function SupportChat() {
|
|||||||
async function handleSendMessage() {
|
async function handleSendMessage() {
|
||||||
if (!ticket || !messageField) return;
|
if (!ticket || !messageField) return;
|
||||||
|
|
||||||
const [_, sendTicketMessageError] = await sendTicketMessage(
|
const [, sendTicketMessageError] = await sendTicketMessage(
|
||||||
ticket.id,
|
ticket.id,
|
||||||
messageField
|
messageField
|
||||||
);
|
);
|
||||||
@ -318,3 +320,8 @@ export default function SupportChat() {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(SupportChat, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Не удалось отобразить чат</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -5,13 +5,16 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
useTheme,
|
useTheme,
|
||||||
Pagination,
|
Pagination,
|
||||||
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import TicketCard from "./TicketCard";
|
import TicketCard from "./TicketCard";
|
||||||
import { setTicketApiPage, useTicketStore } from "@root/stores/tickets";
|
import { setTicketApiPage, useTicketStore } from "@root/stores/tickets";
|
||||||
import { Ticket } from "@frontend/kitui";
|
import { Ticket } from "@frontend/kitui";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
|
|
||||||
export default function TicketList() {
|
function TicketList() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const tickets = useTicketStore((state) => state.tickets);
|
const tickets = useTicketStore((state) => state.tickets);
|
||||||
const ticketCount = useTicketStore((state) => state.ticketCount);
|
const ticketCount = useTicketStore((state) => state.ticketCount);
|
||||||
@ -87,3 +90,8 @@ function sortTicketsByUpdateTime(ticket1: Ticket, ticket2: Ticket) {
|
|||||||
const date2 = new Date(ticket2.updated_at).getTime();
|
const date2 = new Date(ticket2.updated_at).getTime();
|
||||||
return date2 - date1;
|
return date2 - date1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(TicketList, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка загрузки тикетов</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, IconButton, useMediaQuery, useTheme } from "@mui/material";
|
import { Box, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import SectionWrapper from "@components/SectionWrapper";
|
import SectionWrapper from "@components/SectionWrapper";
|
||||||
import { useCustomTariffsStore } from "@root/stores/customTariffs";
|
import { useCustomTariffsStore } from "@root/stores/customTariffs";
|
||||||
@ -8,8 +8,10 @@ import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
|||||||
import TotalPrice from "@root/components/TotalPrice";
|
import TotalPrice from "@root/components/TotalPrice";
|
||||||
import { serviceNameByKey } from "@root/utils/serviceKeys";
|
import { serviceNameByKey } from "@root/utils/serviceKeys";
|
||||||
import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker";
|
import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
export default function TariffConstructor() {
|
function TariffConstructor() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
@ -84,3 +86,8 @@ export default function TariffConstructor() {
|
|||||||
</SectionWrapper>
|
</SectionWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(TariffConstructor, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка при отображении кастомных тарифов</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -18,6 +18,8 @@ import { Slider } from "./slider";
|
|||||||
import { useCartStore } from "@root/stores/cart";
|
import { useCartStore } from "@root/stores/cart";
|
||||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||||
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
|
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
|
||||||
|
import { withErrorBoundary } from "react-error-boundary";
|
||||||
|
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||||
|
|
||||||
const subPages = ["Шаблонизатор", "Опросник", "Сокращатель ссылок"];
|
const subPages = ["Шаблонизатор", "Опросник", "Сокращатель ссылок"];
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ const StepperText: Record<string, string> = {
|
|||||||
time: "Тарифы на время",
|
time: "Тарифы на время",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TariffPage() {
|
function TariffPage() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||||||
@ -178,3 +180,8 @@ export default function TariffPage() {
|
|||||||
</SectionWrapper>
|
</SectionWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default withErrorBoundary(TariffPage, {
|
||||||
|
fallback: <Typography mt="8px" textAlign="center">Ошибка загрузки тарифов</Typography>,
|
||||||
|
onError: handleComponentError,
|
||||||
|
})
|
||||||
|
@ -39,6 +39,6 @@ async function sendErrorsToServer() {
|
|||||||
// body: errorsQueue,
|
// body: errorsQueue,
|
||||||
// useToken: true,
|
// useToken: true,
|
||||||
// });
|
// });
|
||||||
console.log(`Sending ${errorsQueue.length} errors to server`, errorsQueue);
|
console.log(`Fake-sending ${errorsQueue.length} errors to server`, errorsQueue);
|
||||||
errorsQueue = [];
|
errorsQueue = [];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user