From 573a10d01bcead2c3ae9bb068df9996fd10dd958 Mon Sep 17 00:00:00 2001 From: alialaqrabawi3 Date: Mon, 16 Sep 2024 20:21:48 +0300 Subject: [PATCH 1/3] fix(ui-issues): fix safe area issue,fix console error --- control/content/js/contentController.js | 1 + resources/languages.json | 8 ++++++++ widget/global/js/repositories/Settings.js | 1 - widget/index.html | 2 +- widget/js/pages/customer/CustomerView.js | 13 ++++++++++++- widget/js/pages/employee/EmployeeView.js | 8 +++++++- widget/js/utils/handleCPSync.js | 16 +++++++++++----- widget/style/style.css | 2 +- widget/widget.js | 5 ++--- 9 files changed, 43 insertions(+), 13 deletions(-) diff --git a/control/content/js/contentController.js b/control/content/js/contentController.js index d925ba2..f28a888 100644 --- a/control/content/js/contentController.js +++ b/control/content/js/contentController.js @@ -39,6 +39,7 @@ const contentController = { const { settingData, isNewInstance } = await Settings.get(); contentState.settings = settingData; if (isNewInstance) { + await Settings.save(contentState.settings); await UserCodeSequences.initializeCodeSequence(); await AnalyticsManager.init(); } diff --git a/resources/languages.json b/resources/languages.json index 12aae53..aeaef71 100644 --- a/resources/languages.json +++ b/resources/languages.json @@ -227,6 +227,14 @@ "defaultValue": "Scanner works only on devices.", "required": true, "inputType": "text" + }, + "networkError": { + "title": "Network error. Check connection and retry.", + "placeholder": "Network error. Check connection and retry.", + "maxLength": 80, + "defaultValue": "Network error. Check connection and retry.", + "required": true, + "inputType": "text" } } }, diff --git a/widget/global/js/repositories/Settings.js b/widget/global/js/repositories/Settings.js index 3e6ee73..4df1570 100644 --- a/widget/global/js/repositories/Settings.js +++ b/widget/global/js/repositories/Settings.js @@ -18,7 +18,6 @@ class Settings { if (err) return reject(err); if (!res || !res.data || !Object.keys(res.data).length) { const data = new Setting().toJSON(); - Settings.save(data); resolve({ settingData: data, isNewInstance: true }); } else { const data = new Setting(res.data).toJSON(); diff --git a/widget/index.html b/widget/index.html index 2484154..3040ded 100644 --- a/widget/index.html +++ b/widget/index.html @@ -85,7 +85,7 @@

diff --git a/widget/js/pages/customer/CustomerView.js b/widget/js/pages/customer/CustomerView.js index 62b4421..e8259b5 100644 --- a/widget/js/pages/customer/CustomerView.js +++ b/widget/js/pages/customer/CustomerView.js @@ -116,8 +116,14 @@ const CustomerView = { this._initRewardList(availbleRewardLength); this._updateConfirmButton(); }, - _addNewTransaction() { + async _addNewTransaction() { try { + if (!navigator.onLine) { + buildfire.dialog.toast({ + message: await getLanguage('general.networkError'), + }); + return; + } const checkboxes = document.querySelectorAll('input[type="checkbox"]'); this._uiElement.confirmTransactionBtn.disabled = true; @@ -342,6 +348,11 @@ const CustomerView = { availableRewardList.appendChild(emptyState); } }, + refreshRewardList() { + let availbleRewardLength = CustomerController.getAvailbleRewardLength(this.newStamps, widgetAppState.currentCustomer.currentStamps, widgetAppState.settings.cardSize); + availbleRewardLength += widgetAppState.currentCustomer.availableRewards.length; + this._initRewardList(availbleRewardLength); + }, _createCheckbox(index) { const template = document.getElementById('template'); diff --git a/widget/js/pages/employee/EmployeeView.js b/widget/js/pages/employee/EmployeeView.js index cd0598f..6eb582f 100644 --- a/widget/js/pages/employee/EmployeeView.js +++ b/widget/js/pages/employee/EmployeeView.js @@ -35,6 +35,12 @@ const EmployeeView = { }); confirmBtn.addEventListener('click', async () => { + if (!navigator.onLine) { + buildfire.dialog.toast({ + message: await getLanguage('general.networkError'), + }); + return; + } const userId = document.getElementById('userIdField').value; if (!userId) { userIdError.innerText = await getLanguage('general.userIdRequired'); @@ -127,7 +133,7 @@ const EmployeeView = { async _openCustomerProfile(userId) { try { const result = await CustomerController.getCustomerInfo(userId, widgetAppState.settings.cardSize); - if (result.currentStamps) { + if (result.currentStamps !== undefined) { widgetAppState.currentCustomer.currentStamps = result.currentStamps; widgetAppState.currentCustomer.availableRewards = result.availableRewards; } diff --git a/widget/js/utils/handleCPSync.js b/widget/js/utils/handleCPSync.js index d909c7d..9924f48 100644 --- a/widget/js/utils/handleCPSync.js +++ b/widget/js/utils/handleCPSync.js @@ -12,7 +12,9 @@ const handleCPSync = { if (data.data.content || data.data.content === '') { widgetAppState.settings.introductionWYSIWYG = data.data.content; } - if (widgetAppRouter.currentPage) return; + if (AuthManager.isEmployee) { + if (widgetAppRouter.currentPage !== 'home') return; + } else if (widgetAppRouter.currentPage) return; CustomerView._initListView(); CustomerView._initValues(); } else if (data.cmd === 'cardChanged') { @@ -20,7 +22,7 @@ const handleCPSync = { widgetAppState.settings.cardSize = data.data.cardSize; const result = await CustomerController.getCustomerInfo(widgetAppState.currentCustomer.friendlyId, widgetAppState.settings.cardSize); - if (result.currentStamps) { + if (result.currentStamps !== undefined) { widgetAppState.currentCustomer.currentStamps = result.currentStamps; widgetAppState.currentCustomer.availableRewards = result.availableRewards; } @@ -32,14 +34,18 @@ const handleCPSync = { widgetAppState.currentCustomer.imageUrl = user?.imageUrl ? user.imageUrl : 'https://app.buildfire.com/app/media/avatar.png'; } - if (widgetAppRouter.currentPage) return; + if (AuthManager.isEmployee) { + if (widgetAppRouter.currentPage !== 'home') return; + } else if (widgetAppRouter.currentPage) return; CustomerView.drawStamps(widgetAppState.settings.cardSize); if (AuthManager.isEmployee) { - CustomerView._initRewardList(); + CustomerView.refreshRewardList(); } } else if (data.cmd === 'designChanged') { widgetAppState.settings.design = data.data.design; - if (widgetAppRouter.currentPage) return; + if (AuthManager.isEmployee) { + if (widgetAppRouter.currentPage !== 'home') return; + } else if (widgetAppRouter.currentPage) return; CustomerView.drawStamps(widgetAppState.settings.cardSize); } }; diff --git a/widget/style/style.css b/widget/style/style.css index 6cbc367..cb20cbc 100644 --- a/widget/style/style.css +++ b/widget/style/style.css @@ -51,7 +51,7 @@ body.has-safe-area #home { .rewardListContainer .listView-items { margin-bottom: 14px; } -.friendlyId { +#friendlyId { padding-bottom: 1rem; } diff --git a/widget/widget.js b/widget/widget.js index 343a0c4..d4155a2 100644 --- a/widget/widget.js +++ b/widget/widget.js @@ -35,9 +35,8 @@ buildfire.auth.onLogout(() => { buildfire.deeplink.onUpdate((deeplinkData) => { const deeplinkPayload = parseDeeplinkData(deeplinkData); if (deeplinkPayload && deeplinkPayload.earned) { - if (widgetAppRouter.currentPage === 'home') { - widgetAppRouter.push({ pageId: 'customerTransaction', pageName: 'customerTransaction', name: 'history' }); - TransactionView._initCustomerListView(); + if (!widgetAppRouter.currentPage) { + window.location.reload(); } else { TransactionView._initCustomerListView(); } From 0d5c692fc083d74c9fb08967e7e7bab87e64d01d Mon Sep 17 00:00:00 2001 From: alialaqrabawi3 Date: Tue, 17 Sep 2024 01:11:56 +0300 Subject: [PATCH 2/3] feat(date-format): add time inside date in history tab --- control/transaction/js/tableController.js | 27 ++++++++++++++++++----- widget/style/style.css | 3 +-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/control/transaction/js/tableController.js b/control/transaction/js/tableController.js index 9620bb6..02a84b2 100644 --- a/control/transaction/js/tableController.js +++ b/control/transaction/js/tableController.js @@ -7,9 +7,9 @@ const searchTableConfig = { }, columns: [{ header: 'Date', - data: '${data.date}', + data: '${TransactionController.formatDate(data.createdOn)}', type: 'string', - width: '100px', + width: '165px', sortBy: 'date1', defaultSorted: true, }, { @@ -21,18 +21,18 @@ const searchTableConfig = { header: 'Stamps', data: '${data.changeValue}', type: 'string', - width: '100px', + width: '90px', }, { header: 'Rewards', data: '${TransactionController.getRewards(data)}', type: 'string', - width: '100px', + width: '90px', }, { header: 'Redeems', data: '${TransactionController.getRedeems(data)}', type: 'string', - width: '100px', + width: '90px', }, { header: 'Authorized by', @@ -131,6 +131,23 @@ const TransactionController = { return 0; }, + formatDate(dateString) { + console.log('dateString:', dateString); + const date = new Date(dateString); + + const month = date.getMonth() + 1; + const day = date.getDate(); + const year = date.getFullYear(); + + let hours = date.getHours(); + const minutes = date.getMinutes(); + + const ampm = hours >= 12 ? 'PM' : 'AM'; + hours = hours % 12 || 12; + + const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes; + return `${month}/${day}/${year}, ${hours}:${formattedMinutes} ${ampm}`; + }, init() { this.transactionsTable = new SearchTable('transactionTableContainer', searchTableConfig); diff --git a/widget/style/style.css b/widget/style/style.css index cb20cbc..56af7e2 100644 --- a/widget/style/style.css +++ b/widget/style/style.css @@ -156,8 +156,7 @@ body.has-safe-area #transactionCustomerList, body.has-safe-area #transactionEmpl } .customer-info #lifeTimeStamps { - margin-top: 8px; - margin-bottom: 12px; + margin: 8px 0; } .customer-info #lifeTimeStamps, .customer-info #lifeTimeRedeems { From f7247a041383883497a91d79369269636aec449b Mon Sep 17 00:00:00 2001 From: alialaqrabawi3 Date: Tue, 17 Sep 2024 19:45:14 +0300 Subject: [PATCH 3/3] feat(scanner-permission): show required permission message --- resources/languages.json | 14 +++++++++++--- widget/js/pages/employee/EmployeeView.js | 21 ++++++++++++++++++--- widget/layouts/layout1.css | 20 +++++++++++++++----- widget/style/style.css | 3 ++- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/resources/languages.json b/resources/languages.json index aeaef71..e0e0577 100644 --- a/resources/languages.json +++ b/resources/languages.json @@ -229,10 +229,18 @@ "inputType": "text" }, "networkError": { - "title": "Network error. Check connection and retry.", - "placeholder": "Network error. Check connection and retry.", + "title": "Check connection and retry.", + "placeholder": "Check connection and retry.", "maxLength": 80, - "defaultValue": "Network error. Check connection and retry.", + "defaultValue": "Check connection and retry.", + "required": true, + "inputType": "text" + }, + "cameraPermissionRequired": { + "title": "Camera permission required.", + "placeholder": "Access to the camera has been prohibited, please enable it in the settings app to continue", + "maxLength": 80, + "defaultValue": "Access to the camera has been prohibited, please enable it in the settings app to continue", "required": true, "inputType": "text" } diff --git a/widget/js/pages/employee/EmployeeView.js b/widget/js/pages/employee/EmployeeView.js index 6eb582f..3f17724 100644 --- a/widget/js/pages/employee/EmployeeView.js +++ b/widget/js/pages/employee/EmployeeView.js @@ -17,7 +17,7 @@ const EmployeeView = { const formFab = new buildfire.components.fabSpeedDial('#fabSpeedDialContainer', formOptions); const scannerFab = new buildfire.components.fabSpeedDial('#fabSpeedDialContainer', scannerOptions); - scannerFab.onMainButtonClick = () => this._openScanner(); + scannerFab.onMainButtonClick = () => this._openScanner(true, true); formFab.onMainButtonClick = () => this._openMaterialForm(); }, @@ -69,7 +69,7 @@ const EmployeeView = { document.getElementById('userIdField').value = ''; }); }, - _openScanner(showDeviceOnlyMessage = true) { + async _openScanner(showDeviceOnlyMessage = true, showCameraPermissionMessage = false) { const isWeb = buildfire.getContext().device.platform === 'web'; if (isWeb) { if (!showDeviceOnlyMessage) return null; @@ -81,6 +81,7 @@ const EmployeeView = { return null; } + buildfire.services.camera.barcodeScanner.scan( { preferFrontCamera: false, @@ -88,7 +89,21 @@ const EmployeeView = { formats: 'QR_CODE', }, async (err, result) => { - if (err) return console.error(err); + if (err) { + if (JSON.stringify(err) === '"Scanning failed: Access to the camera has been prohibited; please enable it in the Settings app to continue"') { + if (showCameraPermissionMessage) { + const permissionErrorMessage = await getLanguage('general.cameraPermissionRequired'); + buildfire.dialog.toast({ + message: permissionErrorMessage, + type: 'danger', + }); + } + } else { + buildfire.dialog.toast({ message: err, type: 'danger' }); + } + return console.error(err); + } + if (result.cancelled) { return null; } diff --git a/widget/layouts/layout1.css b/widget/layouts/layout1.css index c983493..718ff2c 100644 --- a/widget/layouts/layout1.css +++ b/widget/layouts/layout1.css @@ -80,6 +80,7 @@ body { font-weight: 400; color: var(--bf-theme-body-text); } + .mdc-dialog__actions { padding-top: 24px; } @@ -98,15 +99,16 @@ body { .mdc-text-field__input { font-size: 16px; font-weight: 400; - color: var(--bf-theme-body-text) !important; } .customer-info #lifeTimeStamps, .customer-info #lifeTimeRedeems { font-size: 14px; font-weight: 400; color: var(--bf-theme-body-text); +} - +#userName { + color: var(--bf-theme-body-text); } #stampsActionContainer #decrementStamp { @@ -145,19 +147,27 @@ body { #stampsAction .add-stamp-title { color: var(--bf-theme-header-text); } +#friendlyId { + color: var(--bf-theme-body-text) !important; +} .available-reward-title { color: var(--bf-theme-header-text); } .mdc-checkbox { - color: var(--bf-theme-primary); + color: var(--bf-theme-primary); } -.mdc-checkbox__native-control:enabled:checked~.mdc-checkbox__background, .mdc-checkbox__native-control:enabled:indeterminate~.mdc-checkbox__background { + +.mdc-checkbox__native-control:enabled:checked ~ .mdc-checkbox__background, .mdc-checkbox__native-control:enabled:indeterminate ~ .mdc-checkbox__background { border-color: var(--bf-theme-primary); background-color: var(--bf-theme-primary); } -.mdc-checkbox .mdc-checkbox__native-control:checked~.mdc-checkbox__background::before { +.mdc-checkbox__native-control:enabled:not(:checked):not(:indeterminate)~.mdc-checkbox__background { + border-color: var(--bf-theme-primary-text); +} + +.mdc-checkbox .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background::before { background-color: var(--bf-theme-primary); } diff --git a/widget/style/style.css b/widget/style/style.css index 56af7e2..5ace965 100644 --- a/widget/style/style.css +++ b/widget/style/style.css @@ -156,7 +156,8 @@ body.has-safe-area #transactionCustomerList, body.has-safe-area #transactionEmpl } .customer-info #lifeTimeStamps { - margin: 8px 0; + margin-top: 8px; + margin-bottom: 2px; } .customer-info #lifeTimeStamps, .customer-info #lifeTimeRedeems {