UNPKG

react_size_chart

Version:

Vestfoy smart size charts react package

422 lines 19.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Border = exports.EAlignButton = exports.EButtonIcon = void 0; exports.VestofyContent = VestofyContent; exports.VestofySizeChartPopup = VestofySizeChartPopup; exports.VestofyShowBtn = VestofyShowBtn; const tslib_1 = require("tslib"); const react_1 = tslib_1.__importStar(require("react")); const dangerously_set_html_content_1 = tslib_1.__importDefault(require("dangerously-set-html-content")); const jquery_1 = tslib_1.__importDefault(require("jquery")); require("../../assets/bootstrap.min.css"); require("../../assets/vestofy.css"); var EButtonIcon; (function (EButtonIcon) { EButtonIcon["meter_icon"] = "meter"; EButtonIcon["meter_icon_dark"] = "meter-dark"; })(EButtonIcon || (exports.EButtonIcon = EButtonIcon = {})); var EAlignButton; (function (EAlignButton) { EAlignButton[EAlignButton["eAlignLeft"] = 0] = "eAlignLeft"; EAlignButton[EAlignButton["eAlignCenter"] = 1] = "eAlignCenter"; EAlignButton[EAlignButton["eAlignRight"] = 2] = "eAlignRight"; })(EAlignButton || (exports.EAlignButton = EAlignButton = {})); class Border { BorderWidth; BorderColor; BorderRadius; constructor() { this.BorderColor = "#FFFFFF"; this.BorderWidth = 0; this.BorderRadius = 0; } } exports.Border = Border; const g_sContactMail = "contact@vestofy.com"; let g_sHtmlContent = ""; const devUrl = false; let isString = (value) => typeof value === 'string'; function SaveStorageDialogContent(a_sHtmlDialogContent, a_sShop, a_sSizeChartId = null, a_sProductID = null, a_sVendor = null, a_sProductType = null, a_sTags = null) { try { if (isString(a_sSizeChartId)) { sessionStorage.setItem(a_sShop + a_sSizeChartId, a_sHtmlDialogContent); } else if (isString(a_sProductID)) { sessionStorage.setItem(a_sShop + a_sProductID, a_sHtmlDialogContent); } else if (isString(a_sVendor)) { sessionStorage.setItem(a_sShop + a_sVendor, a_sHtmlDialogContent); } else if (isString(a_sProductType)) { sessionStorage.setItem(a_sShop + a_sProductType, a_sHtmlDialogContent); } else if (isString(a_sTags)) { sessionStorage.setItem(a_sShop + a_sTags, a_sHtmlDialogContent); } else { console.warn('Cant save content to storage'); } } catch (e) { console.error('Save content to localstorage exception\n', e); } } function LoadStorageDialogContent(a_sShop, a_sSizeChartId = null, a_sVendor = null, a_sProductType = null, a_sTags = null) { try { if (isString(a_sSizeChartId)) { return sessionStorage.getItem(a_sShop + a_sSizeChartId); } else if (isString(a_sVendor)) { return sessionStorage.getItem(a_sShop + a_sVendor); } else if (isString(a_sProductType)) { return sessionStorage.getItem(a_sShop + a_sProductType); } else if (isString(a_sTags)) { return sessionStorage.getItem(a_sShop + a_sTags); } else { return null; } } catch (e) { console.error('Load content from storage exception\n', e); return null; } } const defaultBtnOptions = { /** * Text displayed on the button that open the guid popup (default: Size Guide) */ buttonText: 'Size Guide', /** * Text size displayed on the button that open the guid popup (default: 15px) */ buttonTextSize: 15, /** * Text color (hex format) displayed on the button that open the guid popup (default: #000000) */ buttonTextColor: '#000000', /** * Background color (hex format) of the button that open the guid popup (default: transparent) */ buttonBackgroundColor: '#FF000000', /** * Image displayed on the side of button */ buttonImgSrc: EButtonIcon.meter_icon.toString(), /** * Button alignment in parent component rule */ btnAlign: EAlignButton.eAlignLeft, /* * Button border */ border: { BorderColor: "#FFFFFFFF", BorderWidth: 0, BorderRadius: 0 }, /** * Show size advice on parent window (product window) */ advice: true, /** * Size advice background color */ adviceBackgroundColor: "#FAB823", /** * Clearing sessionStorage every reload and some additional log (Use in while development) */ dev: false }; const defaultPopupOptions = { dialogTitle: 'Size Guide', }; function buildBtnOptions(a_oPropsOptions) { try { const l_oOptions = { buttonText: a_oPropsOptions.buttonText ?? defaultBtnOptions.buttonText, buttonTextSize: a_oPropsOptions.buttonTextSize ?? defaultBtnOptions.buttonTextSize, buttonTextColor: a_oPropsOptions.buttonTextColor ?? defaultBtnOptions.buttonTextColor, buttonBackgroundColor: a_oPropsOptions.buttonBackgroundColor ?? defaultBtnOptions.buttonBackgroundColor, buttonImgSrc: a_oPropsOptions.buttonImgSrc ?? defaultBtnOptions.buttonImgSrc, btnAlign: a_oPropsOptions.btnAlign ?? defaultBtnOptions.btnAlign, border: a_oPropsOptions.border ?? defaultBtnOptions.border, advice: a_oPropsOptions.advice ?? defaultBtnOptions.advice, adviceText: a_oPropsOptions.adviceText ?? 'Find your best size', adviceBackgroundColor: a_oPropsOptions.adviceBackgroundColor ?? defaultBtnOptions.adviceBackgroundColor, dev: a_oPropsOptions.dev ?? defaultBtnOptions.dev }; return l_oOptions; } catch (e) { console.error('build options error:\n', e); return defaultBtnOptions; } } function buildPopupOptions(a_oPropsOptions) { try { const l_oOptions = { dialogTitle: a_oPropsOptions.dialogTitle ?? defaultPopupOptions.dialogTitle, // dev: typeof a_oPropsOptions.dev != 'undefined' ? a_oPropsOptions.dev : defaultPopupOptions.dev }; return l_oOptions; } catch (e) { console.error('build options error:\n', e); return defaultPopupOptions; } } const g_oVestofyContentLoadedEvent = new CustomEvent("VestofyContentLoadedEvent", { detail: {}, bubbles: true, cancelable: true, composed: false, }); function addScript(src, id, integrity, crossorigin, onLoad) { try { const existing = document.getElementById(id); if (existing) { onLoad(); return existing; } else { const script = document.createElement("script"); script.src = src; script.id = id; if (integrity) { script.integrity = integrity; } if (crossorigin) { script.crossOrigin = crossorigin; } script.async = true; script.onload = () => { if (onLoad) { onLoad(); } }; document.head.appendChild(script); return script; } } catch (e) { console.error('Add script exception\n', e); return null; } } // ********************************************************* // ------Download Vestofy popup content--------------------- // ********************************************************* function loadFittingRoom(a_sShop, a_sPlatform = 'Standalone', a_sOutlineImage = undefined, a_sBottomDescription = undefined, a_sKey = "", a_sAssignment = undefined, a_sSizeChartId = undefined, a_sVendor = undefined, a_sProductType = undefined, a_sTags = undefined, a_sLang = "en") { return new Promise(function (resolve, reject) { try { let l_sSrc = "https://proxy.vestofy.com/proxy/"; if (devUrl) { l_sSrc = "https://proxy.tunnelto.me/proxy/"; console.warn('Vestofy: About to load debug fitting room\n', l_sSrc); } const params = { size_chart_id: a_sSizeChartId, product_id: undefined, product_type: a_sProductType, product_vendor: a_sVendor, product_tags: a_sTags, assignment: a_sAssignment, shop: a_sShop, key: a_sKey, locale: a_sLang, platform: a_sPlatform, outline_image: a_sOutlineImage, bottom_description: a_sBottomDescription, add_header: false }; const queryString = Object.entries(params) .filter(([_, value]) => value !== undefined && value !== null && value !== "") .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) .join("&"); l_sSrc = `${l_sSrc}?${queryString}`; jquery_1.default.ajax({ url: encodeURI(l_sSrc), dataType: "jsonp", method: "GET", success: function (a_oDialogData) { try { window.$ = jquery_1.default; /**Add jQuery to dialog html */ if (a_oDialogData.html) { resolve(a_oDialogData.html); } else { resolve(a_oDialogData); } } catch (e) { console.error("insert Vestofy html exception\n", e); resolve(`<h3>Ooops, Something wrong: Error to parse data :(</br>Try to refresh.</br>If the problem continue contact support: ${g_sContactMail}/h3>`); } }, error: function (error) { console.error(`Ooops, Error to fetch content from: ${l_sSrc}\n`, error); resolve(`<h3>Ooops, Something wrong: Error to fetch content :(</br>Try to refresh.</br>If the problem continue contact support: ${g_sContactMail}</h3>`); }, }); } catch (e) { console.error("Vestofy script exception:\n", e); reject(e); } }); } function renderLoader() { return react_1.default.createElement("div", { className: "d-flex justify-content-center align-items-center", style: { height: "100vh" } }, react_1.default.createElement("div", { className: "spinner-border text-info", role: "status" }, react_1.default.createElement("span", { className: "sr-only" }, "Loading..."))); } const FittingRoomContent = (props) => { (0, react_1.useEffect)(() => { try { if (!props.loading && props.contentHtml && props.contentHtml.length > 0) { if (props.dev) { setTimeout(() => { console.log('Vestofy: dispatch content event'); document.dispatchEvent(g_oVestofyContentLoadedEvent); }, 10); } else { document.dispatchEvent(g_oVestofyContentLoadedEvent); } } } catch (e) { console.error('dispatch Vestofy init event exception\n', e); } return (() => { }); }); return (props.loading ? renderLoader() : react_1.default.createElement(dangerously_set_html_content_1.default, { html: props.contentHtml, allowRerender: props.dev == true })); }; function renderBtnImage(a_sSrc, a_iWidth) { if (a_sSrc == EButtonIcon.meter_icon) { return react_1.default.createElement("span", { className: 'buttonLogo buttonLogoPosition', style: { width: a_iWidth } }); } else if (a_sSrc == EButtonIcon.meter_icon_dark) { return react_1.default.createElement("span", { className: 'buttonLogoDark buttonLogoPosition', style: { width: a_iWidth } }); } else if (a_sSrc == null) { return null; } else { return react_1.default.createElement("img", { className: 'buttonLogoPosition', src: a_sSrc, alt: 'size guide', width: a_iWidth, height: a_iWidth }); } } function VestofyContent() { const [htmlContent, setHtmlContent] = (0, react_1.useState)(""); const [dev, setDev] = (0, react_1.useState)(false); addEventListener("vestofy_content_loaded_event", (e) => { setHtmlContent(e.detail.html); setDev(e.detail.dev); }); return react_1.default.createElement("div", { id: 'vestofyTag' }, react_1.default.createElement(FittingRoomContent, { contentHtml: htmlContent, loading: htmlContent.length == 0, dev: dev })); } // ****************************************** // --------render Popup----------- // ****************************************** function VestofySizeChartPopup(a_oOptions = defaultPopupOptions) { const [htmlContent, setHtmlContent] = (0, react_1.useState)(""); const [dev, setDev] = (0, react_1.useState)(false); addEventListener("vestofy_content_loaded_event", (e) => { setHtmlContent(e.detail.html); setDev(e.detail.dev); }); try { const l_oOptions = buildPopupOptions(a_oOptions); return react_1.default.createElement("div", null, react_1.default.createElement("div", { className: "modal fade", id: "vestofy-chart-modal", role: "dialog", tabIndex: -1, "data-keyboard": 'true', "data-backdrop": 'false', "aria-hidden": "true", "aria-labelledby": "sizeChartDialogDescribe" }, react_1.default.createElement("div", { className: "modal-dialog modal-dialog-scrollable", role: "document" }, react_1.default.createElement("div", { className: "modal-content" }, react_1.default.createElement("div", { className: "modal-header d-flex justify-content-between align-items-start" }, react_1.default.createElement("button", { type: "button", className: "close position-absolute", style: { right: '1rem' }, "data-dismiss": "modal", "aria-label": "Close" }, react_1.default.createElement("span", { "aria-hidden": "true" }, "\u00D7")), react_1.default.createElement("h5", { className: "modal-title", id: "sizeChartDialogDescribe", style: { fontSize: '1.5em' } }, l_oOptions.dialogTitle, dev ? react_1.default.createElement("span", { className: 'small text-muted' }, " ", `(Preview)`) : null)), react_1.default.createElement("div", { className: "modal-body", id: "chart-body" }, react_1.default.createElement("div", { id: 'vestofyTag' }, react_1.default.createElement(FittingRoomContent, { contentHtml: htmlContent, loading: htmlContent.length == 0, dev: dev }))))))); } catch (e) { console.error('SizeChartPopup exception:\n', e); return null; } } // ****************************************** // --------render button--------------------- // ****************************************** function VestofyShowBtn(props = defaultBtnOptions) { const l_oOptions = buildBtnOptions(props); let btnStyle = { outline: 'none', fontSize: l_oOptions.buttonTextSize, color: l_oOptions.buttonTextColor, backgroundColor: l_oOptions.buttonBackgroundColor, border: `${l_oOptions.border?.BorderWidth}px solid ${l_oOptions.border?.BorderColor}`, borderRadius: `${l_oOptions.border?.BorderRadius}px` }; let adviceStyle = { display: l_oOptions.advice ? 'block' : 'none !important', fontSize: l_oOptions.buttonTextSize, backgroundColor: l_oOptions.adviceBackgroundColor, marginBottom: '2px' }; let align = 'vestofy-content-left'; if (l_oOptions.btnAlign == EAlignButton.eAlignCenter) { align = 'vestofy-content-center'; } else if (l_oOptions.btnAlign == EAlignButton.eAlignRight) { align = 'vestofy-content-right'; } btnStyle = Object.assign({}, btnStyle); adviceStyle = Object.assign({}, adviceStyle); return react_1.default.createElement("div", { className: 'vestofy-root vestofy-btn-wrapper' }, l_oOptions.advice ? react_1.default.createElement("div", { className: `vestofy-btn-wrapper` }, react_1.default.createElement("span", { className: `${align}`, style: adviceStyle, id: "showVestofySizeAdvice" }, l_oOptions.adviceText)) : null, react_1.default.createElement("div", { className: `${align}` }, react_1.default.createElement("button", { type: "button", id: "showVestofyBtn", className: `btn btn-primary vestofy-btn ${align}`, style: btnStyle, "data-toggle": "modal", "data-target": "#vestofy-chart-modal", onClick: props.onClick }, renderBtnImage(l_oOptions.buttonImgSrc, l_oOptions.buttonTextSize), l_oOptions.buttonText))); } async function InitDialogContent(props) { const l_sTags = props.tags?.join(','); if (props.options?.dev) { console.log(`size_charts_id: ${props.size_chart_id} vendor: ${props.vendor} product type: ${props.product_type} tags: ${l_sTags}`); } const l_sHtmlContent = LoadStorageDialogContent(props.shop, props.size_chart_id, props.vendor, props.product_type, l_sTags); if (l_sHtmlContent == null || props.options?.dev) { return await loadFittingRoom(props.shop, props.platform, props.bottom_image, props.bottom_description, props.key, props.assignment, props.size_chart_id, props.vendor, props.product_type, l_sTags, props.locale); } else { return g_sHtmlContent; } } // ******************************************* // ---------Component hook-------------------- // ******************************************* const Vestofy = (props) => { const local = typeof props.locale != 'undefined' ? props.locale : 'en'; /**Initialize and import scripts before render*/ (0, react_1.useLayoutEffect)(() => { addScript(`https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js`, "jQuery", undefined, undefined, () => { addScript(`https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js`, "bootstrap", undefined, // "sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+", undefined, // "anonymous", async () => { ContentLoader(); }); }); }, [local]); const ContentLoader = async () => { try { if (props.options && props.options.dev) { sessionStorage.clear(); } const l_sDialogContent = await InitDialogContent(props); SaveStorageDialogContent(l_sDialogContent, props.shop, props.size_chart_id, props.vendor, props.product_type, props.tags?.join(',')); g_sHtmlContent = `${l_sDialogContent}`; //deep copy const vestofyContentEvent = new CustomEvent("vestofy_content_loaded_event", { detail: { html: l_sDialogContent, dev: props.options?.dev } }); dispatchEvent(vestofyContentEvent); } catch (e) { console.error(`Vestofy content load failed`, e); } }; return (react_1.default.createElement(react_1.default.Fragment, null, (props.Popup ?? true) ? VestofyShowBtn(props.options) : VestofyContent())); }; exports.default = Vestofy; //# sourceMappingURL=App.js.map