router for authentication
parent
a2f0a71bf4
commit
f992526f85
|
@ -23,7 +23,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="Dashboard for ZeitAdler" />
|
<meta name="description" content="Dashboard for ZeitAdler" />
|
||||||
|
|
||||||
<title>Dashboard - ZeitAdler</title>
|
<title>ZeitAdler</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"short_name": "Dashboard - ZeitAdler",
|
"short_name": "ZeitAdler",
|
||||||
"name": "Dashboard - ZeitAdler",
|
"name": "ZeitAdler",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/android-chrome-192x192.png",
|
"src": "/android-chrome-192x192.png",
|
||||||
|
|
14
src/App.js
14
src/App.js
|
@ -1,7 +1,7 @@
|
||||||
import "antd/dist/reset.css";
|
import "antd/dist/reset.css";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { Layout, Spin, Typography } from "antd";
|
import { Layout, Spin, Typography } from "antd";
|
||||||
import { Constants, UseUserSession, myFetch } from "./utils";
|
import { Constants, UseUserSession, handleLogout, myFetch } from "./utils";
|
||||||
import DashboardLayout from "./Components/DashboardLayout";
|
import DashboardLayout from "./Components/DashboardLayout";
|
||||||
import SideBarProvider from "./Contexts/SideBarContext";
|
import SideBarProvider from "./Contexts/SideBarContext";
|
||||||
import { AppProvider } from "./Contexts/AppContext";
|
import { AppProvider } from "./Contexts/AppContext";
|
||||||
|
@ -14,6 +14,7 @@ import { clarity } from "react-microsoft-clarity";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import MyAppLogo from "./Components/MyAppLogo";
|
import MyAppLogo from "./Components/MyAppLogo";
|
||||||
import Authentication from "./Pages/Authentication";
|
import Authentication from "./Pages/Authentication";
|
||||||
|
import { AuthenticationRoutes } from "./Components/AppRoutes";
|
||||||
|
|
||||||
export function Loading() {
|
export function Loading() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -83,14 +84,15 @@ export default function App() {
|
||||||
i18n.changeLanguage(data.user.language);
|
i18n.changeLanguage(data.user.language);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() =>
|
||||||
setUserSession();
|
handleLogout({
|
||||||
window.location.href = "/";
|
setUserSession: setUserSession,
|
||||||
});
|
})
|
||||||
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!userSession) {
|
if (!userSession) {
|
||||||
return <Authentication />;
|
return <AuthenticationRoutes setUserSession={setUserSession} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appUserData === null) {
|
if (appUserData === null) {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { Route, Routes } from "react-router-dom";
|
import { Navigate, Route, Routes } from "react-router-dom";
|
||||||
import { Constants, isDevelopmentEnv } from "../../utils";
|
import { Constants, isDevelopmentEnv } from "../../utils";
|
||||||
import { lazy } from "react";
|
import { lazy } from "react";
|
||||||
import { MySupsenseFallback } from "../MySupsenseFallback";
|
import { MySupsenseFallback } from "../MySupsenseFallback";
|
||||||
|
import Authentication, {
|
||||||
|
AuthenticationMethod,
|
||||||
|
} from "../../Pages/Authentication";
|
||||||
|
|
||||||
// Lazy-loaded components
|
// Lazy-loaded components
|
||||||
const Dashboard = lazy(() => import("../../Pages/Dashboard"));
|
const Dashboard = lazy(() => import("../../Pages/Dashboard"));
|
||||||
|
@ -17,7 +20,36 @@ const StoreWebsite = lazy(() => import("../../Pages/Store/Website"));
|
||||||
//const Feedback = lazy(() => import("../../Pages/Feedback"));
|
//const Feedback = lazy(() => import("../../Pages/Feedback"));
|
||||||
const UserProfile = lazy(() => import("../../Pages/UserProfile"));
|
const UserProfile = lazy(() => import("../../Pages/UserProfile"));
|
||||||
|
|
||||||
export default function AppRoutes({ setUserSession }) {
|
export function AuthenticationRoutes() {
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route
|
||||||
|
path={Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN}
|
||||||
|
element={
|
||||||
|
<MySupsenseFallback>
|
||||||
|
<Authentication method={AuthenticationMethod.LOGIN} />
|
||||||
|
</MySupsenseFallback>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={Constants.ROUTE_PATHS.AUTHENTICATION.SIGN_UP}
|
||||||
|
element={
|
||||||
|
<MySupsenseFallback>
|
||||||
|
<Authentication method={AuthenticationMethod.SIGNUP} />
|
||||||
|
</MySupsenseFallback>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path="*"
|
||||||
|
element={<Navigate to={Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN} />}
|
||||||
|
/>
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AppRoutes({ setUserSession }) {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
|
|
|
@ -209,13 +209,8 @@ export function MyAvailableCheckFormInput({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: body,
|
body: body,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => resolve())
|
||||||
resolve();
|
.catch(() => reject(ruleMessageValueNotAvailable));
|
||||||
})
|
|
||||||
.catch((errStatus) => {
|
|
||||||
console.log(errStatus);
|
|
||||||
reject(ruleMessageValueNotAvailable);
|
|
||||||
});
|
|
||||||
}, fetchDelay);
|
}, fetchDelay);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Content } from "antd/es/layout/layout";
|
import { Content } from "antd/es/layout/layout";
|
||||||
import AppRoutes from "../AppRoutes";
|
|
||||||
import { Layout } from "antd";
|
import { Layout } from "antd";
|
||||||
import HeaderMenu from "../Header";
|
import HeaderMenu from "../Header";
|
||||||
import { BreakpointLgWidth } from "../../utils";
|
import { BreakpointLgWidth } from "../../utils";
|
||||||
import { memo } from "react";
|
import { memo } from "react";
|
||||||
|
import { AppRoutes } from "../AppRoutes";
|
||||||
|
|
||||||
const PageContent = memo(
|
const PageContent = memo(
|
||||||
({
|
({
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
import { createContext, useContext, useEffect, useRef } from "react";
|
|
||||||
import { wsConnectionCustomEventName } from "../utils";
|
|
||||||
|
|
||||||
const WebSocketContext = createContext(null);
|
|
||||||
|
|
||||||
export const useWebSocketContext = () => useContext(WebSocketContext);
|
|
||||||
|
|
||||||
let wsConnectionEvent = null;
|
|
||||||
let firstConnection = true;
|
|
||||||
|
|
||||||
export default function WebSocketProvider({
|
|
||||||
children,
|
|
||||||
userSession,
|
|
||||||
setUserSession,
|
|
||||||
isWebSocketReady,
|
|
||||||
setIsWebSocketReady,
|
|
||||||
notificationApi,
|
|
||||||
}) {
|
|
||||||
const ws = useRef(null);
|
|
||||||
const wsMessageCache = useRef([]);
|
|
||||||
|
|
||||||
if (wsConnectionEvent === null) {
|
|
||||||
wsConnectionEvent = new CustomEvent(wsConnectionCustomEventName, {
|
|
||||||
detail: "wsReconnect",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const connect = () => {
|
|
||||||
setIsWebSocketReady(true);
|
|
||||||
|
|
||||||
/*
|
|
||||||
ws.current = new WebSocket(
|
|
||||||
`${Constants.WS_ADDRESS}?auth=${userSession}&bts=${BrowserTabSession}`
|
|
||||||
);
|
|
||||||
|
|
||||||
ws.current.onopen = () => {
|
|
||||||
sideBarContext.setConnectionBadgeStatus("success");
|
|
||||||
setIsWebSocketReady(true);
|
|
||||||
|
|
||||||
if (firstConnection) {
|
|
||||||
firstConnection = false;
|
|
||||||
} else {
|
|
||||||
document.dispatchEvent(wsConnectionEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
myFetch("/user/", "GET").then((data) => {
|
|
||||||
appContext.userId.current = data.UserId;
|
|
||||||
appContext.setUserPermissions(
|
|
||||||
data.Permissions === null ? [] : data.Permissions
|
|
||||||
);
|
|
||||||
appContext.setUsers(data.Users);
|
|
||||||
headerContext.setTotalNotifications(data.TotalNotifications);
|
|
||||||
sideBarContext.setUsername(data.Username);
|
|
||||||
sideBarContext.setAvatar(data.Avatar);
|
|
||||||
sideBarContext.setAvailableCategories(
|
|
||||||
data.AvailableCategories === null ? [] : data.AvailableCategories
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (wsMessageCache.current.length > 0) {
|
|
||||||
// send cached messages
|
|
||||||
wsMessageCache.current.forEach((message) => {
|
|
||||||
ws.current.send(JSON.stringify(message));
|
|
||||||
});
|
|
||||||
|
|
||||||
wsMessageCache.current = [];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.current.onmessage = (event) => {
|
|
||||||
handleWebSocketMessage(
|
|
||||||
event,
|
|
||||||
navigate,
|
|
||||||
notificationApi,
|
|
||||||
sideBarContext,
|
|
||||||
appContext,
|
|
||||||
headerContext,
|
|
||||||
groupTasksContext,
|
|
||||||
userProfileContext,
|
|
||||||
adminAreaRolesContext,
|
|
||||||
usersContext,
|
|
||||||
consolesContext,
|
|
||||||
scannerContext,
|
|
||||||
crmContext
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.current.onclose = (event) => {
|
|
||||||
setIsWebSocketReady(false);
|
|
||||||
sideBarContext.setConnectionBadgeStatus("error");
|
|
||||||
console.warn("closed", event);
|
|
||||||
|
|
||||||
// custom code defined by the backend server
|
|
||||||
if (event.code === 4001 || event.code === 4002) {
|
|
||||||
//Unauthorized || SessionClosed
|
|
||||||
|
|
||||||
setUserSession();
|
|
||||||
window.location.href = "/";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.reason.code === 1005) return;
|
|
||||||
|
|
||||||
console.warn("reconnecting...");
|
|
||||||
|
|
||||||
setTimeout(() => connect(), 1000);
|
|
||||||
}; */
|
|
||||||
};
|
|
||||||
|
|
||||||
const SendSocketMessage = (cmd, body) => {
|
|
||||||
if (
|
|
||||||
isWebSocketReady &&
|
|
||||||
ws.current !== null &&
|
|
||||||
ws.current.readyState === 1
|
|
||||||
) {
|
|
||||||
ws.current.send(JSON.stringify({ Cmd: cmd, Body: body }));
|
|
||||||
} else {
|
|
||||||
wsMessageCache.current.push({ Cmd: cmd, Body: body });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
connect();
|
|
||||||
|
|
||||||
return () => ws.current.close();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<WebSocketContext.Provider value={{ SendSocketMessage: SendSocketMessage }}>
|
|
||||||
{children}
|
|
||||||
</WebSocketContext.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -25,20 +25,17 @@ import {
|
||||||
} from "../../Components/MyFormInputs";
|
} from "../../Components/MyFormInputs";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import MyAppLogo from "../../Components/MyAppLogo";
|
import MyAppLogo from "../../Components/MyAppLogo";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const AuthenticationMethod = {
|
export const AuthenticationMethod = {
|
||||||
LOGIN: 1,
|
LOGIN: 1,
|
||||||
SIGNUP: 2,
|
SIGNUP: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Authentication() {
|
export default function Authentication({ method }) {
|
||||||
const [notificationApi, notificationContextHolder] =
|
const [notificationApi, notificationContextHolder] =
|
||||||
notification.useNotification();
|
notification.useNotification();
|
||||||
|
|
||||||
const [selectedMethod, setSelectedMethod] = useState(
|
|
||||||
AuthenticationMethod.LOGIN
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{notificationContextHolder}
|
{notificationContextHolder}
|
||||||
|
@ -60,16 +57,10 @@ export default function Authentication() {
|
||||||
<MyAppLogo height={80} />
|
<MyAppLogo height={80} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedMethod === AuthenticationMethod.LOGIN ? (
|
{method === AuthenticationMethod.LOGIN ? (
|
||||||
<Login
|
<Login notificationApi={notificationApi} />
|
||||||
switchMethod={() => setSelectedMethod(AuthenticationMethod.SIGNUP)}
|
|
||||||
notificationApi={notificationApi}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<SignUp
|
<SignUp notificationApi={notificationApi} />
|
||||||
switchMethod={() => setSelectedMethod(AuthenticationMethod.LOGIN)}
|
|
||||||
notificationApi={notificationApi}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
|
@ -97,8 +88,10 @@ const LoginStep = {
|
||||||
|
|
||||||
// First step: account name -> get state of account by backend
|
// First step: account name -> get state of account by backend
|
||||||
// Second step: if account is active -> password -> login otherwise show the state of the account (e. g. deleted, banned)
|
// Second step: if account is active -> password -> login otherwise show the state of the account (e. g. deleted, banned)
|
||||||
function Login({ switchMethod, notificationApi }) {
|
function Login({ notificationApi }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [isRequesting, setIsRequesting] = useState(false);
|
const [isRequesting, setIsRequesting] = useState(false);
|
||||||
const [step, setStep] = useState(LoginStep.ACCOUNT_NAME);
|
const [step, setStep] = useState(LoginStep.ACCOUNT_NAME);
|
||||||
|
|
||||||
|
@ -225,6 +218,7 @@ function Login({ switchMethod, notificationApi }) {
|
||||||
size="large"
|
size="large"
|
||||||
block
|
block
|
||||||
loading={isRequesting}
|
loading={isRequesting}
|
||||||
|
htmlType="submit"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
let validateFields = [];
|
let validateFields = [];
|
||||||
|
|
||||||
|
@ -304,7 +298,13 @@ function Login({ switchMethod, notificationApi }) {
|
||||||
<Flex justify="center" style={{ paddingTop: 12 }}>
|
<Flex justify="center" style={{ paddingTop: 12 }}>
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
{t("authentication.login.dontHaveAccount")}{" "}
|
{t("authentication.login.dontHaveAccount")}{" "}
|
||||||
<Button type="link" style={{ padding: 0 }} onClick={switchMethod}>
|
<Button
|
||||||
|
type="link"
|
||||||
|
style={{ padding: 0 }}
|
||||||
|
onClick={() =>
|
||||||
|
navigate(Constants.ROUTE_PATHS.AUTHENTICATION.SIGN_UP)
|
||||||
|
}
|
||||||
|
>
|
||||||
{t("authentication.signUpLink")}
|
{t("authentication.signUpLink")}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
|
@ -313,8 +313,10 @@ function Login({ switchMethod, notificationApi }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SignUp({ switchMethod, notificationApi }) {
|
function SignUp({ notificationApi }) {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [isRequesting, setIsRequesting] = useState(false);
|
const [isRequesting, setIsRequesting] = useState(false);
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
@ -358,11 +360,21 @@ function SignUp({ switchMethod, notificationApi }) {
|
||||||
setIsRequesting(false);
|
setIsRequesting(false);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => showInputsInvalidNotification(notificationApi, t));
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
showInputsInvalidNotification(notificationApi, t);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form form={form} layout="vertical" requiredMark={false}>
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
requiredMark={false}
|
||||||
|
initialValues={{
|
||||||
|
rememberMe: false,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<MyUsernameFormInput />
|
<MyUsernameFormInput />
|
||||||
|
|
||||||
<MyAccountNameFormInput hasFeedback={true} />
|
<MyAccountNameFormInput hasFeedback={true} />
|
||||||
|
@ -384,7 +396,11 @@ function SignUp({ switchMethod, notificationApi }) {
|
||||||
<Flex justify="center" style={{ paddingTop: 12 }}>
|
<Flex justify="center" style={{ paddingTop: 12 }}>
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
{t("authentication.signUp.alreadyHaveAccount")}{" "}
|
{t("authentication.signUp.alreadyHaveAccount")}{" "}
|
||||||
<Button type="link" style={{ padding: 0 }} onClick={switchMethod}>
|
<Button
|
||||||
|
type="link"
|
||||||
|
style={{ padding: 0 }}
|
||||||
|
onClick={() => navigate(Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN)}
|
||||||
|
>
|
||||||
{t("authentication.loginLink")}
|
{t("authentication.loginLink")}
|
||||||
</Button>
|
</Button>
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
|
@ -392,81 +408,3 @@ function SignUp({ switchMethod, notificationApi }) {
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
htmlType="submit"
|
|
||||||
loading={isRequesting}
|
|
||||||
onClick={() => {
|
|
||||||
form
|
|
||||||
.validateFields()
|
|
||||||
.then((values) => {
|
|
||||||
setIsRequesting(true);
|
|
||||||
|
|
||||||
let body = {
|
|
||||||
accountName: values.accountName.toLocaleLowerCase(),
|
|
||||||
password: EncodeStringToBase64(values.password),
|
|
||||||
};
|
|
||||||
|
|
||||||
if (selectedMethod === "2") {
|
|
||||||
body.username = values.username;
|
|
||||||
body.language = i18n.language;
|
|
||||||
}
|
|
||||||
|
|
||||||
myFetch({
|
|
||||||
url: `/user/auth/${
|
|
||||||
selectedMethod === "1" ? "login" : "signup"
|
|
||||||
}`,
|
|
||||||
method: "POST",
|
|
||||||
body: body,
|
|
||||||
notificationApi: notificationApi,
|
|
||||||
t: t,
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
setUserSessionToLocalStorage(data.XAuthorization);
|
|
||||||
window.location.href = "/";
|
|
||||||
})
|
|
||||||
.catch((errStatus) => {
|
|
||||||
showErrorNotification(errStatus);
|
|
||||||
setIsRequesting(false);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => showInputsInvalidNotification(notificationApi, t));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{selectedMethod === AuthenticationMethod.LOGIN
|
|
||||||
? t("authentication.login.button")
|
|
||||||
: t("authentication.signUp.button")}
|
|
||||||
</Button>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
<Tabs
|
|
||||||
defaultActiveKey="1"
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
key: "1",
|
|
||||||
label: t("login.login"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "2",
|
|
||||||
label: t("login.signUp"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
centered
|
|
||||||
onChange={(activeKey) => setSelectedMethod(activeKey)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Form form={form} layout="vertical" requiredMark={false}>
|
|
||||||
{selectedMethod === "2" && <MyUsernameFormInput />}
|
|
||||||
|
|
||||||
<MyAccountNameFormInput
|
|
||||||
disableAccountNameCheck={selectedMethod === "1"}
|
|
||||||
hasFeedback={selectedMethod === "2"}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<MyPasswordFormInput />
|
|
||||||
</Form>
|
|
||||||
*/
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ export const Constants = {
|
||||||
// WS_ADDRESS: wsAddress,
|
// WS_ADDRESS: wsAddress,
|
||||||
EMBED_CALENDAR_ADDRESS: "https://calendar.ex.umbach.dev/embed/?id=",
|
EMBED_CALENDAR_ADDRESS: "https://calendar.ex.umbach.dev/embed/?id=",
|
||||||
ROUTE_PATHS: {
|
ROUTE_PATHS: {
|
||||||
|
AUTHENTICATION: {
|
||||||
|
LOGIN: "/login",
|
||||||
|
SIGN_UP: "/signup",
|
||||||
|
},
|
||||||
OVERVIEW: "/",
|
OVERVIEW: "/",
|
||||||
STORE: {
|
STORE: {
|
||||||
// schema: /store/:storeId/:subPage
|
// schema: /store/:storeId/:subPage
|
||||||
|
@ -276,7 +280,7 @@ export function showUnkownErrorNotification(notificationApi, t) {
|
||||||
export function handleLogout({ setUserSession }) {
|
export function handleLogout({ setUserSession }) {
|
||||||
if (setUserSession !== undefined) setUserSession();
|
if (setUserSession !== undefined) setUserSession();
|
||||||
|
|
||||||
window.location.href = "/";
|
window.location.href = Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FormatDatetime(datetime) {
|
export function FormatDatetime(datetime) {
|
||||||
|
|
Loading…
Reference in New Issue