added additional plugins

This commit is contained in:
Rodolfo Martinez 2025-12-12 19:05:48 -05:00
parent c85895d306
commit 00e60ec1b7
132 changed files with 27514 additions and 0 deletions

View file

@ -0,0 +1,2 @@
<?php
// Silence is golden.

View file

@ -0,0 +1,2 @@
<?php
// Silence is golden.

View file

@ -0,0 +1,206 @@
import { useState, useEffect } from '@wordpress/element';
import { Button, Spinner } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import StepOne from './components/StepOne';
import StepTwo from './components/StepTwo';
import StepThree from './components/StepThree';
import StepFour from './components/StepFour';
import StepFive from './components/StepFive';
import StepSix from './components/StepSix';
import { fetchAutomation } from './utils/api';
const WizardApp = () => {
const [currentStep, setCurrentStep] = useState(1);
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({
title: '',
form_id: '',
field_mapping: {
email: '',
firstname: '',
lastname: ''
},
trigger_field_id: '',
api_key: '',
api_secret: '',
list_mappings: {},
activate: false
});
const [forms, setForms] = useState([]);
const [fields, setFields] = useState([]);
const [triggerChoices, setTriggerChoices] = useState([]);
const [mailjetLists, setMailjetLists] = useState([]);
const totalSteps = 6;
const editId = window.wpfmjData?.editId || 0;
// Load automation if editing
useEffect(() => {
if (!editId) {
return;
}
let cancelled = false;
setLoading(true);
fetchAutomation(editId)
.then(data => {
if (!cancelled) {
setFormData({
title: data.title,
...data.config,
activate: data.status === 'publish'
});
}
})
.catch(error => {
if (!cancelled) {
alert('Error loading automation: ' + error.message);
}
})
.finally(() => {
if (!cancelled) {
setLoading(false);
}
});
return () => {
cancelled = true;
};
}, [editId]);
const updateFormData = (field, value) => {
setFormData(prev => ({
...prev,
[field]: value
}));
};
const nextStep = () => {
if (currentStep < totalSteps) {
setCurrentStep(currentStep + 1);
}
};
const prevStep = () => {
if (currentStep > 1) {
setCurrentStep(currentStep - 1);
}
};
const renderStep = () => {
const stepProps = {
formData,
updateFormData,
forms,
setForms,
fields,
setFields,
triggerChoices,
setTriggerChoices,
mailjetLists,
setMailjetLists,
nextStep,
setLoading
};
switch (currentStep) {
case 1:
return <StepOne {...stepProps} />;
case 2:
return <StepTwo {...stepProps} />;
case 3:
return <StepThree {...stepProps} />;
case 4:
return <StepFour {...stepProps} />;
case 5:
return <StepFive {...stepProps} />;
case 6:
return <StepSix {...stepProps} editId={editId} />;
default:
return null;
}
};
const renderProgress = () => {
const steps = [
__('Choose Form', 'wpforms-mailjet-automation'),
__('Map Fields', 'wpforms-mailjet-automation'),
__('Trigger Field', 'wpforms-mailjet-automation'),
__('Connect Mailjet', 'wpforms-mailjet-automation'),
__('Map Lists', 'wpforms-mailjet-automation'),
__('Review', 'wpforms-mailjet-automation')
];
return (
<ul className="wpfmj-wizard-progress">
{steps.map((step, index) => {
const stepNumber = index + 1;
const isActive = currentStep === stepNumber;
const isCompleted = currentStep > stepNumber;
const className = isActive ? 'active' : isCompleted ? 'completed' : '';
return (
<li key={stepNumber} className={className}>
{step}
</li>
);
})}
</ul>
);
};
if (loading) {
return (
<div style={{ padding: '40px', textAlign: 'center' }}>
<Spinner />
<p>{__('Loading...', 'wpforms-mailjet-automation')}</p>
</div>
);
}
return (
<div className="wpfmj-wizard-container">
<div className="wpfmj-wizard-header">
{renderProgress()}
</div>
<div className="wpfmj-wizard-body">
{renderStep()}
</div>
<div className="wpfmj-wizard-footer">
<div>
{currentStep > 1 && (
<Button
variant="secondary"
onClick={prevStep}
disabled={loading}
>
{__('Previous', 'wpforms-mailjet-automation')}
</Button>
)}
</div>
<div>
{currentStep < totalSteps && (
<Button
variant="primary"
onClick={nextStep}
disabled={loading}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
)}
</div>
</div>
</div>
);
};
// Mount the app
document.addEventListener('DOMContentLoaded', () => {
const rootElement = document.getElementById('wpfmj-wizard-root');
if (rootElement) {
wp.element.render(<WizardApp />, rootElement);
}
});
export default WizardApp;

View file

@ -0,0 +1,101 @@
import { SelectControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
const StepFive = ({ formData, updateFormData, triggerChoices, mailjetLists, nextStep }) => {
const handleNext = () => {
const hasMapping = Object.keys(formData.list_mappings).length > 0;
if (!hasMapping) {
alert(__('Please map at least one answer to a Mailjet list', 'wpforms-mailjet-automation'));
return;
}
nextStep();
};
const updateListMapping = (choiceValue, listId) => {
const newMappings = { ...formData.list_mappings };
if (listId === '') {
// Remove mapping if empty
delete newMappings[choiceValue];
} else {
newMappings[choiceValue] = listId;
}
updateFormData('list_mappings', newMappings);
};
// Get list of already selected lists to prevent duplicates
const getAvailableLists = (currentChoiceValue) => {
const usedListIds = Object.entries(formData.list_mappings)
.filter(([key]) => key !== currentChoiceValue)
.map(([, listId]) => listId);
return mailjetLists.filter(list => !usedListIds.includes(list.id.toString()));
};
const listOptions = (choiceValue) => {
const available = getAvailableLists(choiceValue);
return [
{ label: __('Select a list...', 'wpforms-mailjet-automation'), value: '' },
...available.map(list => ({
label: list.name,
value: list.id.toString()
}))
];
};
return (
<div className="wpfmj-step">
<h2>{__('Map Answers to Mailjet Lists', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Map each answer from your trigger field to a Mailjet list. When someone selects an answer, they\'ll be added to the corresponding list. Each list can only be used once.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-two-column">
<div className="wpfmj-column">
<h3>{__('Form Answers', 'wpforms-mailjet-automation')}</h3>
{triggerChoices.map((choice) => (
<div key={choice.value} className="wpfmj-mapping-row">
<div className="wpfmj-answer">{choice.label}</div>
</div>
))}
</div>
<div className="wpfmj-column">
<h3>{__('Mailjet Lists', 'wpforms-mailjet-automation')}</h3>
{triggerChoices.map((choice) => (
<div key={choice.value} className="wpfmj-mapping-row">
<SelectControl
value={formData.list_mappings[choice.value] || ''}
options={listOptions(choice.value)}
onChange={(value) => updateListMapping(choice.value, value)}
/>
</div>
))}
</div>
</div>
{mailjetLists.length === 0 && (
<div className="wpfmj-alert wpfmj-alert-error">
{__('No Mailjet lists found. Please create lists in your Mailjet account first.', 'wpforms-mailjet-automation')}
</div>
)}
<div className="wpfmj-alert wpfmj-alert-info" style={{ marginTop: '20px' }}>
<strong>{__('Note:', 'wpforms-mailjet-automation')}</strong> {__('For checkbox fields, users can select multiple answers, and they will be added to multiple lists accordingly.', 'wpforms-mailjet-automation')}
</div>
<Button
variant="primary"
onClick={handleNext}
disabled={mailjetLists.length === 0}
style={{ marginTop: '20px' }}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
</div>
);
};
export default StepFive;

View file

@ -0,0 +1,112 @@
import { useState } from '@wordpress/element';
import { TextControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { testMailjetConnection, fetchMailjetLists } from '../utils/api';
const StepFour = ({ formData, updateFormData, setMailjetLists, setLoading, nextStep }) => {
const [testing, setTesting] = useState(false);
const [tested, setTested] = useState(false);
const [testSuccess, setTestSuccess] = useState(false);
const handleTest = async () => {
if (!formData.api_key || !formData.api_secret) {
alert(__('Please enter both API Key and API Secret', 'wpforms-mailjet-automation'));
return;
}
setTesting(true);
try {
await testMailjetConnection(formData.api_key, formData.api_secret);
setTestSuccess(true);
setTested(true);
// Automatically fetch lists after successful connection
const lists = await fetchMailjetLists(formData.api_key, formData.api_secret);
setMailjetLists(lists);
} catch (error) {
setTestSuccess(false);
setTested(true);
alert(__('Connection failed: ', 'wpforms-mailjet-automation') + error.message);
} finally {
setTesting(false);
}
};
const handleNext = () => {
if (!tested || !testSuccess) {
alert(__('Please test your API connection first', 'wpforms-mailjet-automation'));
return;
}
nextStep();
};
return (
<div className="wpfmj-step">
<h2>{__('Connect to Mailjet', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Enter your Mailjet API credentials. You can find these in your Mailjet account under Account Settings > REST API.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-field-group">
<TextControl
label={__('API Key', 'wpforms-mailjet-automation')}
value={formData.api_key}
onChange={(value) => {
updateFormData('api_key', value);
setTested(false);
}}
type="text"
placeholder={__('Enter your Mailjet API Key', 'wpforms-mailjet-automation')}
/>
</div>
<div className="wpfmj-field-group">
<TextControl
label={__('API Secret', 'wpforms-mailjet-automation')}
value={formData.api_secret}
onChange={(value) => {
updateFormData('api_secret', value);
setTested(false);
}}
type="password"
placeholder={__('Enter your Mailjet API Secret', 'wpforms-mailjet-automation')}
/>
</div>
<div style={{ marginBottom: '20px' }}>
<Button
variant="secondary"
onClick={handleTest}
isBusy={testing}
disabled={testing || !formData.api_key || !formData.api_secret}
>
{testing ? __('Testing...', 'wpforms-mailjet-automation') : __('Test Connection', 'wpforms-mailjet-automation')}
</Button>
</div>
{tested && testSuccess && (
<div className="wpfmj-alert wpfmj-alert-success">
{__('✓ Connection successful! Your Mailjet account is connected.', 'wpforms-mailjet-automation')}
</div>
)}
{tested && !testSuccess && (
<div className="wpfmj-alert wpfmj-alert-error">
{__('✗ Connection failed. Please check your credentials and try again.', 'wpforms-mailjet-automation')}
</div>
)}
<Button
variant="primary"
onClick={handleNext}
disabled={!tested || !testSuccess}
style={{ marginTop: '20px' }}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
</div>
);
};
export default StepFour;

View file

@ -0,0 +1,96 @@
import { useEffect } from '@wordpress/element';
import { SelectControl, TextControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { fetchForms } from '../utils/api';
const StepOne = ({ formData, updateFormData, forms, setForms, setLoading, nextStep }) => {
useEffect(() => {
if (forms.length > 0) {
return;
}
let cancelled = false;
setLoading(true);
fetchForms()
.then(data => {
if (!cancelled) {
setForms(data);
}
})
.catch(error => {
if (!cancelled) {
alert('Error loading forms: ' + error.message);
}
})
.finally(() => {
if (!cancelled) {
setLoading(false);
}
});
return () => {
cancelled = true;
};
}, [forms.length, setForms, setLoading]);
const handleNext = () => {
if (!formData.title) {
alert(__('Please enter an automation title', 'wpforms-mailjet-automation'));
return;
}
if (!formData.form_id) {
alert(__('Please select a form', 'wpforms-mailjet-automation'));
return;
}
nextStep();
};
const formOptions = [
{ label: __('Select a form...', 'wpforms-mailjet-automation'), value: '' },
...forms.map(form => ({
label: form.title,
value: form.id.toString()
}))
];
return (
<div className="wpfmj-step">
<h2>{__('Create Your Automation', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Give your automation a name and select which WPForms form you want to connect to Mailjet.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-field-group">
<TextControl
label={__('Automation Title', 'wpforms-mailjet-automation')}
value={formData.title}
onChange={(value) => updateFormData('title', value)}
placeholder={__('e.g., Newsletter Signup Automation', 'wpforms-mailjet-automation')}
help={__('This is only for your reference and won\'t be shown to users.', 'wpforms-mailjet-automation')}
/>
</div>
<div className="wpfmj-field-group">
<SelectControl
label={__('Select WPForm', 'wpforms-mailjet-automation')}
value={formData.form_id}
options={formOptions}
onChange={(value) => updateFormData('form_id', value)}
help={__('Choose the form that will trigger this automation.', 'wpforms-mailjet-automation')}
/>
</div>
<Button
variant="primary"
onClick={handleNext}
style={{ marginTop: '20px' }}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
</div>
);
};
export default StepOne;

View file

@ -0,0 +1,134 @@
import { useState } from '@wordpress/element';
import { Button, CheckboxControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { saveAutomation } from '../utils/api';
const StepSix = ({ formData, updateFormData, forms, fields, triggerChoices, mailjetLists, editId }) => {
const [saving, setSaving] = useState(false);
const handleSave = async (activate) => {
setSaving(true);
updateFormData('activate', activate);
try {
const result = await saveAutomation({ ...formData, activate }, editId);
alert(__('Automation saved successfully!', 'wpforms-mailjet-automation'));
window.location.href = 'admin.php?page=wpfmj-dashboard';
} catch (error) {
alert(__('Error saving automation: ', 'wpforms-mailjet-automation') + error.message);
} finally {
setSaving(false);
}
};
const getFormName = () => {
const form = forms.find(f => f.id.toString() === formData.form_id);
return form ? form.title : formData.form_id;
};
const getFieldName = (fieldId) => {
const field = fields.find(f => f.id.toString() === fieldId);
return field ? field.label : fieldId;
};
const getTriggerFieldName = () => {
return getFieldName(formData.trigger_field_id);
};
const getListName = (listId) => {
const list = mailjetLists.find(l => l.id.toString() === listId);
return list ? list.name : listId;
};
const getChoiceLabel = (choiceValue) => {
const choice = triggerChoices.find(c => c.value === choiceValue);
return choice ? choice.label : choiceValue;
};
return (
<div className="wpfmj-step">
<h2>{__('Review & Save', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Review your automation settings below. Once you\'re happy with everything, choose whether to save as a draft or save and activate immediately.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-review-section">
<h3>{__('Basic Information', 'wpforms-mailjet-automation')}</h3>
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('Automation Title:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{formData.title}</div>
</div>
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('Form:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{getFormName()}</div>
</div>
</div>
<div className="wpfmj-review-section">
<h3>{__('Field Mapping', 'wpforms-mailjet-automation')}</h3>
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('Email Field:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{getFieldName(formData.field_mapping.email)}</div>
</div>
{formData.field_mapping.firstname && (
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('First Name Field:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{getFieldName(formData.field_mapping.firstname)}</div>
</div>
)}
{formData.field_mapping.lastname && (
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('Last Name Field:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{getFieldName(formData.field_mapping.lastname)}</div>
</div>
)}
<div className="wpfmj-review-item">
<div className="wpfmj-review-label">{__('Trigger Field:', 'wpforms-mailjet-automation')}</div>
<div className="wpfmj-review-value">{getTriggerFieldName()}</div>
</div>
</div>
<div className="wpfmj-review-section">
<h3>{__('List Mappings', 'wpforms-mailjet-automation')}</h3>
{Object.entries(formData.list_mappings).map(([choiceValue, listId]) => (
<div key={choiceValue} className="wpfmj-review-item">
<div className="wpfmj-review-label">{getChoiceLabel(choiceValue)}:</div>
<div className="wpfmj-review-value">{getListName(listId)}</div>
</div>
))}
</div>
<div className="wpfmj-alert wpfmj-alert-info">
<strong>{__('What happens next?', 'wpforms-mailjet-automation')}</strong>
<ul style={{ margin: '10px 0 0 20px' }}>
<li>{__('When someone submits the selected form, the automation will check their answers', 'wpforms-mailjet-automation')}</li>
<li>{__('Based on their selections in the trigger field, they\'ll be added to the corresponding Mailjet list(s)', 'wpforms-mailjet-automation')}</li>
<li>{__('If the API call fails, the system will retry up to 3 times with exponential backoff', 'wpforms-mailjet-automation')}</li>
<li>{__('If all retries fail, you\'ll receive an email notification', 'wpforms-mailjet-automation')}</li>
<li>{__('You can view all automation activity and errors in the dashboard', 'wpforms-mailjet-automation')}</li>
</ul>
</div>
<div style={{ marginTop: '30px', display: 'flex', gap: '10px' }}>
<Button
variant="secondary"
onClick={() => handleSave(false)}
isBusy={saving}
disabled={saving}
>
{__('Save as Draft', 'wpforms-mailjet-automation')}
</Button>
<Button
variant="primary"
onClick={() => handleSave(true)}
isBusy={saving}
disabled={saving}
>
{__('Save & Activate', 'wpforms-mailjet-automation')}
</Button>
</div>
</div>
);
};
export default StepSix;

View file

@ -0,0 +1,80 @@
import { SelectControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
const StepThree = ({ formData, updateFormData, fields, setTriggerChoices, nextStep }) => {
const handleNext = () => {
if (!formData.trigger_field_id) {
alert(__('Please select a trigger field', 'wpforms-mailjet-automation'));
return;
}
// Find the selected field and extract its choices
const triggerField = fields.find(f => f.id.toString() === formData.trigger_field_id);
if (triggerField && triggerField.choices) {
setTriggerChoices(triggerField.choices);
}
nextStep();
};
// Filter fields to only show those with choices (checkbox, radio, select, etc.)
const triggerFieldOptions = [
{ label: __('Select a field...', 'wpforms-mailjet-automation'), value: '' },
...fields
.filter(field => field.choices && field.choices.length > 0)
.map(field => ({
label: `${field.label} (${field.type})`,
value: field.id.toString()
}))
];
const selectedField = fields.find(f => f.id.toString() === formData.trigger_field_id);
return (
<div className="wpfmj-step">
<h2>{__('Choose Trigger Field', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Select the field that will determine which Mailjet lists the contact is added to. This should be a field with multiple choice options like checkboxes, radio buttons, or dropdowns.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-field-group">
<SelectControl
label={__('Trigger Field', 'wpforms-mailjet-automation')}
value={formData.trigger_field_id}
options={triggerFieldOptions}
onChange={(value) => updateFormData('trigger_field_id', value)}
help={__('The answers to this field will determine which Mailjet lists the contact is added to.', 'wpforms-mailjet-automation')}
/>
</div>
{selectedField && selectedField.choices && (
<div className="wpfmj-alert wpfmj-alert-info">
<strong>{__('Field Preview:', 'wpforms-mailjet-automation')}</strong>
<ul style={{ margin: '10px 0 0 20px' }}>
{selectedField.choices.map((choice, index) => (
<li key={index}>{choice.label}</li>
))}
</ul>
</div>
)}
{triggerFieldOptions.length === 1 && (
<div className="wpfmj-alert wpfmj-alert-error">
{__('This form doesn\'t have any fields with multiple choice options. Please add checkbox, radio, or dropdown fields to your form first.', 'wpforms-mailjet-automation')}
</div>
)}
<Button
variant="primary"
onClick={handleNext}
disabled={triggerFieldOptions.length === 1}
style={{ marginTop: '20px' }}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
</div>
);
};
export default StepThree;

View file

@ -0,0 +1,109 @@
import { useEffect } from '@wordpress/element';
import { SelectControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { fetchFormFields } from '../utils/api';
const StepTwo = ({ formData, updateFormData, fields, setFields, setLoading, nextStep }) => {
useEffect(() => {
if (!formData.form_id || fields.length > 0) {
return;
}
let cancelled = false;
setLoading(true);
fetchFormFields(formData.form_id)
.then(data => {
if (!cancelled) {
setFields(data);
}
})
.catch(error => {
if (!cancelled) {
alert('Error loading form fields: ' + error.message);
}
})
.finally(() => {
if (!cancelled) {
setLoading(false);
}
});
return () => {
cancelled = true;
};
}, [formData.form_id, fields.length, setFields, setLoading]);
const handleNext = () => {
if (!formData.field_mapping.email) {
alert(__('Please select an email field', 'wpforms-mailjet-automation'));
return;
}
nextStep();
};
const updateFieldMapping = (field, value) => {
updateFormData('field_mapping', {
...formData.field_mapping,
[field]: value
});
};
const fieldOptions = [
{ label: __('Select a field...', 'wpforms-mailjet-automation'), value: '' },
...fields.map(field => ({
label: field.label,
value: field.id.toString()
}))
];
return (
<div className="wpfmj-step">
<h2>{__('Map Contact Fields', 'wpforms-mailjet-automation')}</h2>
<p className="description">
{__('Map your form fields to Mailjet contact properties. Email is required, while first name and last name are optional.', 'wpforms-mailjet-automation')}
</p>
<div className="wpfmj-field-group">
<SelectControl
label={__('Email Field', 'wpforms-mailjet-automation') + ' *'}
value={formData.field_mapping.email}
options={fieldOptions}
onChange={(value) => updateFieldMapping('email', value)}
help={__('Required. This field will be used as the contact email address.', 'wpforms-mailjet-automation')}
/>
</div>
<div className="wpfmj-field-group">
<SelectControl
label={__('First Name Field', 'wpforms-mailjet-automation')}
value={formData.field_mapping.firstname}
options={fieldOptions}
onChange={(value) => updateFieldMapping('firstname', value)}
help={__('Optional. If selected, this will populate the contact\'s first name in Mailjet.', 'wpforms-mailjet-automation')}
/>
</div>
<div className="wpfmj-field-group">
<SelectControl
label={__('Last Name Field', 'wpforms-mailjet-automation')}
value={formData.field_mapping.lastname}
options={fieldOptions}
onChange={(value) => updateFieldMapping('lastname', value)}
help={__('Optional. If selected, this will populate the contact\'s last name in Mailjet.', 'wpforms-mailjet-automation')}
/>
</div>
<Button
variant="primary"
onClick={handleNext}
style={{ marginTop: '20px' }}
>
{__('Next', 'wpforms-mailjet-automation')}
</Button>
</div>
);
};
export default StepTwo;

View file

@ -0,0 +1,2 @@
<?php
// Silence is golden.

View file

@ -0,0 +1,2 @@
<?php
// Silence is golden.

View file

@ -0,0 +1,107 @@
/**
* API utility functions for AJAX calls
*/
const { ajaxUrl, ajaxNonce } = window.wpfmjData || {};
/**
* Make AJAX request
*/
const makeRequest = async (action, data = {}) => {
const formData = new FormData();
formData.append('action', action);
formData.append('nonce', ajaxNonce);
Object.keys(data).forEach(key => {
if (typeof data[key] === 'object') {
formData.append(key, JSON.stringify(data[key]));
} else {
formData.append(key, data[key]);
}
});
const response = await fetch(ajaxUrl, {
method: 'POST',
body: formData
});
const result = await response.json();
if (!result.success) {
throw new Error(result.data || 'Request failed');
}
return result.data;
};
/**
* Fetch all WPForms
*/
export const fetchForms = async () => {
return await makeRequest('wpfmj_get_forms');
};
/**
* Fetch form fields
*/
export const fetchFormFields = async (formId) => {
return await makeRequest('wpfmj_get_form_fields', { form_id: formId });
};
/**
* Test Mailjet connection
*/
export const testMailjetConnection = async (apiKey, apiSecret) => {
return await makeRequest('wpfmj_test_mailjet', {
api_key: apiKey,
api_secret: apiSecret
});
};
/**
* Fetch Mailjet lists
*/
export const fetchMailjetLists = async (apiKey, apiSecret) => {
return await makeRequest('wpfmj_get_mailjet_lists', {
api_key: apiKey,
api_secret: apiSecret
});
};
/**
* Save automation
*/
export const saveAutomation = async (data, editId = 0) => {
return await makeRequest('wpfmj_save_automation', {
data: data,
edit_id: editId
});
};
/**
* Fetch automation
*/
export const fetchAutomation = async (id) => {
return await makeRequest('wpfmj_get_automation', { id });
};
/**
* Toggle automation status
*/
export const toggleAutomation = async (id) => {
return await makeRequest('wpfmj_toggle_automation', { id });
};
/**
* Delete automation
*/
export const deleteAutomation = async (id) => {
return await makeRequest('wpfmj_delete_automation', { id });
};
/**
* Get dashboard data
*/
export const fetchDashboardData = async () => {
return await makeRequest('wpfmj_get_dashboard_data');
};

View file

@ -0,0 +1,2 @@
<?php
// Silence is golden.