252 lines
8.1 KiB
JavaScript
252 lines
8.1 KiB
JavaScript
import { useSplitClient } from "@splitsoftware/splitio-react";
|
|
import { Button, Result } from "antd";
|
|
import LogRocket from "logrocket";
|
|
import { lazy, Suspense, useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { Route, Routes, useNavigate } from "react-router-dom";
|
|
import { createStructuredSelector } from "reselect";
|
|
import DocumentEditorContainer from "../components/document-editor/document-editor.container";
|
|
import ErrorBoundary from "../components/error-boundary/error-boundary.component";
|
|
import LoadingSpinner from "../components/loading-spinner/loading-spinner.component";
|
|
import DisclaimerPage from "../pages/disclaimer/disclaimer.page";
|
|
import LandingPage from "../pages/landing/landing.page";
|
|
import TechPageContainer from "../pages/tech/tech.page.container";
|
|
import SimplifiedPartsPageContainer from "../pages/simplified-parts/simplified-parts.page.container.jsx";
|
|
import { setIsPartsEntry, setOnline } from "../redux/application/application.actions";
|
|
import { selectIsPartsEntry, selectOnline } from "../redux/application/application.selectors";
|
|
import { checkUserSession } from "../redux/user/user.actions";
|
|
import { selectBodyshop, selectCurrentEula, selectCurrentUser } from "../redux/user/user.selectors";
|
|
import PrivateRoute from "../components/PrivateRoute";
|
|
import "./App.styles.scss";
|
|
import Eula from "../components/eula/eula.component";
|
|
import InstanceRenderMgr from "../utils/instanceRenderMgr";
|
|
import ProductFruitsWrapper from "./ProductFruitsWrapper.jsx";
|
|
import { NotificationProvider } from "../contexts/Notifications/notificationContext.jsx";
|
|
import SocketProvider from "../contexts/SocketIO/socketProvider.jsx";
|
|
import SoundWrapper from "./SoundWrapper.jsx";
|
|
|
|
const ResetPassword = lazy(() => import("../pages/reset-password/reset-password.component"));
|
|
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
|
|
const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page"));
|
|
const CsiPage = lazy(() => import("../pages/csi/csi.container.page"));
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
currentUser: selectCurrentUser,
|
|
online: selectOnline,
|
|
bodyshop: selectBodyshop,
|
|
currentEula: selectCurrentEula,
|
|
isPartsEntry: selectIsPartsEntry
|
|
});
|
|
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
checkUserSession: () => dispatch(checkUserSession()),
|
|
setOnline: (isOnline) => dispatch(setOnline(isOnline)),
|
|
setIsPartsEntry: (isParts) => dispatch(setIsPartsEntry(isParts))
|
|
});
|
|
|
|
export function App({
|
|
bodyshop,
|
|
checkUserSession,
|
|
currentUser,
|
|
online,
|
|
setOnline,
|
|
setIsPartsEntry,
|
|
currentEula,
|
|
isPartsEntry
|
|
}) {
|
|
const client = useSplitClient().client;
|
|
const [listenersAdded, setListenersAdded] = useState(false);
|
|
const { t } = useTranslation();
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
if (!navigator.onLine) {
|
|
setOnline(false);
|
|
}
|
|
checkUserSession();
|
|
}, [checkUserSession, setOnline]);
|
|
|
|
useEffect(() => {
|
|
const pathname = window.location.pathname;
|
|
const isParts = pathname === "/parts" || pathname.startsWith("/parts/");
|
|
setIsPartsEntry(isParts);
|
|
}, [setIsPartsEntry]);
|
|
|
|
// Associate event listeners, memoize to prevent multiple listeners being added
|
|
useEffect(() => {
|
|
const offlineListener = () => {
|
|
setOnline(false);
|
|
};
|
|
|
|
const onlineListener = () => {
|
|
setOnline(true);
|
|
};
|
|
|
|
if (!listenersAdded) {
|
|
console.log("Added events for offline and online");
|
|
window.addEventListener("offline", offlineListener);
|
|
window.addEventListener("online", onlineListener);
|
|
setListenersAdded(true);
|
|
}
|
|
|
|
return () => {
|
|
window.removeEventListener("offline", offlineListener);
|
|
window.removeEventListener("online", onlineListener);
|
|
};
|
|
}, [setOnline, listenersAdded]);
|
|
|
|
useEffect(() => {
|
|
if (currentUser.authorized && bodyshop) {
|
|
client.setAttribute("imexshopid", bodyshop.imexshopid);
|
|
|
|
if (
|
|
client.getTreatment("LogRocket_Tracking") === "on" ||
|
|
window.location.hostname ===
|
|
InstanceRenderMgr({
|
|
imex: "beta.imex.online",
|
|
rome: "beta.romeonline.io"
|
|
})
|
|
) {
|
|
console.log("LR Start");
|
|
LogRocket.init(
|
|
InstanceRenderMgr({
|
|
imex: "gvfvfw/bodyshopapp",
|
|
rome: "rome-online/rome-online"
|
|
})
|
|
);
|
|
}
|
|
}
|
|
}, [bodyshop, client, currentUser.authorized]);
|
|
|
|
if (currentUser.authorized === null) {
|
|
return <LoadingSpinner message={t("general.labels.loggingin")} />;
|
|
}
|
|
|
|
if (!online) {
|
|
return (
|
|
<Result
|
|
status="warning"
|
|
title={t("general.labels.nointernet")}
|
|
subTitle={t("general.labels.nointernet_sub")}
|
|
extra={
|
|
<Button type="primary" onClick={() => window.location.reload()}>
|
|
{t("general.actions.refresh")}
|
|
</Button>
|
|
}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (!isPartsEntry && currentEula && !currentUser.eulaIsAccepted) {
|
|
return <Eula />;
|
|
}
|
|
|
|
// Any route that is not assigned and matched will default to the Landing Page component
|
|
return (
|
|
<Suspense
|
|
fallback={
|
|
<LoadingSpinner
|
|
message={InstanceRenderMgr({
|
|
imex: t("titles.imexonline"),
|
|
rome: t("titles.romeonline")
|
|
})}
|
|
/>
|
|
}
|
|
>
|
|
<ProductFruitsWrapper
|
|
currentUser={currentUser}
|
|
bodyshop={bodyshop}
|
|
workspaceCode={bodyshop?.tours_enabled ? "9BkbEseqNqxw8jUH" : ""}
|
|
isPartsEntry={isPartsEntry}
|
|
/>
|
|
|
|
<NotificationProvider>
|
|
<SoundWrapper bodyshop={bodyshop}>
|
|
<Routes>
|
|
<Route
|
|
path="*"
|
|
element={
|
|
<ErrorBoundary>
|
|
<LandingPage />
|
|
</ErrorBoundary>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/signin"
|
|
element={
|
|
<ErrorBoundary>
|
|
<SignInPage />
|
|
</ErrorBoundary>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/resetpassword"
|
|
element={
|
|
<ErrorBoundary>
|
|
<ResetPassword />
|
|
</ErrorBoundary>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/csi/:surveyId"
|
|
element={
|
|
<ErrorBoundary>
|
|
<CsiPage />
|
|
</ErrorBoundary>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/disclaimer"
|
|
element={
|
|
<ErrorBoundary>
|
|
<DisclaimerPage />
|
|
</ErrorBoundary>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/manage/*"
|
|
element={
|
|
<ErrorBoundary>
|
|
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}>
|
|
<PrivateRoute isAuthorized={currentUser.authorized} />
|
|
</SocketProvider>
|
|
</ErrorBoundary>
|
|
}
|
|
>
|
|
<Route path="*" element={<ManagePage />} />
|
|
</Route>
|
|
<Route
|
|
path="/tech/*"
|
|
element={
|
|
<ErrorBoundary>
|
|
<SocketProvider bodyshop={bodyshop} navigate={navigate} currentUser={currentUser}>
|
|
<PrivateRoute isAuthorized={currentUser.authorized} />
|
|
</SocketProvider>
|
|
</ErrorBoundary>
|
|
}
|
|
>
|
|
<Route path="*" element={<TechPageContainer />} />
|
|
</Route>
|
|
<Route
|
|
path="/parts/*"
|
|
element={
|
|
<ErrorBoundary>
|
|
<PrivateRoute isAuthorized={currentUser.authorized} />
|
|
</ErrorBoundary>
|
|
}
|
|
>
|
|
<Route path="*" element={<SimplifiedPartsPageContainer />} />
|
|
</Route>
|
|
<Route path="/edit/*" element={<PrivateRoute isAuthorized={currentUser.authorized} />}>
|
|
<Route path="*" element={<DocumentEditorContainer />} />
|
|
</Route>
|
|
</Routes>
|
|
</SoundWrapper>
|
|
</NotificationProvider>
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(App);
|