customer-dashboard/src/utils.js

367 lines
9.7 KiB
JavaScript

import { useState } from "react";
import { Buffer } from "buffer";
import { v4 as uuidv4 } from "uuid";
/**
* constants
*/
//const wssProtocol = window.location.protocol === "https:" ? "wss://" : "ws://";
let dashboardAddress = "";
let apiAddress = "";
// let staticContentAddress = "";
// let wsAddress = "";
if (window.location.hostname === "localhost" && window.location.port === "") {
// for docker container testing on localhost
dashboardAddress = "http://localhost/";
apiAddress = "http://localhost/api/v1";
// staticContentAddress = "http://localhost/api/";
// wsAddress = "ws://localhost/ws";
} else if (window.location.hostname === "localhost") {
// programming on localhost
dashboardAddress = `http://localhost:${window.location.port}/`;
apiAddress = "http://localhost:50128/api/v1";
// staticContentAddress = "http://localhost:50050/";
// wsAddress = "ws://localhost:50050/ws";
} else {
// production
dashboardAddress = `${window.location.protocol}//${window.location.hostname}/`;
apiAddress = `${window.location.protocol}//${window.location.hostname}/api/v1`;
//staticContentAddress = `${window.location.protocol}//${window.location.hostname}/api/`;
// wsAddress = `${wssProtocol}${window.location.hostname}/ws`;
}
export const Constants = {
APP_NAME: "ZeitAdler",
TEXT_EMPTY_PLACEHOLDER: "-/-",
DASHBOARD_ADDRESS: dashboardAddress,
API_ADDRESS: apiAddress,
//STATIC_CONTENT_ADDRESS: staticContentAddress,
// WS_ADDRESS: wsAddress,
EMBED_CALENDAR_ADDRESS: process.env.REACT_APP_EMBED_CALENDAR_ADDRESS,
EMBED_CALENDAR_SCRIPT_ADDRESS:
process.env.REACT_APP_EMBED_CALENDAR_SCRIPT_ADDRESS,
PRIVACY_POLICY_URL: process.env.REACT_APP_PRIVACY_POLICY_URL,
ROUTE_PATHS: {
AUTHENTICATION: {
LOGIN: "/login",
SIGN_UP: "/buy",
FORGOT_PASSWORD: "/forgot-password",
CHECKOUT_SUCCESS: "/checkout/success",
CHECKOUT_CANCELED: "/checkout/canceled",
},
VERIFY: "/verify",
OVERVIEW: "/",
STORE: {
// schema: /store/:storeId/:subPage
OVERVIEW: "/store",
SETTINGS: "settings",
EMPLOYEES: "employees",
SERVICES: "services",
CALENDAR: "calendar",
CALENDAR_AUTH: "calendar/auth",
},
PAYMENT_PLAN: "payment-plan",
FEEDBACK: "/feedback",
SUPPORT: "/support",
USER_PROFILE: "/user-profile",
},
GLOBALS: {
MIN_USERNAME_LENGTH: 3,
MAX_USERNAME_LENGTH: 20,
//MIN_ACCOUNT_NAME_LENGTH: 3,
//MAX_ACCOUNT_NAME_LENGTH: 20,
MIN_EMAIL_LENGTH: 3,
MAX_EMAIL_LENGTH: 64,
EMAIL_REGEX: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/,
MIN_PASSWORD_LENGTH: 8,
MAX_PASSWORD_LENGTH: 64,
MIN_STORE_SERVICE_NAME_LENGTH: 3,
MAX_STORE_SERVICE_NAME_LENGTH: 64,
MIN_STORE_SERVICE_ACTIVITY_NAME_LENGTH: 3,
MAX_STORE_SERVICE_ACTIVITY_NAME_LENGTH: 64,
MAX_STORE_SERVICE_ACTIVITY_DESCRIPTION_LENGTH: 1024,
MIN_STORE_SERVICE_ACTIVITY_PRICE: 0,
MAX_STORE_SERVICE_ACTIVITY_PRICE: 10000000,
MIN_STORE_SERVICE_ACTIVITY_DURATION_MINUTES: 0,
MAX_STORE_SERVICE_ACTIVITY_DURATION_MINUTES: 60 * 24, // 24 hours in minutes
MIN_CALENDAR_FUTURE_BOOKING_DAYS: 1,
MIN_CALENDAR_EARLIEST_BOOKING_TIME: 15,
MAX_CALENDAR_EARLIEST_BOOKING_TIME: 60 * 24, // 24 hours in minutes
MIN_FEEDBACK_LENGTH: 10,
MAX_FEEDBACK_LENGTH: 1024,
MIN_COMPANY_NAME_LENGTH: 3,
MAX_COMPANY_NAME_LENGTH: 64,
},
DELAY_EMAIL_CHECK: 250,
CLARITY_PROJECT_ID: process.env.REACT_APP_CLARITY_PROJECT_ID,
ACCOUNT_DELETED_AFTER_DAYS: 30,
ACCOUNT_STATE: {
ACTIVE: 0,
PENDING_DELETION: 1,
INIT_LOGGING: 2,
BANNED: 3,
PENDING_EMAIL_VERIFICATION: 4,
},
SUPPORT_EMAIL: process.env.REACT_APP_SUPPORT_EMAIL,
PAYMENT_PLAN: [
{
name: "Demo",
maxEmployees: 5,
calendarMaxFutureBookingDays: 14,
},
{
name: "Basic",
maxEmployees: 15,
calendarMaxFutureBookingDays: 60,
price: {
en: {
totalNet: "9,99 €", // netto
vat: "1,90 €",
totalAmount: "11,89 €", // brutto
},
de: {
totalNet: "9,99 €",
vat: "1,90 €",
totalAmount: "11,89 €",
},
},
},
{
name: "Premium",
maxEmployees: 50, // temporary
calendarMaxFutureBookingDays: 365, // temporary
price: {
en: {
totalNet: "24,99 €",
vat: "4,75 €",
totalAmount: "29,74 €",
},
de: {
totalNet: "24,99 €",
vat: "4,75 €",
totalAmount: "29,74 €",
},
},
},
],
};
export function isEmailValid(email) {
return Constants.GLOBALS.EMAIL_REGEX.test(email);
}
export const AppStyle = {
app: {
margin: 12,
},
colors: {
primary: "#6878d6",
},
};
export function GetUuid() {
return uuidv4();
}
/**
* user session
*/
export function UseUserSession() {
const getUserSession = () => {
return getUserSessionFromLocalStorage();
};
const [userSession, setUserSession] = useState(getUserSession());
const saveUserSession = (session) => {
setUserSession(session);
if (session === undefined) {
localStorage.removeItem("session");
} else {
setUserSessionToLocalStorage(session);
}
};
return {
setUserSession: saveUserSession,
userSession,
};
}
export function getUserSessionFromLocalStorage() {
return localStorage.getItem("session");
}
export function setUserSessionToLocalStorage(session) {
localStorage.setItem("session", session);
}
// needed for a user who uses multiple tabs in the browser
// with the same session id because otherwise the last browser
// tab would subscribe to the topic and the other tabs would
// not receive any messages
// used for topic subscribtion and grouptasks
export const BrowserTabSession = GetUuid();
export const wsConnectionCustomEventName = "wsConnection";
// used for sideMenu
export const BreakpointLgWidth = 992;
export function EncodeStringToBase64(value) {
return Buffer.from(value).toString("base64");
}
export function DecodedBase64ToString(value) {
return Buffer.from(value, "base64").toString();
}
export const myFetchContentType = {
JSON: 0,
MULTIPART_FORM_DATA: 1,
};
export function myFetch({
url,
method,
body = null,
headers = {},
contentType = myFetchContentType.JSON,
fetchUrl = Constants.API_ADDRESS,
ignoreUnauthorized = false,
notificationApi = null,
t = null,
}) {
const getContentType = () => {
if (contentType === myFetchContentType.JSON) return "application/json";
return "multipart/form-data";
};
const getBody = () => {
if (!body) return null;
if (contentType === myFetchContentType.JSON) return JSON.stringify(body);
return body;
};
// abort fetch if it takes to long
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 30000); // 30 seconds
const requestOptions = {
method: method,
headers: {
"X-Authorization": getUserSessionFromLocalStorage(),
"Content-Type": getContentType(),
...headers,
},
body: getBody(),
signal: signal,
};
if (fetchUrl === "") {
fetchUrl = Constants.API_ADDRESS;
}
return fetch(`${fetchUrl}${url}`, requestOptions)
.then((response) => {
// if status is not in range 200-299
if (!response.ok) {
if (!ignoreUnauthorized && response.status === 401) {
console.error("Unauthorized");
// TODO: check here
//setUserSessionToLocalStorage("");
//window.location.href = "/";
}
throw response.status;
}
// check if response is json
if (response.headers.get("content-type")?.includes("application/json")) {
return response.json();
}
return response.text();
})
.catch((error) => {
// ignore errors here as they are handled in the components
if (error === 400) throw error;
if (error === 401) {
handleLogout({
setUserSession: setUserSessionToLocalStorage,
});
return;
}
// show error notification for all other errors
if (notificationApi !== null && t !== null) {
if (error === 500) {
notificationApi["error"]({
message: t("common.request.failed.title"),
description: t("common.request.failed.description"),
});
} else {
// other errors
notificationApi["error"]({
message: t("common.request.failedInternetProblem.title"),
description: t("common.request.failedInternetProblem.description"),
});
}
}
throw error;
});
}
export function isDevelopmentEnv() {
return process.env.NODE_ENV === "development";
}
export function showInputsInvalidNotification(notificationApi, t) {
notificationApi["warning"]({
message: t("common.request.inputsInvalid.title"),
description: t("common.request.inputsInvalid.description"),
});
}
export function showPasswordIncorrectNotification(notificationApi, t) {
notificationApi["warning"]({
message: t("common.request.passwordIncorrect.title"),
description: t("common.request.passwordIncorrect.description"),
});
}
export function showUnkownErrorNotification(notificationApi, t) {
notificationApi["error"]({
message: t("common.request.unknownError.title"),
description: t("common.request.unknownError.description"),
});
}
export function handleLogout({ setUserSession }) {
console.log("handleLogout");
if (setUserSession !== undefined) setUserSession();
window.location.href = Constants.ROUTE_PATHS.AUTHENTICATION.LOGIN;
}
export function FormatDatetime(datetime) {
if (datetime === undefined || datetime === "0001-01-01T00:00:00Z") {
return Constants.TEXT_EMPTY_PLACEHOLDER;
}
return new Date(datetime).toLocaleString("de-DE");
}