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 (
setOpen( ( prev ) => ! prev ) }
transitionDuration={ 0.2 }
className="z-[100000]"
>
{ isLoading ? (
<>
>
) : (
<>
{ truncateText(
formState?.template_name
? formState.template_name
: 'New SMS Template'
) }
}
iconPosition="left"
size="sm"
tag="button"
type="button"
variant="primary"
onClick={ handleSubmit }
disabled={ isSubmitting }
>
{ isSubmitting
? 'Saving...'
: 'Save Changes' }
>
) }
}
iconPosition="left"
size="sm"
tag="button"
type="button"
variant="primary"
onClick={ handleSubmit }
disabled={ isSubmitting }
>
{ isSubmitting ? 'Saving...' : 'Save Changes' }
{ isLoading ? (
) : (
<>
{ errors.submit && (
) }
>
) }
);
};
export default SmsTemplatesDrawer;
About - Traditional House Signs -Meadow Place House Signs
Established in 1970, here at Meadow Place House Signs we have been proud to supply new and established customers with unique handmade and traditional house signs and numbers for over 51 years.
We provide tough weather-resistant name signs and numbers that are made from reinforced resin. Completed with a long-lasting gloss or matt finish so your house can look stylish whatever the weather.
All of our elegant house signs are hand finished and can be enhanced by one of our finely detailed sculptures or tasteful flourishes of your choice. You can choose from a range of sculptures such as flowers, birds, wildlife or animals to add that individual touch to your sign.
Our bespoke traditional house signs are available in a range of shapes including ovals, moon tops and rectangles and can be detailed with beautiful sculptures or flourishes. You don’t need to worry about rust or corrosion of your house sign as all of our handmade products are coated in weather-resistant acrylic. We promise to give you a high-quality house sign that has been hand finished with several coats of permanent white, black, silver or gold enamel so they won’t crack or fade.
Simply choose a blank house sign then add your own text, name or number and add a sculpture of flourish to finish it off. We offer free UK delivery within 28 days of your order being placed so you can enjoy your handmade house sign as soon as possible.
If you have a particular request get in touch with us today to discuss how we can work with you to create your bespoke handmade house signs.