feat: Page 404

This commit is contained in:
IlyaDoronin 2024-03-20 10:56:36 +03:00
parent 3ffa3418c0
commit cc8f3bea26
3 changed files with 407 additions and 134 deletions

149
src/assets/Icons/404.tsx Normal file

@ -0,0 +1,149 @@
import { Box } from "@mui/material";
interface NotFoundIconProps {
size?: number;
}
export const NotFoundIcon = ({ size = 390 }: NotFoundIconProps) => {
return (
<Box
sx={{ display: "flex", alignItems: "center", justifyContent: "center" }}
>
<svg
width={size}
viewBox="0 0 389 237"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M79 187C77.6667 187 76.5333 186.533 75.6 185.6C74.6667 184.667 74.2 183.533 74.2 182.2V156.6H10.8C9.33333 156.6 8.13333 156.133 7.2 155.2C6.4 154.267 6 153.133 6 151.8V138.2C6 137.4 6.13333 136.467 6.4 135.4C6.8 134.2 7.4 133.133 8.2 132.2L67.2 50.4C68.9333 48.1333 71.4 47 74.6 47H96.4C97.7333 47 98.8667 47.4667 99.8 48.4C100.733 49.3333 101.2 50.4667 101.2 51.8V133H119C120.6 133 121.8 133.467 122.6 134.4C123.533 135.2 124 136.333 124 137.8V151.8C124 153.133 123.533 154.267 122.6 155.2C121.667 156.133 120.533 156.6 119.2 156.6H101.2V182.2C101.2 183.533 100.733 184.667 99.8 185.6C98.8667 186.533 97.7333 187 96.4 187H79ZM33.8 133.8H74.8V76L33.8 133.8Z"
fill="#4D4D4D"
/>
<path
d="M336.846 187C335.512 187 334.379 186.533 333.446 185.6C332.512 184.667 332.046 183.533 332.046 182.2V156.6H268.646C267.179 156.6 265.979 156.133 265.046 155.2C264.246 154.267 263.846 153.133 263.846 151.8V138.2C263.846 137.4 263.979 136.467 264.246 135.4C264.646 134.2 265.246 133.133 266.046 132.2L325.046 50.4C326.779 48.1333 329.246 47 332.446 47H354.246C355.579 47 356.712 47.4667 357.646 48.4C358.579 49.3333 359.046 50.4667 359.046 51.8V133H376.846C378.446 133 379.646 133.467 380.446 134.4C381.379 135.2 381.846 136.333 381.846 137.8V151.8C381.846 153.133 381.379 154.267 380.446 155.2C379.512 156.133 378.379 156.6 377.046 156.6H359.046V182.2C359.046 183.533 358.579 184.667 357.646 185.6C356.712 186.533 355.579 187 354.246 187H336.846ZM291.646 133.8H332.646V76L291.646 133.8Z"
fill="#4D4D4D"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M191.177 189.358C181.743 189.358 173.705 187.963 167.062 185.173C160.419 182.383 154.972 178.53 150.72 173.614C146.468 168.698 143.28 163.052 141.154 156.674C139.028 150.164 137.766 143.255 137.367 135.948C137.234 132.361 137.102 128.441 136.969 124.19V111.036C137.102 106.652 137.234 102.599 137.367 98.8793C137.633 91.5719 138.895 84.7295 141.154 78.3521C147.93 58.8214 170.849 24.9415 186.792 25.938C200.668 26.8053 207.972 36.1671 214.514 44.5531C217.838 48.8133 220.965 52.8217 224.658 55.3365C230.111 59.4227 237.999 61.7595 245.705 64.0423C257.715 67.5998 269.281 71.0261 270.495 80.7377C271.514 88.884 265.142 95.5245 258.561 102.383C252.262 108.948 245.771 115.713 245.384 124.19C245.384 128.441 245.251 132.361 244.986 135.948C244.72 143.255 243.524 150.164 241.398 156.674C239.273 163.052 236.084 168.698 231.832 173.614C227.581 178.53 222.067 182.383 215.291 185.173C208.648 187.963 200.61 189.358 191.177 189.358ZM210.105 158.078C206.119 163.658 199.808 166.448 191.172 166.448C182.802 166.448 176.557 163.658 172.438 158.078C168.32 152.365 166.127 144.659 165.862 134.96C165.862 131.107 165.795 127.254 165.662 123.401V111.443C165.795 107.457 165.862 103.671 165.862 100.083C166.127 90.65 168.253 83.0769 172.239 77.3638C176.358 71.5179 182.669 68.5949 191.172 68.5949C199.808 68.5949 206.119 71.5179 210.105 77.3638C214.223 83.0769 216.349 90.65 216.482 100.083C216.748 103.671 216.881 107.457 216.881 111.443V123.401C216.881 127.254 216.748 131.107 216.482 134.96C216.349 144.659 214.223 152.365 210.105 158.078Z"
fill="#A35FFA"
/>
<g filter="url(#filter0_d_4600_1203)">
<path
d="M191.647 189.286C182.219 189.286 174.186 187.892 167.547 185.104C160.907 182.315 155.463 178.464 151.214 173.551C146.965 168.638 143.778 162.995 141.653 156.621C139.529 150.115 138.267 143.21 137.869 135.907C137.736 132.321 137.603 128.404 137.471 124.155C137.471 119.773 137.471 115.391 137.471 111.009C137.603 106.627 137.736 102.577 137.869 98.8594C138.135 91.5562 139.396 84.7178 141.653 78.344C143.911 71.8375 147.164 66.1941 151.413 61.4139C155.795 56.6336 161.306 52.8492 167.945 50.0607C174.584 47.2722 182.485 45.8779 191.647 45.8779C200.942 45.8779 208.909 47.2722 215.549 50.0607C222.188 52.8492 227.632 56.6336 231.881 61.4139C236.263 66.1941 239.517 71.8375 241.641 78.344C243.898 84.7178 245.16 91.5562 245.425 98.8594C245.691 102.577 245.824 106.627 245.824 111.009C245.824 115.391 245.824 119.773 245.824 124.155C245.824 128.404 245.691 132.321 245.425 135.907C245.16 143.21 243.965 150.115 241.84 156.621C239.716 162.995 236.529 168.638 232.28 173.551C228.031 178.464 222.52 182.315 215.748 185.104C209.109 187.892 201.075 189.286 191.647 189.286ZM191.647 166.381C200.278 166.381 206.586 163.592 210.569 158.015C214.686 152.306 216.81 144.604 216.943 134.911C217.209 131.06 217.341 127.209 217.341 123.358C217.341 119.375 217.341 115.391 217.341 111.408C217.341 107.424 217.209 103.64 216.943 100.055C216.81 90.6267 214.686 83.0579 210.569 77.3481C206.586 71.5056 200.278 68.5843 191.647 68.5843C183.149 68.5843 176.842 71.5056 172.725 77.3481C168.742 83.0579 166.617 90.6267 166.352 100.055C166.352 103.64 166.285 107.424 166.152 111.408C166.152 115.391 166.152 119.375 166.152 123.358C166.285 127.209 166.352 131.06 166.352 134.911C166.617 144.604 168.808 152.306 172.924 158.015C177.041 163.592 183.282 166.381 191.647 166.381Z"
fill="#7E2AEA"
/>
</g>
<ellipse
cx="258.266"
cy="142.409"
rx="9.78603"
ry="9.78603"
transform="rotate(-13.417 258.266 142.409)"
fill="#A35FFA"
/>
<g filter="url(#filter1_d_4600_1203)">
<circle
cx="163.171"
cy="105.276"
r="18.2801"
transform="rotate(-13.417 163.171 105.276)"
fill="#A35FFA"
/>
</g>
<circle
cx="223.552"
cy="39.043"
r="3.72801"
transform="rotate(-13.417 223.552 39.043)"
fill="#7E2AEA"
/>
<defs>
<filter
id="filter0_d_4600_1203"
x="131.525"
y="33.9867"
width="126.19"
height="161.246"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feMorphology
radius="1.48641"
operator="dilate"
in="SourceAlpha"
result="effect1_dropShadow_4600_1203"
/>
<feOffset dx="2.97281" dy="-2.97281" />
<feGaussianBlur stdDeviation="3.71602" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_4600_1203"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_4600_1203"
result="shape"
/>
</filter>
<filter
id="filter1_d_4600_1203"
x="137.455"
y="75.0737"
width="54.4052"
height="54.4052"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha"
/>
<feMorphology
radius="1.48641"
operator="dilate"
in="SourceAlpha"
result="effect1_dropShadow_4600_1203"
/>
<feOffset dx="1.48641" dy="-3" />
<feGaussianBlur stdDeviation="3.71602" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix
type="matrix"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
/>
<feBlend
mode="normal"
in2="BackgroundImageFix"
result="effect1_dropShadow_4600_1203"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_dropShadow_4600_1203"
result="shape"
/>
</filter>
</defs>
</svg>
</Box>
);
};

@ -1,149 +1,217 @@
import React from "react"
import ReactDOM from "react-dom/client"
import { BrowserRouter, Navigate, Route, Routes, useLocation, useNavigate } from "react-router-dom"
import { CssBaseline, ThemeProvider } from "@mui/material"
import Faq from "./pages/Faq/Faq"
import Wallet from "./pages/Wallet"
import Payment from "./pages/Payment/Payment"
import QuizPayment from "./pages/QuizPayment/QuizPayment"
import Support from "./pages/Support/Support"
import ChatImageNewWindow from "./pages/Support/ChatImageNewWindow"
import AccountSettings from "./pages/AccountSettings/AccountSettings"
import Landing from "./pages/Landing/Landing"
import Tariffs from "./pages/Tariffs/Tariffs"
import SigninDialog from "./pages/auth/Signin"
import SignupDialog from "./pages/auth/Signup"
import RecoverDialog from "./pages/auth/Recover"
import History from "./pages/History"
import Cart from "./pages/Cart/Cart"
import TariffPage from "./pages/Tariffs/TariffsPage"
import SavedTariffs from "./pages/SavedTariffs"
import PrivateRoute from "@root/utils/routes/ProtectedRoute"
import reportWebVitals from "./reportWebVitals"
import { SnackbarProvider, enqueueSnackbar } from "notistack"
import "./index.css"
import ProtectedLayout from "./components/ProtectedLayout"
import { clearUserData, setUser, setUserAccount, useUserStore } from "./stores/user"
import TariffConstructor from "./pages/TariffConstructor/TariffConstructor"
import { clearAuthToken, getMessageFromFetchError, useUserAccountFetcher, useUserFetcher } from "@frontend/kitui"
import { pdfjs } from "react-pdf"
import { theme } from "./utils/theme"
import PPofData from "@root/docs/PPofData"
import Docs from "@root/docs/docs"
import Oferta from "@root/docs/content/oferta"
import PrivacyPolicy from "@root/docs/content/PrivacyPolicy"
import RecoverPassword from "@root/pages/auth/RecoverPassword"
import OutdatedLink from "@root/pages/auth/OutdatedLink"
import { verify } from "./pages/AccountSettings/helper"
import AfterPay from "./pages/AfterPay"
import React from "react";
import ReactDOM from "react-dom/client";
import {
BrowserRouter,
Navigate,
Route,
Routes,
useLocation,
useNavigate,
} from "react-router-dom";
import { CssBaseline, ThemeProvider } from "@mui/material";
import Faq from "./pages/Faq/Faq";
import Wallet from "./pages/Wallet";
import Payment from "./pages/Payment/Payment";
import QuizPayment from "./pages/QuizPayment/QuizPayment";
import Support from "./pages/Support/Support";
import ChatImageNewWindow from "./pages/Support/ChatImageNewWindow";
import AccountSettings from "./pages/AccountSettings/AccountSettings";
import Landing from "./pages/Landing/Landing";
import Tariffs from "./pages/Tariffs/Tariffs";
import SigninDialog from "./pages/auth/Signin";
import SignupDialog from "./pages/auth/Signup";
import RecoverDialog from "./pages/auth/Recover";
import History from "./pages/History";
import Cart from "./pages/Cart/Cart";
import TariffPage from "./pages/Tariffs/TariffsPage";
import SavedTariffs from "./pages/SavedTariffs";
import PrivateRoute from "@root/utils/routes/ProtectedRoute";
import reportWebVitals from "./reportWebVitals";
import { SnackbarProvider, enqueueSnackbar } from "notistack";
import "./index.css";
import ProtectedLayout from "./components/ProtectedLayout";
import {
clearUserData,
setUser,
setUserAccount,
useUserStore,
} from "./stores/user";
import TariffConstructor from "./pages/TariffConstructor/TariffConstructor";
import {
clearAuthToken,
getMessageFromFetchError,
useUserAccountFetcher,
useUserFetcher,
} from "@frontend/kitui";
import { pdfjs } from "react-pdf";
import { theme } from "./utils/theme";
import PPofData from "@root/docs/PPofData";
import Docs from "@root/docs/docs";
import Oferta from "@root/docs/content/oferta";
import PrivacyPolicy from "@root/docs/content/PrivacyPolicy";
import RecoverPassword from "@root/pages/auth/RecoverPassword";
import OutdatedLink from "@root/pages/auth/OutdatedLink";
import { verify } from "./pages/AccountSettings/helper";
import AfterPay from "./pages/AfterPay";
import { PageNotFound } from "./pages/PageNotFound";
pdfjs.GlobalWorkerOptions.workerSrc = new URL("pdfjs-dist/build/pdf.worker.min.js", import.meta.url).toString()
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
"pdfjs-dist/build/pdf.worker.min.js",
import.meta.url
).toString();
const App = () => {
console.log("render app")
const location = useLocation()
const userId = useUserStore((state) => state.userId)
const navigate = useNavigate()
console.log("render app");
const location = useLocation();
const userId = useUserStore((state) => state.userId);
const navigate = useNavigate();
console.log(userId)
useUserFetcher({
url: process.env.REACT_APP_DOMAIN + `/user/${userId}`,
userId,
onNewUser: setUser,
onError: (error) => {
const errorMessage = getMessageFromFetchError(error)
if (errorMessage) {
enqueueSnackbar(errorMessage)
clearUserData()
clearAuthToken()
}
},
})
console.log(userId);
useUserFetcher({
url: process.env.REACT_APP_DOMAIN + `/user/${userId}`,
userId,
onNewUser: setUser,
onError: (error) => {
const errorMessage = getMessageFromFetchError(error);
if (errorMessage) {
enqueueSnackbar(errorMessage);
clearUserData();
clearAuthToken();
}
},
});
useUserAccountFetcher({
url: process.env.REACT_APP_DOMAIN + "/customer/account",
userId,
onNewUserAccount: setUserAccount,
onError: (error) => {
const errorMessage = getMessageFromFetchError(error)
if (errorMessage) {
enqueueSnackbar(errorMessage)
clearUserData()
clearAuthToken()
navigate("/signin")
}
},
})
useUserAccountFetcher({
url: process.env.REACT_APP_DOMAIN + "/customer/account",
userId,
onNewUserAccount: setUserAccount,
onError: (error) => {
const errorMessage = getMessageFromFetchError(error);
if (errorMessage) {
enqueueSnackbar(errorMessage);
clearUserData();
clearAuthToken();
navigate("/signin");
}
},
});
verify(userId)
verify(userId);
console.log(location)
if (location.state?.redirectTo)
return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} />
console.log(location);
if (location.state?.redirectTo)
return (
<Navigate
to={location.state.redirectTo}
replace
state={{ backgroundLocation: location }}
/>
);
return (
<>
{location.state?.backgroundLocation && (
<Routes>
<Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} />
<Route path="/recover" element={<RecoverDialog />} />
<Route path="/changepwd" element={<RecoverPassword />} />
<Route path="/changepwd/expired" element={<OutdatedLink />} />
</Routes>
)}
<Routes location={location.state?.backgroundLocation || location}>
<Route path="/" element={<Landing />} />
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />
<Route path="/recover" element={<Navigate to="/" replace state={{ redirectTo: "/recover" }} />} />
<Route path="/changepwd" element={<Navigate to="/" replace state={{ redirectTo: window.location.pathname + window.location.search }} />} />
<Route path="/changepwd/expired" element={<Navigate to="/" replace state={{ redirectTo: "/changepwd/expired" }} />} />
return (
<>
{location.state?.backgroundLocation && (
<Routes>
<Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} />
<Route path="/recover" element={<RecoverDialog />} />
<Route path="/changepwd" element={<RecoverPassword />} />
<Route path="/changepwd/expired" element={<OutdatedLink />} />
</Routes>
)}
<Routes location={location.state?.backgroundLocation || location}>
<Route path="/" element={<Landing />} />
<Route
path="/signin"
element={
<Navigate to="/" replace state={{ redirectTo: "/signin" }} />
}
/>
<Route
path="/signup"
element={
<Navigate to="/" replace state={{ redirectTo: "/signup" }} />
}
/>
<Route
path="/recover"
element={
<Navigate to="/" replace state={{ redirectTo: "/recover" }} />
}
/>
<Route
path="/changepwd"
element={
<Navigate
to="/"
replace
state={{
redirectTo: window.location.pathname + window.location.search,
}}
/>
}
/>
<Route
path="/changepwd/expired"
element={
<Navigate
to="/"
replace
state={{ redirectTo: "/changepwd/expired" }}
/>
}
/>
<Route path={"/image/:srcImage"} element={<ChatImageNewWindow />} />
<Route element={<PrivateRoute />}>
<Route element={<ProtectedLayout />}>
<Route path="/tariffs" element={<Tariffs />} />
<Route path="/tariffs/time" element={<TariffPage />} />
<Route path="/tariffs/volume" element={<TariffPage />} />
<Route path="/faq" element={<Faq />} />
<Route path="/support" element={<Support />} />
<Route path="/support/:ticketId" element={<Support />} />
<Route path="/tariffconstructor" element={<TariffConstructor />} />
<Route path="/cart" element={<Cart />} />
<Route path="/wallet" element={<Wallet />} />
<Route path="/payment" element={<Payment />} />
<Route path="/settings" element={<AccountSettings />} />
<Route path="/history" element={<History />} />
<Route path="/tariffconstructor/savedtariffs" element={<SavedTariffs />} />
</Route>
</Route>
<Route path="/ppdd" element={<PPofData />} />
<Route path="/quizpayment" element={<QuizPayment />} />
<Route element={<Docs />}>
<Route path={"/docs/oferta"} element={<Oferta />} />
<Route path={"/docs/privacy"} element={<PrivacyPolicy />} />
</Route>
<Route path="/afterpay" element={<AfterPay />} />
</Routes>
</>
)
}
<Route path={"/image/:srcImage"} element={<ChatImageNewWindow />} />
<Route element={<PrivateRoute />}>
<Route element={<ProtectedLayout />}>
<Route path="/tariffs" element={<Tariffs />} />
<Route path="/tariffs/time" element={<TariffPage />} />
<Route path="/tariffs/volume" element={<TariffPage />} />
<Route path="/faq" element={<Faq />} />
<Route path="/support" element={<Support />} />
<Route path="/support/:ticketId" element={<Support />} />
<Route path="/tariffconstructor" element={<TariffConstructor />} />
<Route path="/cart" element={<Cart />} />
<Route path="/wallet" element={<Wallet />} />
<Route path="/payment" element={<Payment />} />
<Route path="/settings" element={<AccountSettings />} />
<Route path="/history" element={<History />} />
<Route
path="/tariffconstructor/savedtariffs"
element={<SavedTariffs />}
/>
</Route>
</Route>
<Route path="/ppdd" element={<PPofData />} />
<Route path="/quizpayment" element={<QuizPayment />} />
<Route element={<Docs />}>
<Route path={"/docs/oferta"} element={<Oferta />} />
<Route path={"/docs/privacy"} element={<PrivacyPolicy />} />
</Route>
<Route path="/afterpay" element={<AfterPay />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</>
);
};
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement)
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
// <React.StrictMode>
<ThemeProvider theme={theme}>
<BrowserRouter>
<CssBaseline />
<SnackbarProvider />
<App />
</BrowserRouter>
</ThemeProvider>
// </React.StrictMode>
)
// <React.StrictMode>
<ThemeProvider theme={theme}>
<BrowserRouter>
<CssBaseline />
<SnackbarProvider />
<App />
</BrowserRouter>
</ThemeProvider>
// </React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals()
reportWebVitals();

@ -0,0 +1,56 @@
import {
Box,
Typography,
Button,
useTheme,
useMediaQuery,
} from "@mui/material";
import { Link } from "react-router-dom";
import { NotFoundIcon } from "@root/assets/Icons/404";
export const PageNotFound = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(800));
return (
<Box
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
minHeight: "70vh",
margin: "0 10px",
}}
>
<NotFoundIcon size={isMobile ? 275 : 390} />
<Typography
sx={{
color: "#4D4D4D",
fontSize: "18px",
textAlign: "center",
lineHeight: "1em",
fontWeight: "400",
}}
>
Страница не найдена
</Typography>
<Typography
sx={{
color: "#4D4D4D",
fontSize: "18px",
textAlign: "center",
lineHeight: "1em",
fontWeight: "400",
marginBottom: "30px",
}}
>
Посетите главную страницу, возможно вы найдете ее
</Typography>
<Link to="/" style={{ textDecoration: "none" }}>
<Button variant="pena-contained-dark">На главную</Button>
</Link>
</Box>
);
};