auth screens
parent
8a027eb403
commit
41d81e8f13
|
@ -24,7 +24,7 @@
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
"passwordPlaceholder": "Geben Sie Ihr Passwort ein",
|
"passwordPlaceholder": "Geben Sie Ihr Passwort ein",
|
||||||
"noDataFound": "Keine Einträge gefunden",
|
"noDataFound": "Keine Einträge gefunden",
|
||||||
"inputRules": {
|
"inputRules": {
|
||||||
"usernameRequired": "Anzeigename ist erforderlich",
|
"usernameRequired": "Anzeigename ist erforderlich",
|
||||||
"usernameMinLength": "Anzeigename muss mindestens {{minLength}} Zeichen lang sein",
|
"usernameMinLength": "Anzeigename muss mindestens {{minLength}} Zeichen lang sein",
|
||||||
"accountNameRequired": "Benutzername ist erforderlich",
|
"accountNameRequired": "Benutzername ist erforderlich",
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
"serviceActivityDurationMinutesPlaceholder": "Geben Sie die Dauer der Tätigkeit in Minuten ein",
|
"serviceActivityDurationMinutesPlaceholder": "Geben Sie die Dauer der Tätigkeit in Minuten ein",
|
||||||
"serviceActivityDurationMinutesUnit": "Minuten",
|
"serviceActivityDurationMinutesUnit": "Minuten",
|
||||||
"serviceActivityResponsible": "Verantwortliche Mitarbeiter",
|
"serviceActivityResponsible": "Verantwortliche Mitarbeiter",
|
||||||
"inputRules": {
|
"inputRules": {
|
||||||
"serviceNameRequired": "Name der Dienstleistung ist erforderlich",
|
"serviceNameRequired": "Name der Dienstleistung ist erforderlich",
|
||||||
"serviceNameMinLength": "Name der Dienstleistung muss mindestens {{minLength}} Zeichen lang sein",
|
"serviceNameMinLength": "Name der Dienstleistung muss mindestens {{minLength}} Zeichen lang sein",
|
||||||
"serviceActivityNameRequired": "Name der Tätigkeit ist erforderlich",
|
"serviceActivityNameRequired": "Name der Tätigkeit ist erforderlich",
|
||||||
|
@ -126,6 +126,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"calendar": {
|
"calendar": {
|
||||||
"pageTitle": "Kalender"
|
"pageTitle": "Kalender",
|
||||||
|
"authFinish": {
|
||||||
|
"title": "Erfolgreich verbunden",
|
||||||
|
"description": "Die Verbindung mit Ihrem Google-Kalender war erfolgreich.",
|
||||||
|
"button": "Weiter zum Kalender",
|
||||||
|
"countDownRedirect": "Sie werden in {{countDown}} Sekunden weitergeleitet."
|
||||||
|
},
|
||||||
|
"authFailed": {
|
||||||
|
"title": "Verbindung fehlgeschlagen",
|
||||||
|
"description": "Die Verbindung mit Ihrem Google-Kalender ist fehlgeschlagen.",
|
||||||
|
"button": "Erneut versuchen"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"calendar": {
|
"calendar": {
|
||||||
"pageTitle": "Calendar"
|
"pageTitle": "Calendar",
|
||||||
|
"authFinish": {
|
||||||
|
"title": "Connection successful",
|
||||||
|
"description": "Connection to your calendar was successful.",
|
||||||
|
"button": "Continue to calendar",
|
||||||
|
"countDownRedirect": "Redirecting to calendar in {{countDown}} seconds"
|
||||||
|
},
|
||||||
|
"authFailed": {
|
||||||
|
"title": "Connection failed",
|
||||||
|
"description": "Connection to your calendar failed.",
|
||||||
|
"button": "Try again"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Route, Routes } from "react-router-dom";
|
import { Route, Routes } from "react-router-dom";
|
||||||
import { Constants } from "../../utils";
|
import { Constants } from "../../utils";
|
||||||
import { useAppContext } from "../../Contexts/AppContext";
|
|
||||||
import { lazy } from "react";
|
import { lazy } from "react";
|
||||||
import { MySupsenseFallback } from "../MySupsenseFallback";
|
import { MySupsenseFallback } from "../MySupsenseFallback";
|
||||||
|
|
||||||
|
@ -11,6 +10,7 @@ const StoreSettings = lazy(() => import("../../Pages/Store/Settings"));
|
||||||
const StoreEmployees = lazy(() => import("../../Pages/Store/Employees"));
|
const StoreEmployees = lazy(() => import("../../Pages/Store/Employees"));
|
||||||
const StoreServices = lazy(() => import("../../Pages/Store/Services"));
|
const StoreServices = lazy(() => import("../../Pages/Store/Services"));
|
||||||
const StoreCalendar = lazy(() => import("../../Pages/Store/Calendar"));
|
const StoreCalendar = lazy(() => import("../../Pages/Store/Calendar"));
|
||||||
|
const StoreCalendarAuth = lazy(() => import("../../Pages/Store/Calendar/Auth"));
|
||||||
const Support = lazy(() => import("../../Pages/Support"));
|
const Support = lazy(() => import("../../Pages/Support"));
|
||||||
const Feedback = lazy(() => import("../../Pages/Feedback"));
|
const Feedback = lazy(() => import("../../Pages/Feedback"));
|
||||||
const UserProfile = lazy(() => import("../../Pages/UserProfile"));
|
const UserProfile = lazy(() => import("../../Pages/UserProfile"));
|
||||||
|
@ -65,6 +65,15 @@ export default function AppRoutes({ userSession, setUserSession }) {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={`${Constants.ROUTE_PATHS.STORE.CALENDAR_AUTH}/:status`}
|
||||||
|
element={
|
||||||
|
<MySupsenseFallback>
|
||||||
|
<StoreCalendarAuth />
|
||||||
|
</MySupsenseFallback>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={Constants.ROUTE_PATHS.SUPPORT}
|
path={Constants.ROUTE_PATHS.SUPPORT}
|
||||||
element={
|
element={
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
export default function MyCenteredContainer({ children }) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "98.3vh",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,23 +1,14 @@
|
||||||
import { Spin } from "antd";
|
import { Spin } from "antd";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
|
import MyCenteredContainer from "../MyContainer";
|
||||||
|
|
||||||
export function MySupsenseFallback({ children }) {
|
export function MySupsenseFallback({ children }) {
|
||||||
return (
|
return (
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<div
|
<MyCenteredContainer>
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
textAlign: "center",
|
|
||||||
height: "98.3vh",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin size="large" />
|
<Spin size="large" />
|
||||||
</div>
|
</MyCenteredContainer>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { Button, Result, Spin } from "antd";
|
||||||
|
import { Link, useParams, useNavigate } from "react-router-dom";
|
||||||
|
import { Constants, myFetch } from "../../../../utils";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import MyCenteredContainer from "../../../../Components/MyContainer";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { MySupsenseFallback } from "../../../../Components/MySupsenseFallback";
|
||||||
|
|
||||||
|
export default function StoreCalendarAuth() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { status } = useParams();
|
||||||
|
|
||||||
|
const [isRequesting, setIsRequesting] = useState(true);
|
||||||
|
const [storeId, setStoreId] = useState("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsRequesting(true);
|
||||||
|
|
||||||
|
myFetch("/calendar/store", "GET")
|
||||||
|
.then((res) => {
|
||||||
|
setIsRequesting(false);
|
||||||
|
setStoreId(res.storeId);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
|
if (isRequesting) {
|
||||||
|
return (
|
||||||
|
<MyCenteredContainer>
|
||||||
|
<Spin size="large" />
|
||||||
|
</MyCenteredContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status={status === "finish" ? "success" : "error"}
|
||||||
|
title={
|
||||||
|
status === "finish"
|
||||||
|
? t("calendar.authFinish.title")
|
||||||
|
: t("calendar.authFailed.title")
|
||||||
|
}
|
||||||
|
subTitle={
|
||||||
|
status === "finish"
|
||||||
|
? t("calendar.authFinish.description")
|
||||||
|
: t("calendar.authFailed.description")
|
||||||
|
}
|
||||||
|
extra={[
|
||||||
|
<div key="1">
|
||||||
|
<Link to={`${Constants.ROUTE_PATHS.STORE.CALENDAR}/${storeId}`}>
|
||||||
|
<Button>
|
||||||
|
{status === "finish"
|
||||||
|
? t("calendar.authFinish.button")
|
||||||
|
: t("calendar.authFailed.button")}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{status === "finish" && <CountdownRedirect storeId={storeId} />}
|
||||||
|
</div>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CountdownRedirect({ storeId }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [count, setCount] = useState(5);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (count > 0) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setCount(count - 1);
|
||||||
|
}, 1000);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
} else {
|
||||||
|
navigate(`${Constants.ROUTE_PATHS.STORE.CALENDAR}/${storeId}`);
|
||||||
|
}
|
||||||
|
}, [count, navigate]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p style={{ paddingTop: 10, color: "#8c8c8c" }}>
|
||||||
|
{t("calendar.authFinish.countDownRedirect", { countDown: count })}
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ export const Constants = {
|
||||||
EMPLOYEES: "/store/employees",
|
EMPLOYEES: "/store/employees",
|
||||||
SERVICES: "/store/services",
|
SERVICES: "/store/services",
|
||||||
CALENDAR: "/store/calendar",
|
CALENDAR: "/store/calendar",
|
||||||
|
CALENDAR_AUTH: "/store/calendar/auth",
|
||||||
},
|
},
|
||||||
FEEDBACK: "/feedback",
|
FEEDBACK: "/feedback",
|
||||||
SUPPORT: "/support",
|
SUPPORT: "/support",
|
||||||
|
|
Loading…
Reference in New Issue