Actualizar frontend/src/components/ConfigModal.jsx
This commit is contained in:
@@ -1117,58 +1117,93 @@ function SubirBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const puede = plantillaSel && telefonos.length > 0 && !enviando;
|
const puede = plantillaSel && telefonos.length > 0 && !enviando;
|
||||||
const lbl = { fontSize: 12.5, fontWeight: 700, color: "#334155", marginBottom: 8, display: "block" };
|
// Estilos iguales a Plantillas (cards radius 14, step cuadrado, labels mayúscula)
|
||||||
const card = { background: "#fff", border: "1px solid #e6eaf0", borderRadius: 12, padding: 16, marginBottom: 14 };
|
const card = { background: "#fff", border: "1px solid #e6eaf0", borderRadius: 14,
|
||||||
const num = (n) => <span style={{ width: 22, height: 22, borderRadius: 6, background: "#1e3a5f", color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center", fontSize: 12, fontWeight: 700, marginRight: 8 }}>{n}</span>;
|
padding: 20, boxShadow: "0 1px 3px rgba(15,23,42,.04)" };
|
||||||
|
const cardHead = { display: "flex", alignItems: "center", gap: 10, marginBottom: 4 };
|
||||||
|
const step = { width: 26, height: 26, borderRadius: 8, background: "#1e3a5f", color: "#fff",
|
||||||
|
display: "flex", alignItems: "center", justifyContent: "center",
|
||||||
|
fontSize: 13, fontWeight: 800, flexShrink: 0 };
|
||||||
|
const cardTitle = { fontSize: 15, fontWeight: 700, color: "#0f172a" };
|
||||||
|
const cardSub = { fontSize: 12.5, color: "#94a3b8", margin: "2px 0 14px 36px" };
|
||||||
|
const fieldLabel = { fontSize: 12, fontWeight: 700, color: "#64748b", marginBottom: 7,
|
||||||
|
textTransform: "uppercase", letterSpacing: ".02em", display: "block" };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ maxWidth: 680 }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 16, maxWidth: 1080 }}>
|
||||||
<div style={{ fontSize: 13, color: "#64748b", marginBottom: 16, lineHeight: 1.6 }}>
|
|
||||||
Sube un Excel con una columna <b>TELEFONO</b> (con código de país, ej. <code>51966319975</code>).
|
|
||||||
A cada número se le crea el contacto, se le asignan las etiquetas y el asesor que elijas, y se le
|
|
||||||
envía la plantilla. <b>Si el número no existe</b>, se borra automáticamente (contacto y conversación).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
{/* PASO 1 — Plantilla + Asesor */}
|
||||||
<div style={card}>
|
<div style={card}>
|
||||||
<label style={lbl}>{num(1)} Plantilla a enviar</label>
|
<div style={cardHead}>
|
||||||
<Select value={plantillaSel ? plantillaSel.nombre : ""}
|
<span style={step}>1</span>
|
||||||
options={[{ value: "", label: "— Elige una plantilla —" },
|
<span style={cardTitle}>Elige la plantilla y el asesor</span>
|
||||||
...plantillas.map((p) => ({ value: p.nombre, label: p.nombre }))]}
|
</div>
|
||||||
onChange={(v) => setPlantillaSel(plantillas.find((p) => p.nombre === v) || null)}
|
<div style={cardSub}>La plantilla se enviará a los números; el asesor se asignará a cada uno.</div>
|
||||||
minWidth={200} />
|
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
|
||||||
</div>
|
<div>
|
||||||
|
<label style={fieldLabel}>📄 Plantilla</label>
|
||||||
<div style={card}>
|
<Select value={plantillaSel ? plantillaSel.nombre : ""}
|
||||||
<label style={lbl}>{num(2)} Etiquetas (puedes elegir varias)</label>
|
options={[{ value: "", label: "— Elige una plantilla —" },
|
||||||
<MultiSelectEtiquetas opciones={etiquetas} seleccion={etiqSel} onToggle={toggleEtiqueta} />
|
...plantillas.map((p) => ({ value: p.nombre, label: p.nombre }))]}
|
||||||
</div>
|
onChange={(v) => setPlantillaSel(plantillas.find((p) => p.nombre === v) || null)}
|
||||||
|
minWidth={0} />
|
||||||
<div style={card}>
|
</div>
|
||||||
<label style={lbl}>{num(3)} Asignar a un asesor (solo uno)</label>
|
<div>
|
||||||
<Select value={asesorSel}
|
<label style={fieldLabel}>👤 Asesor (solo uno)</label>
|
||||||
options={[{ value: "SIN", label: "— SIN ASIGNACIÓN —" },
|
<Select value={asesorSel}
|
||||||
...asesores.map((a) => ({ value: String(a.id), label: a.nombre }))]}
|
options={[{ value: "SIN", label: "— SIN ASIGNACIÓN —" },
|
||||||
onChange={(v) => setAsesorSel(v)}
|
...asesores.map((a) => ({ value: String(a.id), label: a.nombre }))]}
|
||||||
minWidth={200} />
|
onChange={(v) => setAsesorSel(v)}
|
||||||
|
minWidth={0} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{asesorSel === "SIN" && (
|
{asesorSel === "SIN" && (
|
||||||
<div style={{ fontSize: 11.5, color: "#92400e", background: "#fffbeb", border: "1px solid #fde68a", borderRadius: 8, padding: "7px 10px", marginTop: 8 }}>
|
<div style={{ fontSize: 11.5, color: "#92400e", background: "#fffbeb", border: "1px solid #fde68a", borderRadius: 8, padding: "7px 10px", marginTop: 12 }}>
|
||||||
No se asignará ningún asesor. Si un número ya tenía asesor, se mantiene (no se quita).
|
No se asignará ningún asesor. Si un número ya tenía asesor, se mantiene (no se quita).
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* PASO 2 — Etiquetas */}
|
||||||
<div style={card}>
|
<div style={card}>
|
||||||
<label style={lbl}>{num(4)} Importar Excel</label>
|
<div style={cardHead}>
|
||||||
<label style={{ display: "inline-flex", alignItems: "center", gap: 8, cursor: "pointer", padding: "9px 16px", border: "1px solid #cbd5e1", borderRadius: 8, background: "#f8fafc", fontSize: 13, fontWeight: 600, color: "#334155" }}>
|
<span style={step}>2</span>
|
||||||
📁 Elegir archivo
|
<span style={cardTitle}>Etiquetas</span>
|
||||||
<input type="file" accept=".xlsx,.xls" onChange={importarExcel} style={{ display: "none" }} />
|
<span style={{ marginLeft: "auto", fontSize: 12, color: "#94a3b8", fontWeight: 600 }}>
|
||||||
</label>
|
{etiqSel.length} seleccionada{etiqSel.length === 1 ? "" : "s"}
|
||||||
{archivo && <span style={{ fontSize: 12.5, color: "#15803d", marginLeft: 12 }}>✓ {archivo} — {telefonos.length} número(s)</span>}
|
</span>
|
||||||
|
</div>
|
||||||
|
<div style={cardSub}>Se agregan a cada número (no borran las que ya tuviera). Puedes elegir varias.</div>
|
||||||
|
<label style={fieldLabel}>🏷️ Etiquetas de Chatwoot</label>
|
||||||
|
<MultiSelectEtiquetas opciones={etiquetas} seleccion={etiqSel} onToggle={toggleEtiqueta} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* PASO 3 — Importar Excel */}
|
||||||
|
<div style={card}>
|
||||||
|
<div style={cardHead}>
|
||||||
|
<span style={step}>3</span>
|
||||||
|
<span style={cardTitle}>Importar base</span>
|
||||||
|
</div>
|
||||||
|
<div style={cardSub}>
|
||||||
|
Excel con una columna <b>TELEFONO</b> (con código de país, ej. 51966319975).
|
||||||
|
Si un número no existe, se borra automáticamente.
|
||||||
|
</div>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
|
||||||
|
<label style={{ display: "inline-flex", alignItems: "center", gap: 8, cursor: "pointer",
|
||||||
|
padding: "10px 18px", border: "1px solid #cbd5e1", borderRadius: 9,
|
||||||
|
background: "#f8fafc", fontSize: 13.5, fontWeight: 600, color: "#334155" }}>
|
||||||
|
📁 Elegir archivo
|
||||||
|
<input type="file" accept=".xlsx,.xls" onChange={importarExcel} style={{ display: "none" }} />
|
||||||
|
</label>
|
||||||
|
{archivo && <span style={{ fontSize: 13, color: "#15803d", fontWeight: 600 }}>✓ {archivo} — {telefonos.length} número(s)</span>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button onClick={intentarEnviar} disabled={!puede}
|
<button onClick={intentarEnviar} disabled={!puede}
|
||||||
style={{ width: "100%", padding: "12px", borderRadius: 10, border: "none", background: puede ? "#1e3a5f" : "#cbd5e1", color: "#fff", fontWeight: 700, fontSize: 14, cursor: puede ? "pointer" : "default" }}>
|
style={{ width: "100%", padding: "13px", borderRadius: 11, border: "none",
|
||||||
{enviando ? "Procesando… (esto puede tardar)" : "📤 Subir base y enviar plantilla"}
|
background: puede ? "#1e3a5f" : "#cbd5e1", color: "#fff", fontWeight: 700, fontSize: 14.5,
|
||||||
|
cursor: puede ? "pointer" : "default" }}>
|
||||||
|
{enviando ? "Procesando… (esto puede tardar)" : "🚀 Subir base y enviar plantilla"}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{resultado && (
|
{resultado && (
|
||||||
|
|||||||
Reference in New Issue
Block a user