IO-3020 IO-3036 Add upsell components to several components. Add upsell mask wrapper.

This commit is contained in:
Patrick Fic
2024-12-06 14:24:03 -08:00
parent 77e966dfe1
commit eaea73a955
25 changed files with 3001 additions and 2265 deletions

View File

@@ -1,8 +1,9 @@
import { AppstoreAddOutlined } from "@ant-design/icons";
import { Result } from "antd";
import { AppstoreAddOutlined, CalendarOutlined, CarOutlined, MobileOutlined } from "@ant-design/icons";
import { Result, Button, Card } from "antd";
import React, { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import upsellEnum from "./upsell.enum";
import i18n from "i18next";
import "./upsell.styles.scss";
export default function UpsellComponent({ featureName, subFeatureName, upsell, disableMask = false }) {
const { t } = useTranslation();
@@ -19,16 +20,17 @@ export default function UpsellComponent({ featureName, subFeatureName, upsell, d
mask.style.left = 0;
mask.style.width = "100%";
mask.style.height = "100%";
mask.style.backgroundColor = "rgba(0, 0, 0, 0.25)";
mask.style.zIndex = 9999;
mask.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
// mask.style.zIndex = 9999;
parentElement.style.position = "relative";
parentElement.appendChild(mask);
parentElement.prepend(mask);
return () => {
parentElement.removeChild(mask);
};
}
}, []);
}, [disableMask]);
if (!resultProps) return <Result status="info" title={t("upsell.messages.generic")} />;
return (
@@ -37,3 +39,102 @@ export default function UpsellComponent({ featureName, subFeatureName, upsell, d
</div>
);
}
//Kept in the same function as the result props line must mirror and doesnt warrant a separate function.
export function UpsellMaskWrapper({ children, upsell, featureName, subFeatureName, disableMask = false }) {
const resultProps = upsell || upsellEnum[featureName][subFeatureName];
return (
<div className="mask-wrapper">
<div className="mask-content">{children}</div>
<div className="mask-overlay">
<Card size="small">
<Result status="info" icon={<AppstoreAddOutlined />} {...resultProps} />
</Card>
</div>
</div>
);
}
//This is kept in this function as pulling it out into it's own util/enum prevents passing JSX as an `extra` prop
export const upsellEnum = {
bills: {
autoreconcile: {
//icon: null,
title: i18n.t("upsell.messages.bills.autoreconcile.title"),
subTitle: i18n.t("upsell.messages.bills.autoreconcile.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null
},
general: {
//icon: null,
title: i18n.t("upsell.messages.bills.general.title"),
subTitle: i18n.t("upsell.messages.bills.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null
}
},
audit: {
general: {
//icon: null,
title: i18n.t("upsell.messages.audit.general.title"),
subTitle: i18n.t("upsell.messages.audit.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null
}
},
lifecycle: {
general: {
//icon: null,
title: i18n.t("upsell.messages.lifecycle.general.title"),
subTitle: i18n.t("upsell.messages.lifecycle.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null }
}
},
media: {
general: {
//icon: null,
title: i18n.t("upsell.messages.media.general.title"),
subTitle: i18n.t("upsell.messages.media.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null }
},
mobile: {
icon: <MobileOutlined />,
title: i18n.t("upsell.messages.media.mobile.title"),
subTitle: i18n.t("upsell.messages.media.mobile.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
//status: null }
}
},
timetickets: {
allocations: {
title: i18n.t("upsell.messages.timetickets.allocations.title"),
subTitle: i18n.t("upsell.messages.timetickets.allocations.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
},
general: {
title: i18n.t("upsell.messages.timetickets.general.title"),
subTitle: i18n.t("upsell.messages.timetickets.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
}
},
smartscheduling: {
general: {
icon: <CalendarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.general.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.general.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
},
hrsdelta: {
icon: <CarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.hrsdelta.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.hrsdelta.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
},
datepicker: {
icon: <CarOutlined />,
title: i18n.t("upsell.messages.smartscheduling.datepicker.title"),
subTitle: i18n.t("upsell.messages.smartscheduling.datepicker.subtitle"),
extra: <Button type="primary">{i18n.t("upsell.cta.learnmore")}</Button>
}
}
};

View File

@@ -1,34 +0,0 @@
import i18n from "i18next";
const upsellEnum = {
bills: {
postbills: {
icon: null,
title: i18n.t("upsell.messages.bills.postbills.title"),
subTitle: i18n.t("upsell.messages.bills.postbills.subtitle"),
status: null //Nullable
},
reconcile: {
icon: null,
title: i18n.t("upsell.messages.bills.reconcile.title"),
subTitle: i18n.t("upsell.messages.bills.reconcile.subtitle"),
status: null //Nullable
},
table: {
//icon: null,
title: i18n.t("upsell.messages.bills.table.title"),
subTitle: i18n.t("upsell.messages.bills.table.subtitle"),
//status: null //Nullable
}
},
timetickets: {
table: {
icon: null,
title: i18n.t("upsell.messages.timetickets.table.title"),
subTitle: i18n.t("upsell.messages.timetickets.table.subtitle"),
status: null //Nullable
}
}
};
export default upsellEnum;

View File

@@ -0,0 +1,56 @@
.mask-wrapper {
position: relative;
//Newly added
display: flex;
justify-content: center;
align-items: center;
min-height: 100px; /* Adjust as needed */
}
.mask-content {
// filter: blur(5px);
background-color: rgba(0, 0, 0, 0.05);
pointer-events: none;
//Newly added
//width: 100%;
}
.mask-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
// width: 100%
}
.mask-overlay .ant-card {
max-width: 100%;
}
// .mask-wrapper {
// position: relative;
// display: inline-block;
// }
// .mask-content {
// filter: blur(5px);
// pointer-events: none;
// }
// .mask-overlay {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// display: flex;
// justify-content: center;
// align-items: center;
// z-index: 10;
// }
// .mask-overlay .ant-card {
// max-width: 100%;
// }