diff --git a/package.json b/package.json index 2c15fc8..eb1f8f2 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dependencies": { "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@frontend/kitui": "1.0.44", + "@frontend/kitui": "1.0.45", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", "@popperjs/core": "^2.11.8", diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx deleted file mode 100644 index f976f33..0000000 --- a/src/components/Layout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { Outlet } from "react-router-dom"; -import Navbar from "./Navbar/Navbar"; - -export default function Layout() { - return ( - - - - ); -} diff --git a/src/components/ProtectedLayout.tsx b/src/components/ProtectedLayout.tsx new file mode 100644 index 0000000..db10241 --- /dev/null +++ b/src/components/ProtectedLayout.tsx @@ -0,0 +1,83 @@ +import { Outlet } from "react-router-dom"; +import Navbar from "./Navbar/Navbar"; +import { Ticket, getMessageFromFetchError, useAllTariffsFetcher, usePrivilegeFetcher, useSSESubscription, useTicketsFetcher, useToken } from "@frontend/kitui"; +import { updateTickets, setTicketCount, useTicketStore, setTicketsFetchState } from "@root/stores/tickets"; +import { enqueueSnackbar } from "notistack"; +import { updateTariffs } from "@root/stores/tariffs"; +import { useCustomTariffs } from "@root/utils/hooks/useCustomTariffs"; +import { setCustomTariffs } from "@root/stores/customTariffs"; +import { useDiscounts } from "@root/utils/hooks/useDiscounts"; +import { setDiscounts } from "@root/stores/discounts"; +import { setPrivileges } from "@root/stores/privileges"; + + +export default function ProtectedLayout() { + const token = useToken(); + const ticketApiPage = useTicketStore((state) => state.apiPage); + const ticketsPerPage = useTicketStore((state) => state.ticketsPerPage); + + useSSESubscription({ + url: `https://admin.pena.digital/heruvym/subscribe?Authorization=${token}`, + onNewData: data => { + updateTickets(data.filter(d => Boolean(d.id))); + setTicketCount(data.length); + }, + marker: "ticket", + }); + + useTicketsFetcher({ + url: "https://hub.pena.digital/heruvym/getTickets", + ticketsPerPage, + ticketApiPage, + onSuccess: (result) => { + if (result.data) updateTickets(result.data); + setTicketCount(result.count); + }, + onError: (error: Error) => { + const message = getMessageFromFetchError(error); + if (message) enqueueSnackbar(message); + }, + onFetchStateChange: setTicketsFetchState, + }); + + useAllTariffsFetcher({ + onSuccess: updateTariffs, + onError: (error) => { + const errorMessage = getMessageFromFetchError(error); + if (errorMessage) enqueueSnackbar(errorMessage); + }, + }); + + useCustomTariffs({ + url: "https://admin.pena.digital/strator/privilege/service", + onNewUser: setCustomTariffs, + onError: (error) => { + const errorMessage = getMessageFromFetchError( + error, + "Не удалось получить кастомные тарифы" + ); + if (errorMessage) enqueueSnackbar(errorMessage); + }, + }); + + useDiscounts({ + onNewDiscounts: setDiscounts, + onError: (error) => { + const message = getMessageFromFetchError(error); + if (message) enqueueSnackbar(message); + }, + }); + + usePrivilegeFetcher({ + onSuccess: setPrivileges, + onError: (error) => { + console.log("usePrivilegeFetcher error :>> ", error); + }, + }); + + return ( + + + + ); +} diff --git a/src/index.tsx b/src/index.tsx index 0159852..024a541 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,12 +1,12 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { - BrowserRouter, - Navigate, - Route, - Routes, - useLocation, - useNavigate, + BrowserRouter, + Navigate, + Route, + Routes, + useLocation, + useNavigate, } from "react-router-dom"; import { CssBaseline, ThemeProvider } from "@mui/material"; import Faq from "./pages/Faq/Faq"; @@ -22,168 +22,134 @@ 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 "@utils/routes/privateRoute"; +import PrivateRoute from "@root/utils/routes/ProtectedRoute"; import reportWebVitals from "./reportWebVitals"; import { SnackbarProvider, enqueueSnackbar } from "notistack"; import "./index.css"; -import Layout from "./components/Layout"; +import ProtectedLayout from "./components/ProtectedLayout"; import { - clearUserData, - setUser, - setUserAccount, - useUserStore, + clearUserData, + setUser, + setUserAccount, + useUserStore, } from "./stores/user"; import TariffConstructor from "./pages/TariffConstructor/TariffConstructor"; import { - clearAuthToken, - getMessageFromFetchError, - usePrivilegeFetcher, - useUserAccountFetcher, - useUserFetcher, + clearAuthToken, + getMessageFromFetchError, useUserAccountFetcher, + useUserFetcher } from "@frontend/kitui"; -import { setCustomTariffs } from "@root/stores/customTariffs"; -import { useCustomTariffs } from "@root/utils/hooks/useCustomTariffs"; -import { useDiscounts } from "./utils/hooks/useDiscounts"; -import { setDiscounts } from "./stores/discounts"; import { pdfjs } from "react-pdf"; -import { setPrivileges } from "./stores/privileges"; import { theme } from "./utils/theme"; pdfjs.GlobalWorkerOptions.workerSrc = new URL( - "pdfjs-dist/build/pdf.worker.min.js", - import.meta.url + "pdfjs-dist/build/pdf.worker.min.js", + import.meta.url ).toString(); const App = () => { - const location = useLocation(); - const userId = useUserStore((state) => state.userId); - const navigate = useNavigate(); + const location = useLocation(); + const userId = useUserStore((state) => state.userId); + const navigate = useNavigate(); - useCustomTariffs({ - url: "https://admin.pena.digital/strator/privilege/service", - onNewUser: setCustomTariffs, - onError: (error) => { - const errorMessage = getMessageFromFetchError( - error, - "Не удалось получить кастомные тарифы" - ); - if (errorMessage) enqueueSnackbar(errorMessage); - }, - }); + useUserFetcher({ + url: `https://hub.pena.digital/user/${userId}`, + userId, + onNewUser: setUser, + onError: (error) => { + const errorMessage = getMessageFromFetchError(error); + if (errorMessage) { + enqueueSnackbar(errorMessage); + clearUserData(); + clearAuthToken(); + } + }, + }); - useUserFetcher({ - url: `https://hub.pena.digital/user/${userId}`, - userId, - onNewUser: setUser, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) { - enqueueSnackbar(errorMessage); - clearUserData(); - clearAuthToken(); - } - }, - }); + useUserAccountFetcher({ + url: "https://hub.pena.digital/customer/account", + userId, + onNewUserAccount: setUserAccount, + onError: (error) => { + const errorMessage = getMessageFromFetchError(error); + if (errorMessage) { + enqueueSnackbar(errorMessage); + clearUserData(); + clearAuthToken(); + navigate("/signin"); + } + }, + }); - useUserAccountFetcher({ - url: "https://hub.pena.digital/customer/account", - userId, - onNewUserAccount: setUserAccount, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) { - enqueueSnackbar(errorMessage); - clearUserData(); - clearAuthToken(); - navigate("/signin"); - } - }, - }); - - useDiscounts({ - onNewDiscounts: setDiscounts, - onError: (error) => { - const message = getMessageFromFetchError(error); - if (message) enqueueSnackbar(message); - }, - }); - - usePrivilegeFetcher({ - onSuccess: setPrivileges, - onError: (error) => { - console.log("usePrivilegeFetcher error :>> ", error); - }, - }); - - if (location.state?.redirectTo) - return ( - - ); - - return ( - <> - {location.state?.backgroundLocation && ( - - } /> - } /> - - )} - - } /> - - } - /> - - } - /> - }> - }> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } + if (location.state?.redirectTo) + return ( + - - - - - ); + ); + + return ( + <> + {location.state?.backgroundLocation && ( + + } /> + } /> + + )} + + } /> + + } + /> + + } + /> + }> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } + /> + + + + + ); }; const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement + document.getElementById("root") as HTMLElement ); root.render( - - - - - - - - - + + + + + + + + + ); // If you want to start measuring performance in your app, pass a function diff --git a/src/pages/SavedTariffs/index.tsx b/src/pages/SavedTariffs/index.tsx index 6a5ba10..a41b671 100644 --- a/src/pages/SavedTariffs/index.tsx +++ b/src/pages/SavedTariffs/index.tsx @@ -3,10 +3,8 @@ import SectionWrapper from "../../components/SectionWrapper"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker"; import SaveWrapper from "./SaveWrapper"; -import { useTariffStore, updateTariffs } from "@root/stores/tariffs"; -import { getMessageFromFetchError, type Tariff } from "@frontend/kitui"; -import { useAllTariffsFetcher } from "@root/utils/hooks/useAllTariffsFetcher"; -import { enqueueSnackbar } from "notistack"; +import { useTariffStore } from "@root/stores/tariffs"; +import { type Tariff } from "@frontend/kitui"; export default function SavedTariffs() { const theme = useTheme(); @@ -15,14 +13,6 @@ export default function SavedTariffs() { const tariffs: Tariff[] = useTariffStore((state) => state.tariffs); - useAllTariffsFetcher({ - onSuccess: updateTariffs, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) enqueueSnackbar(errorMessage); - }, - }); - console.log(tariffs); const handleCustomBackNavigation = useHistoryTracker(); diff --git a/src/pages/TariffConstructor/TariffConstructor.tsx b/src/pages/TariffConstructor/TariffConstructor.tsx index 6e26dfd..c3d1735 100644 --- a/src/pages/TariffConstructor/TariffConstructor.tsx +++ b/src/pages/TariffConstructor/TariffConstructor.tsx @@ -7,10 +7,6 @@ import CustomTariffCard from "./CustomTariffCard"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import TotalPrice from "@root/components/TotalPrice"; import { serviceNameByKey } from "@root/utils/serviceKeys"; -import { useAllTariffsFetcher } from "@root/utils/hooks/useAllTariffsFetcher"; -import { updateTariffs } from "@root/stores/tariffs"; -import { getMessageFromFetchError } from "@frontend/kitui"; -import { enqueueSnackbar } from "notistack"; import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker"; export default function TariffConstructor() { @@ -23,14 +19,6 @@ export default function TariffConstructor() { const basePrice = Object.values(summaryPriceBeforeDiscountsMap).reduce((a, e) => a + e, 0); const discountedPrice = Object.values(summaryPriceAfterDiscountsMap).reduce((a, e) => a + e, 0); - useAllTariffsFetcher({ - onSuccess: updateTariffs, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) enqueueSnackbar(errorMessage); - }, - }); - const handleCustomBackNavigation = useHistoryTracker(); return ( diff --git a/src/pages/Tariffs/TariffsPage.tsx b/src/pages/Tariffs/TariffsPage.tsx index a8f6cec..b529bbc 100644 --- a/src/pages/Tariffs/TariffsPage.tsx +++ b/src/pages/Tariffs/TariffsPage.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { useLocation } from "react-router-dom"; import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; import SectionWrapper from "@components/SectionWrapper"; -import { updateTariffs, useTariffStore } from "@root/stores/tariffs"; +import { useTariffStore } from "@root/stores/tariffs"; import { enqueueSnackbar } from "notistack"; import { Select } from "@root/components/Select"; import { Tabs } from "@root/components/Tabs"; @@ -16,7 +16,6 @@ import { addTariffToCart, useUserStore } from "@root/stores/user"; import { useDiscountStore } from "@root/stores/discounts"; import { Slider } from "./slider"; import { useCartStore } from "@root/stores/cart"; -import { useAllTariffsFetcher } from "@root/utils/hooks/useAllTariffsFetcher"; const subPages = ["Шаблонизатор", "Опросник", "Сокращатель ссылок"]; @@ -41,14 +40,6 @@ export default function TariffPage() { console.log(currentTariffs); - useAllTariffsFetcher({ - onSuccess: updateTariffs, - onError: (error) => { - const errorMessage = getMessageFromFetchError(error); - if (errorMessage) enqueueSnackbar(errorMessage); - }, - }); - function handleTariffItemClick(tariffId: string) { addTariffToCart(tariffId) .then(() => { diff --git a/src/utils/hooks/useAllTariffsFetcher.ts b/src/utils/hooks/useAllTariffsFetcher.ts deleted file mode 100644 index f820598..0000000 --- a/src/utils/hooks/useAllTariffsFetcher.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { GetTariffsResponse, Tariff, makeRequest } from "@frontend/kitui"; -import { useRef, useLayoutEffect, useEffect } from "react"; - - -export function useAllTariffsFetcher({ - baseUrl = process.env.NODE_ENV === "production" ? "/strator/tariff" : "https://hub.pena.digital/strator/tariff", - onSuccess, - onError, -}: { - baseUrl?: string; - onSuccess: (response: Tariff[]) => void; - onError?: (error: Error) => void; -}) { - const onNewTariffsRef = useRef(onSuccess); - const onErrorRef = useRef(onError); - - useLayoutEffect(() => { - onNewTariffsRef.current = onSuccess; - onErrorRef.current = onError; - }, [onError, onSuccess]); - - useEffect(() => { - const controller = new AbortController(); - - async function getPaginatedTariffs() { - let apiPage = 1; - const tariffsPerPage = 100; - let isDone = false; - - while (!isDone) { - try { - const result = await makeRequest({ - url: baseUrl + `?page=${apiPage}&limit=${tariffsPerPage}`, - method: "get", - useToken: true, - signal: controller.signal, - }); - if (result.tariffs.length > 0) { - onNewTariffsRef.current(result.tariffs); - apiPage++; - } else { - isDone = true; - } - } catch (error) { - onErrorRef.current?.(error as Error); - isDone = true; - } - } - } - - getPaginatedTariffs(); - - return () => controller.abort(); - }, [baseUrl]); -} diff --git a/src/utils/routes/ProtectedRoute.tsx b/src/utils/routes/ProtectedRoute.tsx new file mode 100644 index 0000000..f3431bf --- /dev/null +++ b/src/utils/routes/ProtectedRoute.tsx @@ -0,0 +1,9 @@ +import { Navigate, Outlet } from 'react-router-dom'; +import { useUserStore } from '@root/stores/user'; + + +export default function PrivateRoute() { + const user = useUserStore(state => state.user); + + return user ? : ; +} diff --git a/src/utils/routes/privateRoute.tsx b/src/utils/routes/privateRoute.tsx deleted file mode 100644 index 7e658bc..0000000 --- a/src/utils/routes/privateRoute.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Navigate, Outlet } from 'react-router-dom'; -import { useUserStore } from '@root/stores/user'; -import { Ticket, getMessageFromFetchError, useSSESubscription, useTicketsFetcher, useToken } from '@frontend/kitui'; -import { updateTickets, setTicketCount, useTicketStore, setTicketsFetchState } from '@root/stores/tickets'; -import { enqueueSnackbar } from 'notistack'; - - -export default function PrivateRoute() { - const token = useToken(); - const user = useUserStore(state => state.user); - const ticketApiPage = useTicketStore((state) => state.apiPage); - const ticketsPerPage = useTicketStore((state) => state.ticketsPerPage); - - useSSESubscription({ - enabled: Boolean(token), - url: `https://admin.pena.digital/heruvym/subscribe?Authorization=${token}`, - onNewData: data => { - updateTickets(data.filter(d => Boolean(d.id))); - setTicketCount(data.length); - }, - marker: "ticket", - }); - - useTicketsFetcher({ - url: "https://hub.pena.digital/heruvym/getTickets", - ticketsPerPage, - ticketApiPage, - onSuccess: (result) => { - if (result.data) updateTickets(result.data); - setTicketCount(result.count); - }, - onError: (error: Error) => { - const message = getMessageFromFetchError(error); - if (message) enqueueSnackbar(message); - }, - onFetchStateChange: setTicketsFetchState, - }); - - return user ? : ; -} diff --git a/yarn.lock b/yarn.lock index 3505070..90de839 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1532,10 +1532,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@frontend/kitui@1.0.44": - version "1.0.44" - resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.44.tgz#7a6e48e37294b6cc283e22fa0fe6ee4903a843aa" - integrity sha1-em5I43KUtswoPiL6D+buSQOoQ6o= +"@frontend/kitui@1.0.45": + version "1.0.45" + resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.45.tgz#61400fe4e0f29b213138997197389d74f81981ef" + integrity sha1-YUAP5ODymyExOJlxlziddPgZge8= dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2"