diff --git a/components/TemplateEditor.tsx b/components/TemplateEditor.tsx
index 2f57e27..c967d18 100644
--- a/components/TemplateEditor.tsx
+++ b/components/TemplateEditor.tsx
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react';
import { EmailTemplate } from '../types';
-import { saveTemplate, generateSQL, generateSelectSQL, getTemplates, generateTemplateKey, generateN8nCode } from '../services/storage';
+import { saveTemplate, generateSQL, generateSelectSQL, getTemplates, generateTemplateKey, generateN8nCode, generateUUID } from '../services/storage';
import { generateEmailContent } from '../services/geminiService';
import RichTextEditor from './RichTextEditor';
import {
@@ -15,18 +15,6 @@ interface Props {
onSave: () => void;
}
-// Fallback for crypto.randomUUID in non-secure (HTTP) contexts
-const generateUUID = () => {
- if (typeof crypto !== 'undefined' && crypto.randomUUID) {
- return crypto.randomUUID();
- }
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- const r = Math.random() * 16 | 0;
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
- return v.toString(16);
- });
-};
-
const DEFAULT_HEADER = `
La Mia Azienda
`;
@@ -78,21 +66,20 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
const newKey = generateTemplateKey(name);
if (!newKey) {
- setNameError('Il nome del template non può essere vuoto o contenere solo simboli.');
+ setNameError('Il nome del template non può essere vuoto.');
return;
}
setIsSaving(true);
+ console.log("Saving process started for:", name);
+
try {
- console.log("Inizio processo di salvataggio per:", name);
-
- // Check for duplicates
+ // 1. Get current templates to check duplicates
let allTemplates: EmailTemplate[] = [];
try {
allTemplates = await getTemplates();
} catch (err) {
- console.error("Errore durante il recupero dei template esistenti:", err);
- // Non blocchiamo necessariamente, ma avvisiamo
+ console.warn("Could not fetch templates for duplicate check, proceeding anyway...", err);
}
const isDuplicate = allTemplates.some(t => {
@@ -118,13 +105,13 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
updatedAt: new Date().toISOString()
};
- console.log("Invio dati al server...", newTemplate);
+ console.log("Sending POST to server with data:", newTemplate);
await saveTemplate(newTemplate);
- console.log("Salvataggio completato con successo");
+ console.log("Save successful!");
onSave();
} catch (e: any) {
- console.error("ERRORE SALVATAGGIO:", e);
- alert(`Errore: ${e.message || 'Impossibile salvare il template'}`);
+ console.error("SAVE ERROR DETAILS:", e);
+ alert(`Errore di salvataggio: ${e.message}`);
} finally {
setIsSaving(false);
}
@@ -231,7 +218,7 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
placeholder="es. Email di Benvenuto"
/>
{nameError && {nameError}
}
- Deve essere univoco. Usato per generare la chiave DB: {generateTemplateKey(name) || '...'}
+ Deve essere univoco. Chiave DB: {generateTemplateKey(name) || '...'}
@@ -240,7 +227,7 @@ const Editor: React.FC
= ({ initialTemplate, onBack, onSave }) => {
value={description}
onChange={e => setDescription(e.target.value)}
className="w-full px-3 py-2 border border-slate-300 rounded-md focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none bg-white resize-none text-sm"
- placeholder="Note interne (es. Usato per i nuovi iscritti)"
+ placeholder="Note interne..."
rows={2}
/>
@@ -252,18 +239,17 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
value={subject}
onChange={e => setSubject(e.target.value)}
className="w-full px-3 py-2 border border-slate-300 rounded-md focus:ring-2 focus:ring-brand-500 focus:border-brand-500 outline-none bg-white"
- placeholder="Oggetto... (supporta {{placeholder}})"
+ placeholder="Oggetto..."
/>
- Variabili Attive
- Rilevate automaticamente dal testo
+ Variabili
- {detectedVars.length === 0 &&
Nessuna variabile rilevata. Scrivi {'{{nome}}'} per aggiungerne una. }
+ {detectedVars.length === 0 &&
Nessuna variabile. Usa {'{{nome}}'}. }
{detectedVars.map(v => (
{`{{${v}}}`}
@@ -290,16 +276,14 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
-
Editor Contenuti
-
- setShowAiModal(true)}
- className="text-xs flex items-center gap-1 text-purple-600 hover:text-purple-700 font-medium bg-purple-50 px-2 py-1 rounded"
- >
-
- Genera con IA
-
-
+
Editor
+
setShowAiModal(true)}
+ className="text-xs flex items-center gap-1 text-purple-600 hover:text-purple-700 font-medium bg-purple-50 px-2 py-1 rounded"
+ >
+
+ IA
+
@@ -307,34 +291,26 @@ const Editor: React.FC
= ({ initialTemplate, onBack, onSave }) => {
key={activeTab}
value={getActiveContent()}
onChange={setActiveContent}
- placeholder={`Crea qui la sezione ${tabNames[activeTab]}...`}
+ placeholder={`Scrivi qui...`}
className="h-full shadow-sm"
/>
-
-
- Usa il pulsante "Variabile" nella toolbar per inserire placeholder come {'{{nome}}'}.
-
-
+
- Anteprima Live
+ Anteprima
-
- Renderizzato come HTML standard
-
Oggetto:
-
{subject.replace(/\{\{([\w\d_-]+)\}\}/g, (match, p1) => `${match} `)}
+
{subject}
-
@@ -349,68 +325,18 @@ const Editor: React.FC
= ({ initialTemplate, onBack, onSave }) => {
- Dettagli Integrazione
+ Integrazione
- setShowSqlModal(false)} className="text-slate-400 hover:text-slate-600">
- ×
-
+ setShowSqlModal(false)} className="text-slate-400 hover:text-slate-600 text-2xl">×
-
-
-
-
-
1. Setup (Esegui una volta nel DB)
-
-
- {currentInsertSql}
-
-
navigator.clipboard.writeText(currentInsertSql)}
- className="absolute top-2 right-2 p-2 bg-slate-700 text-white rounded hover:bg-slate-600"
- title="Copia SQL INSERT"
- >
-
-
-
-
-
-
-
2. Recupero (Nodo SQL n8n)
-
-
- {currentSelectSql}
-
-
navigator.clipboard.writeText(currentSelectSql)}
- className="absolute top-2 right-2 p-2 bg-slate-600 text-white rounded hover:bg-slate-500"
- title="Copia SQL SELECT"
- >
-
-
-
-
-
-
+
-
-
- 3. Popolamento (Nodo Codice n8n)
-
-
-
- {currentN8nCode}
-
-
navigator.clipboard.writeText(currentN8nCode)}
- className="absolute top-2 right-2 p-2 bg-white border border-slate-200 text-slate-600 rounded hover:bg-slate-50 shadow-sm"
- title="Copia Codice JS"
- >
-
-
-
-
- Incolla questo codice in un Nodo Code collegato dopo il tuo nodo SQL. Sostituisci REPLACE_WITH_VALUE con le variabili reali (es. $('NodeName').item.json.name).
-
+
SQL INSERT/UPDATE
+
{currentInsertSql}
+
+
+
JS n8n
+
{currentN8nCode}
@@ -420,34 +346,21 @@ const Editor: React.FC = ({ initialTemplate, onBack, onSave }) => {
{showAiModal && (
-
-
- Generatore Contenuti IA
-
-
- Descrivi cosa vuoi per la sezione {tabNames[activeTab]} .
- L'IA genererà il codice HTML con i placeholder necessari.
-
+
Generatore IA