payment plan settings
parent
cf0b173ab7
commit
dac70b358a
|
@ -126,7 +126,9 @@
|
|||
},
|
||||
"support": "Unterstützung",
|
||||
"feedback": "Feedback",
|
||||
"paymentPlan": "Zahlungsplan"
|
||||
"paymentPlan": "Zahlungsplan",
|
||||
"paymentPlanTrailingDaysLeft": "{{daysLeft}} {{dayUnit}} verbleibend",
|
||||
"paymentPlanUpgradeButton": "Jetzt upgraden"
|
||||
},
|
||||
"employees": {
|
||||
"pageTitle": "Mitarbeiter",
|
||||
|
@ -184,7 +186,6 @@
|
|||
"choosenProduct": {
|
||||
"title": "Ausgewähltes Produkt",
|
||||
"products": [
|
||||
{},
|
||||
{
|
||||
"price": "9,99 € / Monat",
|
||||
"featuresCount": 9,
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
"hour": "hour",
|
||||
"minutes": "minutes",
|
||||
"minute": "minute",
|
||||
"days": "Days",
|
||||
"day": "Day",
|
||||
"days": "days",
|
||||
"day": "day",
|
||||
"separator": "and"
|
||||
},
|
||||
"failed": "Failed",
|
||||
|
@ -126,7 +126,9 @@
|
|||
},
|
||||
"support": "Support",
|
||||
"feedback": "Feedback",
|
||||
"paymentPlan": "Payment plan"
|
||||
"paymentPlan": "Payment plan",
|
||||
"paymentPlanTrailingDaysLeft": "{{daysLeft}} {{dayUnit}} left",
|
||||
"paymentPlanUpgradeButton": "Upgrade now"
|
||||
},
|
||||
"employees": {
|
||||
"pageTitle": "Employees",
|
||||
|
@ -184,7 +186,6 @@
|
|||
"choosenProduct": {
|
||||
"title": "Choosen product",
|
||||
"products": [
|
||||
{},
|
||||
{
|
||||
"price": "9,99 € / month",
|
||||
"featuresCount": 9,
|
||||
|
|
|
@ -132,6 +132,9 @@ export function App() {
|
|||
options={{
|
||||
username: appUserData.user.username,
|
||||
permissions: appUserData.permissions,
|
||||
paymentPlanStatus: appUserData.user.payment_plan_status,
|
||||
paymentPlanTrialEnd: appUserData.user.payment_plan_trial_end,
|
||||
paymentPlanCanceledAt: appUserData.user.payment_plan_canceled_at,
|
||||
}}
|
||||
>
|
||||
<UserProfileProvider>
|
||||
|
@ -139,6 +142,7 @@ export function App() {
|
|||
<AppProvider
|
||||
options={{
|
||||
paymentPlan: appUserData.user.payment_plan,
|
||||
paymentPlanSettings: appUserData.paymentPlanSettings,
|
||||
}}
|
||||
>
|
||||
<StoresProvider options={{ stores: appUserData.stores }}>
|
||||
|
|
|
@ -134,10 +134,7 @@ export function MyCalendarMaxFutureBookingDaysFormInput({
|
|||
<MyFormInput
|
||||
formItemName={formItemName}
|
||||
minLength={Constants.GLOBALS.MIN_CALENDAR_FUTURE_BOOKING_DAYS}
|
||||
maxLength={
|
||||
Constants.PAYMENT_PLAN[appContext.paymentPlan]
|
||||
.calendarMaxFutureBookingDays
|
||||
}
|
||||
maxLength={appContext.paymentPlanSettings.maxEmployees}
|
||||
label={t("common.calendarMaxFutureBookingDays")}
|
||||
ruleMessageValueRequired={t(
|
||||
"common.inputRules.calendarMaxFutureBookingDaysRequired"
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
UserOutlined,
|
||||
WalletOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Divider, Menu } from "antd";
|
||||
import { Button, Card, Divider, Flex, Menu, Typography } from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { BreakpointLgWidth, Constants, isDevelopmentEnv } from "../../utils";
|
||||
|
@ -100,6 +100,12 @@ export function SideMenuContent({
|
|||
return items;
|
||||
};
|
||||
|
||||
const showPaymentPlanInfoBanner =
|
||||
sideBarContext.permissions.includes("paymentPlan") &&
|
||||
sideBarContext.paymentPlanStatus === "trialing" &&
|
||||
sideBarContext.paymentPlanTrialEnd !== null &&
|
||||
sideBarContext.paymentPlanCanceledAt !== null;
|
||||
|
||||
const getSecondMenuItems = () => {
|
||||
let items = [];
|
||||
|
||||
|
@ -118,7 +124,7 @@ export function SideMenuContent({
|
|||
);
|
||||
}
|
||||
|
||||
if (sideBarContext.permissions.includes("paymentPlan")) {
|
||||
if (!showPaymentPlanInfoBanner) {
|
||||
items.push({
|
||||
label: t("sideMenu.paymentPlan"),
|
||||
icon: <WalletOutlined />,
|
||||
|
@ -162,6 +168,17 @@ export function SideMenuContent({
|
|||
}
|
||||
}, [location.pathname]);
|
||||
|
||||
const calculateExpiry = () => {
|
||||
const currentDate = new Date();
|
||||
const expiryDate = new Date(sideBarContext.paymentPlanTrialEnd * 1000);
|
||||
const diffTime = Math.abs(expiryDate - currentDate);
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
return diffDays;
|
||||
};
|
||||
|
||||
const accountPlanExpiry = calculateExpiry();
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
@ -216,6 +233,36 @@ export function SideMenuContent({
|
|||
<div>
|
||||
<Divider style={{ margin: 0 }} />
|
||||
|
||||
{showPaymentPlanInfoBanner && (
|
||||
<Card
|
||||
style={{ backgroundColor: "#6878d6", margin: 8 }}
|
||||
styles={{ body: { padding: 10 } }}
|
||||
>
|
||||
<Flex justify="center" align="center">
|
||||
<Typography.Title
|
||||
level={5}
|
||||
style={{ color: "#fff", textAlign: "center" }}
|
||||
>
|
||||
{t("sideMenu.paymentPlanTrailingDaysLeft", {
|
||||
daysLeft: accountPlanExpiry,
|
||||
dayUnit:
|
||||
accountPlanExpiry > 1
|
||||
? t("common.unit.days")
|
||||
: t("common.unit.day"),
|
||||
})}
|
||||
</Typography.Title>
|
||||
</Flex>
|
||||
|
||||
<Button
|
||||
block
|
||||
style={{ fontWeight: "bold", fontSize: 13 }}
|
||||
onClick={() => navigate(Constants.ROUTE_PATHS.PAYMENT_PLAN)}
|
||||
>
|
||||
{t("sideMenu.paymentPlanUpgradeButton")}
|
||||
</Button>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<Menu
|
||||
selectable={true}
|
||||
selectedKeys={[selectedKeys]}
|
||||
|
|
|
@ -3,6 +3,12 @@ import { createContext, useContext, useState } from "react";
|
|||
const preview = {
|
||||
paymentPlan: "",
|
||||
setPaymentPlan: () => {},
|
||||
paymentPlanSettings: {
|
||||
name: "",
|
||||
maxEmployees: 0,
|
||||
calendarMaxFutureBookingDays: 0,
|
||||
},
|
||||
setPaymentPlanSettings: () => {},
|
||||
};
|
||||
|
||||
const AppContext = createContext(preview);
|
||||
|
@ -11,12 +17,17 @@ export const useAppContext = () => useContext(AppContext);
|
|||
|
||||
export function AppProvider({ children, options }) {
|
||||
const [paymentPlan, setPaymentPlan] = useState(options.paymentPlan);
|
||||
const [paymentPlanSettings, setPaymentPlanSettings] = useState(
|
||||
options.paymentPlanSettings
|
||||
);
|
||||
|
||||
return (
|
||||
<AppContext.Provider
|
||||
value={{
|
||||
paymentPlan,
|
||||
setPaymentPlan,
|
||||
paymentPlanSettings,
|
||||
setPaymentPlanSettings,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -5,8 +5,12 @@ const preview = {
|
|||
setUsername: () => {},
|
||||
permissions: [],
|
||||
setPermissions: () => {},
|
||||
accountPlanExpiry: "",
|
||||
setAccountPlanExpiry: () => {},
|
||||
paymentPlanStatus: "",
|
||||
setPaymentPlanStatus: () => {},
|
||||
paymentPlanTrialEnd: "",
|
||||
setPaymentPlanTrialEnd: () => {},
|
||||
paymentPlanCanceledAt: "",
|
||||
setPaymentPlanCanceledAt: () => {},
|
||||
};
|
||||
|
||||
const SideBarContext = createContext(preview);
|
||||
|
@ -16,8 +20,14 @@ export const useSideBarContext = () => useContext(SideBarContext);
|
|||
export default function SideBarProvider({ children, options }) {
|
||||
const [username, setUsername] = useState(options.username);
|
||||
const [permissions, setPermissions] = useState(options.permissions);
|
||||
const [accountPlanExpiry, setAccountPlanExpiry] = useState(
|
||||
options.accountPlanExpiry
|
||||
const [paymentPlanStatus, setPaymentPlanStatus] = useState(
|
||||
options.paymentPlanStatus
|
||||
);
|
||||
const [paymentPlanTrialEnd, setPaymentPlanTrialEnd] = useState(
|
||||
options.paymentPlanTrialEnd
|
||||
);
|
||||
const [paymentPlanCanceledAt, setPaymentPlanCanceledAt] = useState(
|
||||
options.paymentPlanCanceledAt
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -27,8 +37,12 @@ export default function SideBarProvider({ children, options }) {
|
|||
setUsername,
|
||||
permissions,
|
||||
setPermissions,
|
||||
accountPlanExpiry,
|
||||
setAccountPlanExpiry,
|
||||
paymentPlanStatus,
|
||||
setPaymentPlanStatus,
|
||||
paymentPlanTrialEnd,
|
||||
setPaymentPlanTrialEnd,
|
||||
paymentPlanCanceledAt,
|
||||
setPaymentPlanCanceledAt,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -34,6 +34,7 @@ import { MyRecaptcha, PrivacyPolicyCheckbox } from ".";
|
|||
import MyAppLogo from "../../Components/MyAppLogo";
|
||||
import { CheckOutlined } from "@ant-design/icons";
|
||||
import { RequestState } from "../../Components/MyRequestStateItem";
|
||||
import { useAppContext } from "../../Contexts/AppContext";
|
||||
/*
|
||||
const SignUpStep = {
|
||||
SIGN_UP: 1,
|
||||
|
@ -131,6 +132,10 @@ function AccountDetails({ t, form }) {
|
|||
}
|
||||
|
||||
export function ChoosenProduct({ t, paymentPlan, extra }) {
|
||||
const appContext = useAppContext();
|
||||
|
||||
console.log(appContext.paymentPlanSettings);
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={t("authentication.signUp.choosenProduct.title")}
|
||||
|
@ -138,7 +143,7 @@ export function ChoosenProduct({ t, paymentPlan, extra }) {
|
|||
extra={extra}
|
||||
>
|
||||
<Typography.Title level={2}>
|
||||
{Constants.APP_NAME} - {Constants.PAYMENT_PLAN[paymentPlan].name}
|
||||
{Constants.APP_NAME} - {appContext.paymentPlanSettings.name}
|
||||
</Typography.Title>
|
||||
<Divider />
|
||||
|
||||
|
@ -173,6 +178,7 @@ export function ChoosenProduct({ t, paymentPlan, extra }) {
|
|||
|
||||
function CostSummary({ notificationApi, paymentPlan, form }) {
|
||||
const { t, i18n } = useTranslation();
|
||||
const appContext = useAppContext();
|
||||
|
||||
const [isRequesting, setIsRequesting] = useState(RequestState.INIT);
|
||||
const recaptchaRef = useRef(null);
|
||||
|
@ -290,7 +296,7 @@ function CostSummary({ notificationApi, paymentPlan, form }) {
|
|||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
{Constants.APP_NAME} - {Constants.PAYMENT_PLAN[paymentPlan].name}
|
||||
{Constants.APP_NAME} - {appContext.paymentPlanSettings.name}
|
||||
</div>
|
||||
<Flex justify="space-between">
|
||||
<Typography.Text style={{ fontSize: 16 }}>
|
||||
|
|
|
@ -183,7 +183,7 @@ export default function StoreEmployees() {
|
|||
setModalOptions={setAddEditEmployeeModalOptions}
|
||||
fetchEmployees={fetchEmployees}
|
||||
disabled={
|
||||
Constants.PAYMENT_PLAN[appContext.paymentPlan].maxEmployees <=
|
||||
appContext.paymentPlanSettings.maxEmployees <=
|
||||
requestData.employees.length
|
||||
}
|
||||
/>
|
||||
|
|
17
src/utils.js
17
src/utils.js
|
@ -110,23 +110,6 @@ export const Constants = {
|
|||
INIT_PAYMENT: 5,
|
||||
},
|
||||
SUPPORT_EMAIL: process.env.REACT_APP_SUPPORT_EMAIL,
|
||||
PAYMENT_PLAN: [
|
||||
{
|
||||
name: "Demo",
|
||||
maxEmployees: 5,
|
||||
calendarMaxFutureBookingDays: 14,
|
||||
},
|
||||
{
|
||||
name: "Basic",
|
||||
maxEmployees: 15,
|
||||
calendarMaxFutureBookingDays: 60,
|
||||
},
|
||||
{
|
||||
name: "Premium",
|
||||
maxEmployees: 50, // temporary
|
||||
calendarMaxFutureBookingDays: 365, // temporary
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function isEmailValid(email) {
|
||||
|
|
Loading…
Reference in New Issue