diff --git a/backend/Actions/Wsms/RecordApiHelper.php b/backend/Actions/Wsms/RecordApiHelper.php new file mode 100644 index 00000000..26e37b3e --- /dev/null +++ b/backend/Actions/Wsms/RecordApiHelper.php @@ -0,0 +1,137 @@ +_integrationDetails = $integrationDetails; + $this->_integrationID = $integId; + } + + /** + * Execute the integration + * + * @param array $fieldValues Field values from form + * @param array $fieldMap Field mapping + * @param array $utilities Actions to perform + * + * @return array + */ + public function execute($fieldValues, $fieldMap, $utilities) + { + if (!\defined('WP_SMS_VERSION')) { + return [ + 'success' => false, + 'message' => __('WSMS (WP SMS) is not installed or activated', 'bit-integrations') + ]; + } + + $fieldData = static::generateReqDataFromFieldMap($fieldMap, $fieldValues); + + $mainAction = $this->_integrationDetails->mainAction ?? 'send_sms'; + + $defaultResponse = [ + 'success' => false, + // translators: %s: Plugin name + 'message' => wp_sprintf(__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integrations Pro') + ]; + + // Route to appropriate action method + switch ($mainAction) { + case 'send_sms': + $response = Hooks::apply(Config::withPrefix('wsms_send_sms'), $defaultResponse, $fieldData); + $type = 'sms'; + $actionType = 'send_sms'; + + break; + + case 'add_subscriber': + $response = Hooks::apply(Config::withPrefix('wsms_add_subscriber'), $defaultResponse, $fieldData, $this->_integrationDetails); + $type = 'subscriber'; + $actionType = 'add_subscriber'; + + break; + + case 'update_subscriber': + $response = Hooks::apply(Config::withPrefix('wsms_update_subscriber'), $defaultResponse, $fieldData, $this->_integrationDetails); + $type = 'subscriber'; + $actionType = 'update_subscriber'; + + break; + + case 'delete_subscriber': + $response = Hooks::apply(Config::withPrefix('wsms_delete_subscriber'), $defaultResponse, $fieldData, $this->_integrationDetails); + $type = 'subscriber'; + $actionType = 'delete_subscriber'; + + break; + + case 'add_group': + $response = Hooks::apply(Config::withPrefix('wsms_add_group'), $defaultResponse, $fieldData); + $type = 'group'; + $actionType = 'add_group'; + + break; + + case 'update_group': + $response = Hooks::apply(Config::withPrefix('wsms_update_group'), $defaultResponse, $fieldData); + $type = 'group'; + $actionType = 'update_group'; + + break; + + case 'delete_group': + $response = Hooks::apply(Config::withPrefix('wsms_delete_group'), $defaultResponse, $fieldData); + $type = 'group'; + $actionType = 'delete_group'; + + break; + + default: + $response = [ + 'success' => false, + 'message' => __('Invalid action', 'bit-integrations') + ]; + $type = 'WSMS'; + $actionType = 'unknown'; + + break; + } + + $responseType = isset($response['success']) && $response['success'] ? 'success' : 'error'; + LogHandler::save($this->_integrationID, ['type' => $type, 'type_name' => $actionType], $responseType, $response); + + return $response; + } + + private static function generateReqDataFromFieldMap($fieldMap, $fieldValues) + { + $dataFinal = []; + foreach ($fieldMap as $item) { + $triggerValue = $item->formField; + $actionValue = $item->wsmsField; + + $dataFinal[$actionValue] = $triggerValue === 'custom' && isset($item->customValue) ? Common::replaceFieldWithValue($item->customValue, $fieldValues) : $fieldValues[$triggerValue] ?? ''; + } + + return $dataFinal; + } +} diff --git a/backend/Actions/Wsms/Routes.php b/backend/Actions/Wsms/Routes.php new file mode 100644 index 00000000..a19aab24 --- /dev/null +++ b/backend/Actions/Wsms/Routes.php @@ -0,0 +1,11 @@ + (int) $group->ID, + 'label' => $group->name, + ]; + } + } + + $response['groups'] = $groups; + wp_send_json_success($response, 200); + } + + public function execute($integrationData, $fieldValues) + { + $integrationDetails = $integrationData->flow_details; + $integId = $integrationData->id; + $fieldMap = $integrationDetails->field_map; + $utilities = isset($integrationDetails->utilities) ? $integrationDetails->utilities : []; + + if (empty($fieldMap)) { + return new WP_Error('field_map_empty', __('Field map is empty', 'bit-integrations')); + } + + $recordApiHelper = new RecordApiHelper($integrationDetails, $integId); + $wsmsResponse = $recordApiHelper->execute($fieldValues, $fieldMap, $utilities); + + if (is_wp_error($wsmsResponse)) { + return $wsmsResponse; + } + + return $wsmsResponse; + } +} diff --git a/backend/Core/Util/AllTriggersName.php b/backend/Core/Util/AllTriggersName.php index a611756e..ee40488e 100644 --- a/backend/Core/Util/AllTriggersName.php +++ b/backend/Core/Util/AllTriggersName.php @@ -58,6 +58,7 @@ public static function allTriggersName() 'FluentBooking' => ['name' => 'Fluent Booking', 'isPro' => true, 'is_active' => false], 'CreatorLms' => ['name' => 'Creator LMS', 'isPro' => true, 'is_active' => false], 'FluentCart' => ['name' => 'FluentCart', 'isPro' => true, 'is_active' => false], + 'Wsms' => ['name' => 'WSMS (WP SMS)', 'isPro' => true, 'is_active' => false], 'FluentCrm' => ['name' => 'Fluent CRM', 'isPro' => true, 'is_active' => false], 'FluentCommunity' => ['name' => 'Fluent Community', 'isPro' => true, 'is_active' => false], 'FluentPdfGenerator' => ['name' => 'Fluent PDF Generator', 'isPro' => true, 'is_active' => false], diff --git a/frontend/src/Utils/StaticData/webhookIntegrations.js b/frontend/src/Utils/StaticData/webhookIntegrations.js index cc893d01..3ca08e6e 100644 --- a/frontend/src/Utils/StaticData/webhookIntegrations.js +++ b/frontend/src/Utils/StaticData/webhookIntegrations.js @@ -102,7 +102,15 @@ export const customFormIntegrations = [ 'WordPress', 'FluentPdfGenerator', 'BookingPress', - 'FluentPdfGenerator' + 'FluentPdfGenerator', + 'B2BKing', + 'FormyChat', + 'GiveWp', + 'SenseiLMS', + 'SureDash', + 'WpDataTables', + 'WpErp', + 'Wsms' ] export const actionHookIntegrations = ['ActionHook'] diff --git a/frontend/src/components/AllIntegrations/EditInteg.jsx b/frontend/src/components/AllIntegrations/EditInteg.jsx index baf8e2a1..10fdcc34 100644 --- a/frontend/src/components/AllIntegrations/EditInteg.jsx +++ b/frontend/src/components/AllIntegrations/EditInteg.jsx @@ -177,6 +177,7 @@ const EditCreatorLms = lazy(() => import('./CreatorLms/EditCreatorLms')) const EditUltimateAffiliatePro = lazy(() => import('./UltimateAffiliatePro/EditUltimateAffiliatePro')) const EditBookly = lazy(() => import('./Bookly/EditBookly')) const EditFluentCart = lazy(() => import('./FluentCart/EditFluentCart')) +const EditWsms = lazy(() => import('./Wsms/EditWsms')) const EditMoreConvertWishlist = lazy(() => import('./MoreConvertWishlist/EditMoreConvertWishlist')) const EditHefflCRM = lazy(() => import('./HefflCRM/EditHefflCRM')) const EditSecureCustomFields = lazy(() => import('./SecureCustomFields/EditSecureCustomFields')) @@ -618,6 +619,8 @@ const IntegType = memo(({ allIntegURL, flow }) => { return case 'FluentCart': return + case 'Wsms': + return case 'MoreConvert Wishlist': return case 'Heffl CRM': diff --git a/frontend/src/components/AllIntegrations/IntegInfo.jsx b/frontend/src/components/AllIntegrations/IntegInfo.jsx index c095b228..5145e4df 100644 --- a/frontend/src/components/AllIntegrations/IntegInfo.jsx +++ b/frontend/src/components/AllIntegrations/IntegInfo.jsx @@ -181,6 +181,7 @@ const UltimateAffiliateProAuthorization = lazy( ) const BooklyAuthorization = lazy(() => import('./Bookly/BooklyAuthorization')) const FluentCartAuthorization = lazy(() => import('./FluentCart/FluentCartAuthorization')) +const WsmsAuthorization = lazy(() => import('./Wsms/WsmsAuthorization')) const MoreConvertWishlistAuthorization = lazy(() => import('./MoreConvertWishlist/MoreConvertWishlistAuthorization')) const HefflCRMAuthorization = lazy(() => import('./HefflCRM/HefflCRMAuthorization')) @@ -666,6 +667,8 @@ export default function IntegInfo() { return case 'FluentCart': return + case 'Wsms': + return case 'MoreConvert Wishlist': return ( import('./CreatorLms/CreatorLms')) const UltimateAffiliatePro = lazy(() => import('./UltimateAffiliatePro/UltimateAffiliatePro')) const Bookly = lazy(() => import('./Bookly/Bookly')) const FluentCart = lazy(() => import('./FluentCart/FluentCart')) +const Wsms = lazy(() => import('./Wsms/Wsms')) const MoreConvertWishlist = lazy(() => import('./MoreConvertWishlist/MoreConvertWishlist')) const HefflCRM = lazy(() => import('./HefflCRM/HefflCRM')) const SecureCustomFields = lazy(() => import('./SecureCustomFields/SecureCustomFields')) @@ -1728,6 +1729,15 @@ export default function NewInteg({ allIntegURL }) { setFlow={setFlow} /> ) + case 'Wsms': + return ( + + ) case 'MoreConvert Wishlist': return ( + + +
+ {__('Integration Name:', 'bit-integrations')} + handleInput(e, wsmsConf, setWsmsConf)} + name="name" + value={wsmsConf.name} + type="text" + placeholder={__('Integration Name...', 'bit-integrations')} + /> +
+
+ + + + + + + saveActionConf({ + flow, + setFlow, + allIntegURL, + conf: wsmsConf, + navigate, + id, + edit: 1, + setIsLoading, + setSnackbar + }) + } + disabled={!checkMappedFields(wsmsConf)} + isLoading={isLoading} + dataConf={wsmsConf} + setDataConf={setWsmsConf} + formFields={formFields} + /> +
+ + ) +} diff --git a/frontend/src/components/AllIntegrations/Wsms/Wsms.jsx b/frontend/src/components/AllIntegrations/Wsms/Wsms.jsx new file mode 100644 index 00000000..a3c66d11 --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/Wsms.jsx @@ -0,0 +1,106 @@ +import { useState } from 'react' +import 'react-multiple-select-dropdown-lite/dist/index.css' +import { useNavigate, useParams } from 'react-router' +import BackIcn from '../../../Icons/BackIcn' +import { __ } from '../../../Utils/i18nwrap' +import SnackMsg from '../../Utilities/SnackMsg' +import { saveIntegConfig } from '../IntegrationHelpers/IntegrationHelpers' +import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree' +import WsmsAuthorization from './WsmsAuthorization' +import { checkMappedFields } from './WsmsCommonFunc' +import WsmsIntegLayout from './WsmsIntegLayout' + +export default function Wsms({ formFields, setFlow, flow, allIntegURL }) { + const navigate = useNavigate() + const { formID } = useParams() + const [isLoading, setIsLoading] = useState(false) + const [step, setStep] = useState(1) + const [snack, setSnackbar] = useState({ show: false }) + const [wsmsConf, setWsmsConf] = useState({ + name: 'WSMS (WP SMS)', + type: 'Wsms', + field_map: [{ formField: '', wsmsField: '' }], + actions: {}, + mainAction: '' + }) + + const nextPage = val => { + setTimeout(() => { + document.getElementById('btcd-settings-wrp').scrollTop = 0 + }, 300) + + if (val === 3) { + if (!checkMappedFields(wsmsConf)) { + setSnackbar({ + show: true, + msg: __('Please map all required fields to continue.', 'bit-integrations') + }) + return + } + + if (wsmsConf.name !== '' && wsmsConf.field_map.length > 0) { + setStep(val) + } + } else { + setStep(val) + } + } + + return ( +
+ +
{/* */}
+ + {/* STEP 1 */} + + + {/* STEP 2 */} +
+ +
+
+
+ +
+ + {/* STEP 3 */} + + saveIntegConfig(flow, setFlow, allIntegURL, wsmsConf, navigate, '', '', setIsLoading) + } + isLoading={isLoading} + /> +
+ ) +} diff --git a/frontend/src/components/AllIntegrations/Wsms/WsmsAuthorization.jsx b/frontend/src/components/AllIntegrations/Wsms/WsmsAuthorization.jsx new file mode 100644 index 00000000..53ad0243 --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/WsmsAuthorization.jsx @@ -0,0 +1,117 @@ +import { useState } from 'react' +import BackIcn from '../../../Icons/BackIcn' +import bitsFetch from '../../../Utils/bitsFetch' +import { __ } from '../../../Utils/i18nwrap' +import LoaderSm from '../../Loaders/LoaderSm' +import TutorialLink from '../../Utilities/TutorialLink' + +export default function WsmsAuthorization({ + formID, + wsmsConf, + setWsmsConf, + step, + nextPage, + isLoading, + setIsLoading, + setSnackbar +}) { + const [isAuthorized, setIsAuthorized] = useState(false) + const [showAuthMsg, setShowAuthMsg] = useState(false) + const authorizeHandler = () => { + setIsLoading('auth') + bitsFetch({}, 'wsms_authorize') + .then(result => { + if (result?.success) { + setIsAuthorized(true) + setSnackbar({ + show: true, + msg: __('Connected with WSMS (WP SMS) Successfully', 'bit-integrations') + }) + } + setIsLoading(false) + setShowAuthMsg(true) + }) + .catch(() => { + setIsLoading(false) + setShowAuthMsg(true) + }) + } + + const handleInput = e => { + const newConf = { ...wsmsConf } + newConf[e.target.name] = e.target.value + setWsmsConf(newConf) + } + + return ( +
+ + +
+ {__('Integration Name:', 'bit-integrations')} +
+ + + {isLoading === 'auth' && ( +
+ + {__('Checking if WSMS (WP SMS) is authorized!!!', 'bit-integrations')} +
+ )} + + {showAuthMsg && !isAuthorized && !isLoading && ( +
+
+
+ +
+
+ {__('WSMS (WP SMS) is not activated or not installed', 'bit-integrations')} +
+
+
+ )} + + {showAuthMsg && isAuthorized && !isLoading && ( +
+
+ +
+
{__('WSMS (WP SMS) is activated', 'bit-integrations')}
+
+ )} + + +
+ +
+ ) +} diff --git a/frontend/src/components/AllIntegrations/Wsms/WsmsCommonFunc.js b/frontend/src/components/AllIntegrations/Wsms/WsmsCommonFunc.js new file mode 100644 index 00000000..2be8af4f --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/WsmsCommonFunc.js @@ -0,0 +1,60 @@ +import { create } from 'mutative' +import toast from 'react-hot-toast' +import bitsFetch from '../../../Utils/bitsFetch' +import { __ } from '../../../Utils/i18nwrap' + +export const handleInput = (e, wsmsConf, setWsmsConf) => { + const { name, value } = e.target + + setWsmsConf(prevConf => + create(prevConf, draftConf => { + draftConf[name] = value + }) + ) +} + +export const refreshGroups = (setWsmsConf, setIsLoading) => { + setIsLoading(true) + bitsFetch(null, 'refresh_wsms_groups') + .then(result => { + if (result && result?.success && result?.data?.groups) { + setWsmsConf(prevConf => + create(prevConf, draftConf => { + draftConf.allGroups = result.data.groups + }) + ) + + setIsLoading(false) + toast.success(__('All groups fetched successfully', 'bit-integrations')) + return + } + setIsLoading(false) + toast.error(__('WSMS groups fetch failed. Please try again', 'bit-integrations')) + }) + .catch(() => setIsLoading(false)) +} + +export const checkMappedFields = wsmsConf => { + const mappedFields = wsmsConf?.field_map + ? wsmsConf.field_map.filter( + mappedField => + !mappedField.formField || + !mappedField.wsmsField || + (mappedField.formField === 'custom' && !mappedField.customValue) + ) + : [] + if (mappedFields.length > 0) { + return false + } + return true +} + +export const generateMappedField = fields => { + const requiredFlds = fields.filter(fld => fld.required === true) + return requiredFlds.length > 0 + ? requiredFlds.map(field => ({ + formField: '', + wsmsField: field.key + })) + : [{ formField: '', wsmsField: '' }] +} diff --git a/frontend/src/components/AllIntegrations/Wsms/WsmsFieldMap.jsx b/frontend/src/components/AllIntegrations/Wsms/WsmsFieldMap.jsx new file mode 100644 index 00000000..777c2fb3 --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/WsmsFieldMap.jsx @@ -0,0 +1,104 @@ +import { useRecoilValue } from 'recoil' +import { $appConfigState } from '../../../GlobalStates' +import { __, sprintf } from '../../../Utils/i18nwrap' +import { SmartTagField } from '../../../Utils/StaticData/SmartTagField' +import TagifyInput from '../../Utilities/TagifyInput' +import { + addFieldMap, + delFieldMap, + handleCustomValue, + handleFieldMapping +} from '../GlobalIntegrationHelper' + +export default function WsmsFieldMap({ i, formFields, field, wsmsConf, setWsmsConf }) { + const btcbi = useRecoilValue($appConfigState) + const { isPro } = btcbi + + const requiredFlds = wsmsConf?.wsmsFields?.filter(fld => fld.required === true) || [] + const nonRequiredFlds = wsmsConf?.wsmsFields?.filter(fld => fld.required === false) || [] + + return ( +
+
+
+ + + {field.formField === 'custom' && ( + handleCustomValue(e, i, wsmsConf, setWsmsConf)} + label={__('Custom Value', 'bit-integrations')} + className="mr-2" + type="text" + value={field.customValue} + placeholder={__('Custom Value', 'bit-integrations')} + formFields={formFields} + /> + )} + + +
+ {i >= requiredFlds.length && ( + <> + + + + )} +
+
+ ) +} diff --git a/frontend/src/components/AllIntegrations/Wsms/WsmsIntegLayout.jsx b/frontend/src/components/AllIntegrations/Wsms/WsmsIntegLayout.jsx new file mode 100644 index 00000000..36b903c7 --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/WsmsIntegLayout.jsx @@ -0,0 +1,176 @@ +import { create } from 'mutative' +import MultiSelect from 'react-multiple-select-dropdown-lite' +import { useRecoilValue } from 'recoil' +import { $appConfigState } from '../../../GlobalStates' +import { __ } from '../../../Utils/i18nwrap' +import Loader from '../../Loaders/Loader' +import { checkIsPro, getProLabel } from '../../Utilities/ProUtilHelpers' +import { addFieldMap } from '../IntegrationHelpers/IntegrationHelpers' +import { generateMappedField, refreshGroups } from './WsmsCommonFunc' +import WsmsFieldMap from './WsmsFieldMap' +import { modules, wsmsStatuses, WsmsStaticData } from './staticData' + +const GROUP_ACTIONS = ['add_subscriber', 'update_subscriber', 'delete_subscriber'] +const STATUS_ACTIONS = ['add_subscriber', 'update_subscriber'] + +export default function WsmsIntegLayout({ + formID, + formFields, + wsmsConf, + setWsmsConf, + isLoading, + setIsLoading, + setSnackbar +}) { + const btcbi = useRecoilValue($appConfigState) + const { isPro } = btcbi + + const handleMainAction = value => { + setWsmsConf(prevConf => + create(prevConf, draftConf => { + draftConf.mainAction = value + draftConf.wsmsFields = WsmsStaticData[value] || [] + draftConf.field_map = generateMappedField(draftConf.wsmsFields) + // Clear identifiers from the previous action so they do not leak into the new one. + delete draftConf.groupId + delete draftConf.status + }) + ) + + if (GROUP_ACTIONS.includes(value)) { + refreshGroups(setWsmsConf, setIsLoading) + } + } + + return ( + <> +
+
+ {__('Action:', 'bit-integrations')} + handleMainAction(value)} + options={modules?.map(action => ({ + label: checkIsPro(isPro, action.is_pro) ? action.label : getProLabel(action.label), + value: action.name, + disabled: checkIsPro(isPro, action.is_pro) ? false : true + }))} + singleSelect + closeOnSelect + /> +
+ + {GROUP_ACTIONS.includes(wsmsConf?.mainAction) && ( + <> +
+
+ {__('Group:', 'bit-integrations')} + ({ + label: group.label, + value: group.value?.toString() + })) + : [] + } + onChange={val => + setWsmsConf(prevConf => + create(prevConf, draftConf => { + draftConf.groupId = val + }) + ) + } + singleSelect + closeOnSelect + /> + +
+ + )} + + {STATUS_ACTIONS.includes(wsmsConf?.mainAction) && ( + <> +
+
+ {__('Status:', 'bit-integrations')} + + setWsmsConf(prevConf => + create(prevConf, draftConf => { + draftConf.status = val + }) + ) + } + singleSelect + closeOnSelect + /> +
+ + )} + + {isLoading && ( + + )} + + {wsmsConf?.mainAction && wsmsConf.wsmsFields && wsmsConf.wsmsFields.length > 0 && ( +
+ {__('Map Fields', 'bit-integrations')} +
+
+
+ {__('Form Fields', 'bit-integrations')} +
+
+ {__('WSMS Fields', 'bit-integrations')} +
+
+ + {wsmsConf?.field_map?.map((itm, i) => ( + + ))} +
+ +
+
+
+ )} + + ) +} diff --git a/frontend/src/components/AllIntegrations/Wsms/staticData.js b/frontend/src/components/AllIntegrations/Wsms/staticData.js new file mode 100644 index 00000000..b76d511e --- /dev/null +++ b/frontend/src/components/AllIntegrations/Wsms/staticData.js @@ -0,0 +1,59 @@ +import { __ } from '../../../Utils/i18nwrap' + +export const modules = [ + { name: 'send_sms', label: __('Send SMS', 'bit-integrations'), is_pro: true }, + { name: 'add_subscriber', label: __('Add Subscriber', 'bit-integrations'), is_pro: true }, + { name: 'update_subscriber', label: __('Update Subscriber', 'bit-integrations'), is_pro: true }, + { name: 'delete_subscriber', label: __('Delete Subscriber', 'bit-integrations'), is_pro: true }, + { name: 'add_group', label: __('Add Group', 'bit-integrations'), is_pro: true }, + { name: 'update_group', label: __('Update Group', 'bit-integrations'), is_pro: true }, + { name: 'delete_group', label: __('Delete Group', 'bit-integrations'), is_pro: true } +] + +const SendSmsFields = [ + { key: 'to', label: __('To (Recipient Numbers)', 'bit-integrations'), required: true }, + { key: 'message', label: __('Message', 'bit-integrations'), required: true }, + { key: 'sender_id', label: __('Sender ID', 'bit-integrations'), required: false }, + { key: 'is_flash', label: __('Is Flash', 'bit-integrations'), required: false }, + { key: 'media_urls', label: __('Media URLs', 'bit-integrations'), required: false } +] + +const AddSubscriberFields = [ + { key: 'name', label: __('Name', 'bit-integrations'), required: true }, + { key: 'mobile', label: __('Mobile', 'bit-integrations'), required: true } +] + +const UpdateSubscriberFields = [ + { key: 'name', label: __('Name', 'bit-integrations'), required: true }, + { key: 'mobile', label: __('Mobile', 'bit-integrations'), required: true } +] + +const DeleteSubscriberFields = [ + { key: 'mobile', label: __('Mobile', 'bit-integrations'), required: true } +] + +const AddGroupFields = [{ key: 'name', label: __('Group Name', 'bit-integrations'), required: true }] + +const UpdateGroupFields = [ + { key: 'group_id', label: __('Group ID', 'bit-integrations'), required: true }, + { key: 'name', label: __('Group Name', 'bit-integrations'), required: true } +] + +const DeleteGroupFields = [ + { key: 'group_id', label: __('Group ID', 'bit-integrations'), required: true } +] + +export const WsmsStaticData = { + send_sms: SendSmsFields, + add_subscriber: AddSubscriberFields, + update_subscriber: UpdateSubscriberFields, + delete_subscriber: DeleteSubscriberFields, + add_group: AddGroupFields, + update_group: UpdateGroupFields, + delete_group: DeleteGroupFields +} + +export const wsmsStatuses = [ + { value: '1', label: __('Active', 'bit-integrations') }, + { value: '0', label: __('Inactive', 'bit-integrations') } +] diff --git a/frontend/src/components/Flow/New/SelectAction.jsx b/frontend/src/components/Flow/New/SelectAction.jsx index 9259273f..809d381a 100644 --- a/frontend/src/components/Flow/New/SelectAction.jsx +++ b/frontend/src/components/Flow/New/SelectAction.jsx @@ -180,6 +180,7 @@ export default function SelectAction() { { type: 'CreatorLms' }, { type: 'Bookly' }, { type: 'FluentCart' }, + { type: 'Wsms', name: 'WSMS (WP SMS)' }, { type: 'MoreConvert Wishlist', logo: 'moreConvertWishlist' }, { type: 'Heffl CRM' }, { type: 'Secure Custom Fields' }, diff --git a/frontend/src/resource/img/integ/wsms.svg b/frontend/src/resource/img/integ/wsms.svg new file mode 100644 index 00000000..93933e9a --- /dev/null +++ b/frontend/src/resource/img/integ/wsms.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/resource/img/integ/wsms.webp b/frontend/src/resource/img/integ/wsms.webp new file mode 100644 index 00000000..30995d99 Binary files /dev/null and b/frontend/src/resource/img/integ/wsms.webp differ