diff --git a/src/public/modules/forms/admin/directives/configure-mobile.client.directive.js b/src/public/modules/forms/admin/directives/configure-mobile.client.directive.js
index ee0bcec6a0..7f2a4b25c3 100644
--- a/src/public/modules/forms/admin/directives/configure-mobile.client.directive.js
+++ b/src/public/modules/forms/admin/directives/configure-mobile.client.directive.js
@@ -1,4 +1,13 @@
'use strict'
+const { get } = require('lodash')
+
+const {
+ ADMIN_VERIFIED_SMS_STATES,
+} = require('../../../../../shared/util/verification')
+
+const AdminMetaService = require('../../../../services/AdminMetaService')
+
+const { injectedVariables } = require('../../../../utils/injectedVariables')
angular
.module('forms')
@@ -10,24 +19,89 @@ function configureMobileDirective() {
'modules/forms/admin/directiveViews/configure-mobile.client.view.html',
restrict: 'E',
scope: {
- field: '=',
+ field: '<',
+ form: '<',
name: '=',
characterLimit: '=',
+ isLoading: '<',
},
controller: [
+ '$q',
'$uibModal',
'$scope',
'$translate',
- function ($uibModal, $scope, $translate) {
- // Get support form link from translation json.
- $translate('LINKS.SUPPORT_FORM_LINK').then((supportFormLink) => {
- $scope.supportFormLink = supportFormLink
- })
+ 'Toastr',
+ function ($q, $uibModal, $scope, $translate, Toastr) {
+ // Get the link for onboarding the form from the translation json
+ $translate('LINKS.VERIFIED_SMS_SETUP_LINK').then(
+ (verifiedSmsSetupLink) => {
+ $scope.verifiedSmsSetupLink = verifiedSmsSetupLink
+ },
+ )
+
+ // Formats a given string as a number by setting it to US locale.
+ // Concretely, this adds commas between every thousand.
+ const formatStringAsNumber = (num) =>
+ Number(num).toLocaleString('en-US')
+
+ // NOTE: This is set on scope as it is used by the UI to determine if the toggle is loading
+ $scope.isLoading = true
+ $scope.field.hasRetrievalError = false
+
+ const formattedSmsVerificationLimit =
+ // Format so that it has commas; conversion is required because it's string initially
+ formatStringAsNumber(injectedVariables.smsVerificationLimit)
+ const getAdminVerifiedSmsState = (verifiedSmsCount, msgSrvcId) => {
+ if (msgSrvcId) {
+ return ADMIN_VERIFIED_SMS_STATES.hasMessageServiceId
+ }
+ if (verifiedSmsCount <= injectedVariables.smsVerificationLimit) {
+ return ADMIN_VERIFIED_SMS_STATES.belowLimit
+ }
+ return ADMIN_VERIFIED_SMS_STATES.limitExceeded
+ }
+
+ $q.when(
+ AdminMetaService.getFreeSmsCountsUsedByFormAdmin($scope.form._id),
+ )
+ .then((smsCounts) => {
+ $scope.verifiedSmsCount = smsCounts
+ $scope.adminVerifiedSmsState = getAdminVerifiedSmsState(
+ smsCounts,
+ $scope.form.msgSrvcName,
+ )
+ // NOTE: This links into the verifiable field component and hence, is used by both email and mobile
+ $scope.field.hasAdminExceededSmsLimit =
+ $scope.adminVerifiedSmsState ===
+ ADMIN_VERIFIED_SMS_STATES.limitExceeded
+ })
+ .catch((error) => {
+ $scope.field.hasRetrievalError = true
+ Toastr.error(
+ get(
+ error,
+ 'response.data.message',
+ 'Sorry, an error occurred. Please refresh the page to toggle OTP verification.',
+ ),
+ )
+ })
+ .finally(() => ($scope.isLoading = false))
+
+ // Only open if the admin has sms counts below the limit.
+ // If the admin has counts above limit without a message id, the toggle should be disabled anyway.
+ // Otherwise, if the admin has a message id, just enable it without the modal
$scope.openVerifiedSMSModal = function () {
const isTogglingOnVerifiedSms = !$scope.field.isVerifiable
- $scope.verifiedSMSModal =
+ const isAdminBelowLimit =
+ $scope.adminVerifiedSmsState ===
+ ADMIN_VERIFIED_SMS_STATES.belowLimit
+ const shouldShowModal =
isTogglingOnVerifiedSms &&
+ isAdminBelowLimit &&
+ !$scope.field.hasRetrievalError
+ $scope.verifiedSMSModal =
+ shouldShowModal &&
$uibModal.open({
animation: true,
backdrop: 'static',
@@ -39,14 +113,22 @@ function configureMobileDirective() {
resolve: {
externalScope: function () {
return {
- title: 'Verified SMS charges',
- confirmButtonText: 'OK, Noted',
+ title: `OTP verification will be disabled at ${formattedSmsVerificationLimit} responses`,
+ confirmButtonText: 'Accept',
description: `
- Under 10,000 form responses: Free verified SMS
-
- Above 10,000 form responses: ~US$0.0395 per SMS - contact us
- for billing. Forms exceeding the free tier without billing will be deactivated.
+ We provide SMS OTP verification for free up to ${formattedSmsVerificationLimit} responses. OTP verification will be automatically disabled when your account reaches ${formattedSmsVerificationLimit} responses.
+
+ If you require OTP verification for more than ${formattedSmsVerificationLimit} responses,
+ please arrange advance billing with us.
+
+
+ Current response count: ${formatStringAsNumber(
+ $scope.verifiedSmsCount,
+ )}/${formattedSmsVerificationLimit}
`,
+ isImportant: true,
}
},
},
diff --git a/src/public/modules/forms/admin/views/edit-fields.client.modal.html b/src/public/modules/forms/admin/views/edit-fields.client.modal.html
index 98f1c99808..6dfd863430 100644
--- a/src/public/modules/forms/admin/views/edit-fields.client.modal.html
+++ b/src/public/modules/forms/admin/views/edit-fields.client.modal.html
@@ -849,6 +849,7 @@