save user settings

master
alex 2024-01-26 16:03:40 +01:00
parent c958e0cb2f
commit c2b17ddae3
9 changed files with 156 additions and 57 deletions

6
package-lock.json generated
View File

@ -22,6 +22,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.0.1",
"react-microsoft-clarity": "^1.2.0",
"react-qr-scanner": "^1.0.0-alpha.11",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",
@ -18687,6 +18688,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-microsoft-clarity": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/react-microsoft-clarity/-/react-microsoft-clarity-1.2.0.tgz",
"integrity": "sha512-a1bsJR1uN1daWq3cBc7NheEGPXrotMRE0oFeRio7kXvHawzQfqu5iX9BoYFF9zRUL0dn+Mz57h1fNlcv3pqXEg=="
},
"node_modules/react-qr-scanner": {
"version": "1.0.0-alpha.11",
"resolved": "https://registry.npmjs.org/react-qr-scanner/-/react-qr-scanner-1.0.0-alpha.11.tgz",

View File

@ -17,6 +17,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.0.1",
"react-microsoft-clarity": "^1.2.0",
"react-qr-scanner": "^1.0.0-alpha.11",
"react-router-dom": "^6.10.0",
"react-scripts": "5.0.1",

View File

@ -29,19 +29,4 @@
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
<script type="text/javascript">
(function (c, l, a, r, i, t, y) {
c[a] =
c[a] ||
function () {
(c[a].q = c[a].q || []).push(arguments);
};
t = l.createElement(r);
t.async = 1;
t.src = "https://www.clarity.ms/tag/" + i;
y = l.getElementsByTagName(r)[0];
y.parentNode.insertBefore(t, y);
})(window, document, "clarity", "script", "kr0pale8uy");
</script>
</html>

View File

@ -229,6 +229,8 @@
},
"userProfile": {
"title": "Ihr Profil",
"language": "Sprache"
"language": "Sprache",
"analytics": "Analytik",
"analyticsDescription": "Dazu gehören Informationen über die Nutzung unseres Dashboards, wie die besuchten Seiten, die Verweildauer auf den Seiten und die allgemeine Interaktion mit den Seiten. Dies hilft uns, unser Dashboard zu verbessern und es benutzerfreundlicher zu gestalten."
}
}

View File

@ -232,6 +232,8 @@
},
"userProfile": {
"title": "Your profile",
"language": "Language"
"language": "Language",
"analytics": "Analytics",
"analyticsDescription": "This includes information about the use of our dashboard, such as the visited pages, the length of stay on the pages and the general interaction with the pages. This helps us to improve our dashboard and make it more user-friendly."
}
}

View File

@ -2,7 +2,7 @@ import "antd/dist/reset.css";
import "./App.css";
import Login from "./Pages/Login";
import { Layout, Spin } from "antd";
import { UseUserSession, myFetch } from "./utils";
import { Constants, UseUserSession, myFetch } from "./utils";
import DashboardLayout from "./Components/DashboardLayout";
import SideBarProvider from "./Contexts/SideBarContext";
import { AppProvider } from "./Contexts/AppContext";
@ -11,6 +11,7 @@ import { UsersProvider } from "./Contexts/UsersContext";
import HeaderProvider from "./Contexts/HeaderContext";
import { useEffect, useState } from "react";
import StoresProvider from "./Contexts/StoresContext";
import { clarity } from "react-microsoft-clarity";
export default function App() {
/*const [notificationApi, notificationContextHolder] =
@ -30,6 +31,10 @@ export default function App() {
})
.then((data) => {
setAppUserData(data);
if (data.user.analytics_enabled) {
clarity.init(Constants.CLARITY_PROJECT_ID);
}
})
.catch(() => {
setUserSession();

View File

@ -19,7 +19,7 @@ export default function StoreSettings() {
const [isRequesting, setIsRequesting] = useState(true);
const [requestState, setRequestState] = useState(RequestState.INIT);
const [storeData, setStoreData] = useState({});
//const [storeData, setStoreData] = useState({});
const delayTimeout = useRef();
const companyName = Form.useWatch("companyName", form);
@ -35,7 +35,7 @@ export default function StoreSettings() {
t: t,
})
.then((data) => {
setStoreData(data.store);
// setStoreData(data.store);
form.setFieldsValue({
companyName: data.store.name,

View File

@ -1,14 +1,86 @@
import { Button, Card, Select, Typography, notification } from "antd";
import {
Button,
Card,
Checkbox,
Form,
Select,
Skeleton,
Space,
Switch,
Typography,
notification,
} from "antd";
import { myFetch } from "../../utils";
import { useTranslation } from "react-i18next";
import { useState } from "react";
import { useEffect, useRef, useState } from "react";
import {
RequestState,
RequestStateItem,
} from "../../Components/MyRequestStateItem";
export default function UserProfile({ setUserSession }) {
const { t, i18n } = useTranslation();
const [notificationApi, notificationContextHolder] =
notification.useNotification();
const [form] = Form.useForm();
const [requestState, setRequestState] = useState(RequestState.INIT);
const [isRequestingLogout, setIsRequestingLogout] = useState(false);
const delayTimeout = useRef();
const language = Form.useWatch("language", form);
const analytics = Form.useWatch("analytics", form);
useEffect(() => {
myFetch({
url: "/user/profile/settings",
method: "GET",
notificationApi: notificationApi,
t: t,
})
.then((data) => {
form.setFieldsValue({
language: data.language,
analytics: data.analytics_enabled,
});
})
.catch((errStatus) => {
console.log(errStatus);
});
}, []);
useEffect(() => {
if (language === undefined || analytics === undefined) return;
if (RequestState.INIT === requestState) {
setRequestState(RequestState.NOTHING);
return;
}
setRequestState(RequestState.REQUESTING);
if (delayTimeout.current) {
clearTimeout(delayTimeout.current);
}
delayTimeout.current = setTimeout(() => {
myFetch({
url: "/user/profile/settings",
method: "POST",
body: {
language: language,
analyticsEnabled: analytics,
},
notificationApi: notificationApi,
t: t,
})
.then(() => setRequestState(RequestState.SUCCESS))
.catch((errStatus) => {
console.log(errStatus);
setRequestState(RequestState.FAILED);
});
}, 500);
}, [language, analytics]);
return (
<>
@ -17,46 +89,71 @@ export default function UserProfile({ setUserSession }) {
<Card
title={t("userProfile.title")}
extra={
<Button
type="primary"
loading={isRequestingLogout}
onClick={() => {
setIsRequestingLogout(true);
<Space>
<RequestStateItem
state={requestState}
setRequestState={setRequestState}
/>
myFetch({
url: "/user/auth/logout",
method: "DELETE",
notificationApi: notificationApi,
t: t,
})
.then(() => {
setUserSession();
window.location.href = "/";
<Button
type="primary"
loading={isRequestingLogout}
onClick={() => {
setIsRequestingLogout(true);
myFetch({
url: "/user/auth/logout",
method: "DELETE",
notificationApi: notificationApi,
t: t,
})
.catch(() => setIsRequestingLogout(false));
}}
>
{t("common.button.logout")}
</Button>
.then(() => {
setUserSession();
window.location.href = "/";
})
.catch(() => setIsRequestingLogout(false));
}}
>
{t("common.button.logout")}
</Button>
</Space>
}
>
<Typography.Paragraph>{t("userProfile.language")}</Typography.Paragraph>
<Form layout="horizontal" form={form}>
<Form.Item name="language" label={t("userProfile.language")}>
{requestState === RequestState.INIT ? (
<Skeleton.Input active block></Skeleton.Input>
) : (
<Select
style={{ width: "100%" }}
options={[
{
value: "en",
label: "English",
},
{
value: "de",
label: "Deutsch",
},
]}
onChange={(e) => i18n.changeLanguage(e)}
/>
)}
</Form.Item>
<Select
style={{ width: "100%" }}
defaultValue={i18n.language}
options={[
{
value: "en",
label: "English",
},
{
value: "de",
label: "Deutsch",
},
]}
onChange={(e) => i18n.changeLanguage(e)}
/>
<Form.Item
name="analytics"
valuePropName="checked"
label={t("userProfile.analytics")}
extra={t("userProfile.analyticsDescription")}
>
{requestState === RequestState.INIT ? (
<Skeleton.Button shape="round" active />
) : (
<Switch>{t("userProfile.analytics")}</Switch>
)}
</Form.Item>
</Form>
</Card>
</>
);

View File

@ -70,6 +70,7 @@ export const Constants = {
MAX_CALENDAR_EARLIEST_BOOKING_TIME: 60 * 24, // 24 hours in minutes
},
DELAY_ACCOUNT_NAME_CHECK: 250,
CLARITY_PROJECT_ID: "kr0pale8uy",
};
export const AppStyle = {