Files
EmailManager/services/storage.ts
2025-12-10 12:10:20 +01:00

106 lines
3.6 KiB
TypeScript

import { EmailTemplate } from '../types';
// Helper functions remain synchronous as they are utility functions
export const generateTemplateKey = (name: string): string => {
return name.trim().toLowerCase().replace(/\s+/g, '_').replace(/[^a-z0-9_]/g, '');
};
export const generateSQL = (template: EmailTemplate): string => {
const fullHtml = `${template.header}${template.body}${template.footer}`.replace(/'/g, "''");
const header = template.header.replace(/'/g, "''");
const body = template.body.replace(/'/g, "''");
const footer = template.footer.replace(/'/g, "''");
const subject = template.subject.replace(/'/g, "''");
const vars = JSON.stringify(template.variables).replace(/'/g, "''");
const key = generateTemplateKey(template.name);
return `INSERT INTO email_templates (id, template_key, name, description, subject, header_html, body_html, footer_html, full_html, required_variables)
VALUES ('${template.id}', '${key}', '${template.name.replace(/'/g, "''")}', '${template.description?.replace(/'/g, "''") || ''}', '${subject}', '${header}', '${body}', '${footer}', '${fullHtml}', '${vars}')
ON DUPLICATE KEY UPDATE
subject = VALUES(subject),
header_html = VALUES(header_html),
body_html = VALUES(body_html),
footer_html = VALUES(footer_html),
full_html = VALUES(full_html),
required_variables = VALUES(required_variables);`;
};
export const generateSelectSQL = (template: EmailTemplate): string => {
const key = generateTemplateKey(template.name);
return `SELECT * FROM email_templates WHERE template_key = '${key}';`;
};
export const generateN8nCode = (template: EmailTemplate): string => {
const varsMap = template.variables.map(v => ` "${v}": "REPLACE_WITH_VALUE"`).join(',\n');
const hasVars = template.variables.length > 0;
return `// n8n Code Node - Template Populator
// 1. Ensure the previous node (SQL) returns the template with 'full_html' column.
// 2. Adjust the 'item.json.full_html' path if your SQL node output is different.
for (const item of items) {
const templateHtml = item.json.full_html;
// Define your dynamic data here
const replacements = {
${hasVars ? varsMap : ' // No variables detected in this template'}
};
let finalHtml = templateHtml;
// Perform replacement
for (const [key, value] of Object.entries(replacements)) {
// Replaces {{key}} globally
finalHtml = finalHtml.replace(new RegExp('{{' + key + '}}', 'g'), value);
}
// Output the processed HTML
item.json.processed_html = finalHtml;
}
return items;`;
};
// Async API calls to replace synchronous localStorage
export const getTemplates = async (): Promise<EmailTemplate[]> => {
try {
const response = await fetch('/api/templates');
if (!response.ok) throw new Error('Failed to fetch');
return await response.json();
} catch (e) {
console.error("Failed to load templates", e);
return [];
}
};
export const saveTemplate = async (template: EmailTemplate): Promise<void> => {
try {
const response = await fetch('/api/templates', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(template),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to save');
}
} catch (e) {
console.error("Failed to save template", e);
throw e;
}
};
export const deleteTemplate = async (id: string): Promise<void> => {
try {
const response = await fetch(`/api/templates/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('Failed to delete');
} catch (e) {
console.error("Failed to delete template", e);
throw e;
}
};