auth screens

master
alex 2024-01-14 19:25:19 +01:00
parent 8a027eb403
commit 41d81e8f13
7 changed files with 147 additions and 17 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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>
</>
);
}

View File

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