import { useState, useEffect } from 'react';
import { Drawer, Button, toast } from '@bsf/force-ui';
import { CheckIcon } from '@heroicons/react/24/outline';
import { __ } from '@wordpress/i18n';
import parse from 'html-react-parser';
import { doApiFetch } from '@Store';
import SkeletonLoader from '@Components/common/skeletons/SkeletonLoader';
import SmsTemplatesDrawerBody from './SmsTemplatesDrawerBody';
const SmsTemplatesDrawer = ( { open, setOpen, template, onSave } ) => {
const [ formState, setFormState ] = useState( {
template_name: '',
sms_body: `Hi {{customer.firstname}}! You left {{cart.product.names}} in your cart. Complete your order before it’s gone: {{cart.checkout_url}}`,
sms_frequency: 10,
sms_frequency_unit: 'MINUTE',
is_activated: false,
override_global_coupon: false,
discount_type: 'percent',
coupon_amount: '',
coupon_expiry_date: 1,
coupon_expiry_unit: 'days',
auto_coupon: false,
free_shipping_coupon: false,
individual_use_only: false,
exclude_product_ids: '',
enable_sms_rule_engine: false,
sms_rule_engine: [],
} );
const [ isSubmitting, setIsSubmitting ] = useState( false );
const [ isLoading, setIsLoading ] = useState( true );
const [ errors, setErrors ] = useState( {} );
useEffect( () => {
setIsLoading( true );
if ( template ) {
setFormState( {
...template,
} );
} else {
// Reset form for new template with default values
setFormState( {
template_name: '',
sms_body: `Hi {{customer.firstname}}! You left {{cart.product.names}} in your cart. Complete your order before it’s gone: {{cart.checkout_url}}`,
sms_frequency: 10,
sms_frequency_unit: 'MINUTE',
is_activated: false,
override_global_coupon: false,
discount_type: 'percent',
coupon_amount: '',
coupon_expiry_date: 1,
coupon_expiry_unit: 'days',
auto_coupon: false,
free_shipping_coupon: false,
individual_use_only: false,
exclude_product_ids: '',
enable_sms_rule_engine: false,
sms_rule_engine: [],
} );
}
setErrors( {} );
setIsLoading( false );
}, [ template, open ] );
const handleChange = ( name, value ) => {
setFormState( ( prev ) => {
return { ...prev, [ name ]: value };
} );
// Clear error for this field if it exists
if ( errors[ name ] ) {
setErrors( { ...errors, [ name ]: null } );
}
};
const isEmptyStringOrArray = ( val ) => {
return (
( typeof val === 'string' && val.trim() === '' ) ||
( Array.isArray( val ) && val.length === 0 )
);
};
const validateForm = () => {
const newErrors = {};
if ( ! formState.template_name.trim() ) {
newErrors.template_name = __(
'Template name is required',
'woo-cart-abandonment-recovery'
);
}
if ( ! formState.sms_body.trim() ) {
newErrors.email_body = __(
'SMS body is required',
'woo-cart-abandonment-recovery'
);
}
if ( formState.email_frequency < 1 ) {
newErrors.email_frequency = __(
'Time should be minimum 1 min.',
'woo-cart-abandonment-recovery'
);
}
if ( formState.sms_body.length > 160 ) {
newErrors.sms = __(
'SMS body should be less than 160 characters.',
'woo-cart-abandonment-recovery'
);
}
if (
! [ '', '0', false ].includes( formState?.enable_sms_rule_engine )
) {
let rules = formState.sms_rule_engine || [];
if ( typeof rules === 'string' ) {
try {
rules = JSON.parse( rules );
} catch ( e ) {
newErrors.sms_rule_engine = __(
'Invalid JSON in rule engine',
'woo-cart-abandonment-recovery'
);
return false;
}
}
if (
rules.length === 0 ||
rules.some(
( group ) =>
group.rules &&
group.rules.some(
( rule ) =>
isEmptyStringOrArray( rule.condition ) ||
isEmptyStringOrArray( rule.value ) ||
isEmptyStringOrArray( rule.operator )
)
)
) {
newErrors.sms_rule_engine = __(
'Missing fields in rule: condition, operator, or value.',
'woo-cart-abandonment-recovery'
);
}
}
setErrors( newErrors );
if ( Object.keys( newErrors ).length !== 0 ) {
toast.error( 'Error!', {
description: parse( Object.values( newErrors ).join( '
' ) ),
} );
return false;
}
return true;
};
const handleSubmit = () => {
if ( ! validateForm() ) {
return;
}
setIsSubmitting( true );
const formData = new window.FormData();
// Set the full option name in the form data
formData.append( 'wcf_template_name', formState.template_name );
formData.append( 'wcf_sms_body', formState.sms_body );
formData.append( 'wcf_sms_frequency', formState.sms_frequency );
formData.append(
'wcf_sms_frequency_unit',
formState.sms_frequency_unit
);
formData.append(
'wcf_activate_sms_template',
formState.is_activated ? '1' : ''
);
formData.append(
'wcf_override_global_coupon',
formState.override_global_coupon ? '1' : ''
);
formData.append( 'wcf_discount_type', formState.discount_type );
formData.append( 'wcf_coupon_amount', formState.coupon_amount );
formData.append(
'wcf_coupon_expiry_date',
formState.coupon_expiry_date
);
formData.append(
'wcf_coupon_expiry_unit',
formState.coupon_expiry_unit
);
formData.append(
'wcf_exclude_product_ids',
formState.exclude_product_ids
);
formData.append( 'wcf_auto_coupon', formState.auto_coupon ? '1' : '' );
formData.append(
'wcf_free_shipping_coupon',
formState.free_shipping_coupon ? '1' : ''
);
formData.append(
'wcf_individual_use_only',
formState.individual_use_only ? '1' : ''
);
formData.append(
'wcf_enable_sms_rule_engine',
formState?.enable_sms_rule_engine ? '1' : ''
);
formData.append(
'wcf_sms_rule_engine',
JSON.stringify( formState?.sms_rule_engine || [] )
);
// Add template ID if editing
if ( template?.id ) {
formData.append( 'id', template.id );
formData.append( 'action', 'wcar_pro_update_sms_template' );
formData.append(
'security',
cart_abandonment_admin?.update_sms_template_nonce
);
} else {
formData.append( 'action', 'wcar_pro_save_sms_template' );
formData.append(
'security',
cart_abandonment_admin?.save_sms_template_nonce
);
}
const ajaxUrl = cart_abandonment_admin?.ajax_url || window.ajaxurl;
// Make API call
doApiFetch(
ajaxUrl,
formData,
'POST',
( response ) => {
if ( response.success ) {
// Call the parent's onSave callback with the updated template
onSave( response.data.template );
toast.success( 'Success!', {
description: __(
'Template saved successfully',
'woo-cart-abandonment-recovery'
),
} );
} else {
toast.success( 'Error!', {
description:
response.data.message ||
__(
'Failed to save template',
'woo-cart-abandonment-recovery'
),
} );
}
},
( error ) => {
toast.error( 'Error!', {
description:
error.message ||
__(
'Failed to save template',
'woo-cart-abandonment-recovery'
),
} );
},
true
).finally( () => {
setIsSubmitting( false );
} );
};
const truncateText = ( text, maxLength = 60 ) => {
return text.length > maxLength
? text.slice( 0, maxLength ) + '...'
: text;
};
return (
{ errors.submit }
Several coats of tough weather-resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The edge of each shed sign is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post Dad’s / Grandad’s / Mum’s / Grandma’s Shed Sign 290mm x 100mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather-resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each of our beware of the dog signs is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post RECTANGLE.4 Beware of the Dog 210mm x 55mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post TRADITIONAL.4 228mm x 305mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post RECTANGLE.1 456mm x 100mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined in gold unless you request a colour.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post REC.3 415mm x 140mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post VERTICAL.1 100mm x 456mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post TRADITIONAL.1 456mm x 100mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post RECTANGLE.4 210mm x 55mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined in gold unless you request a colour.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post RECTANGLE.2 305mm x 100mm appeared first on Meadow Place House Signs.
]]>Several coats of tough weather resistant acrylic paint are applied to each sign with its raised lettering and traditional edge moulding, resulting in a lasting and beautiful gloss or matt finish.
The sculptures and flourishes are meticulously painted and finished by hand.
The edge of each plaque is coach lined to compliment your colour choice of letters or numbers.
All plaques are supplied with holes, screws and rawl plugs ready to install.
The post TRADITIONAL.2 290mm x 100mm appeared first on Meadow Place House Signs.
]]>