upgrade package & refactor hooks

This commit is contained in:
nflnkr 2023-08-29 16:38:05 +03:00
parent 5a20286486
commit 5d7744ca42
11 changed files with 210 additions and 288 deletions

@ -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",

@ -1,10 +0,0 @@
import { Outlet } from "react-router-dom";
import Navbar from "./Navbar/Navbar";
export default function Layout() {
return (
<Navbar>
<Outlet />
</Navbar>
);
}

@ -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<Ticket>({
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 (
<Navbar>
<Outlet />
</Navbar>
);
}

@ -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 (
<Navigate
to={location.state.redirectTo}
replace
state={{ backgroundLocation: location }}
/>
);
return (
<>
{location.state?.backgroundLocation && (
<Routes>
<Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} />
</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 element={<Layout />}>
<Route element={<PrivateRoute />}>
<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 />}
if (location.state?.redirectTo)
return (
<Navigate
to={location.state.redirectTo}
replace
state={{ backgroundLocation: location }}
/>
</Route>
</Route>
</Routes>
</>
);
);
return (
<>
{location.state?.backgroundLocation && (
<Routes>
<Route path="/signin" element={<SigninDialog />} />
<Route path="/signup" element={<SignupDialog />} />
</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 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>
</Routes>
</>
);
};
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
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

@ -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();

@ -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 (

@ -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(() => {

@ -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<never, GetTariffsResponse>({
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]);
}

@ -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 ? <Outlet /> : <Navigate to="/" replace />;
}

@ -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<Ticket>({
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 ? <Outlet /> : <Navigate to="/" replace />;
}

@ -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"