feat: boton sincronizar respuestas por correo
This commit is contained in:
1 parent
2594c6a315
commit
2502de4e06
2 files changed
+62
No files matched your search
@@ -6,6 +6,7 @@ import {
|
|||||||
updateEmailTemplate,
|
updateEmailTemplate,
|
||||||
getEmailLog,
|
getEmailLog,
|
||||||
sendTestEmail,
|
sendTestEmail,
|
||||||
|
syncInboundEmail,
|
||||||
type EmailTemplate,
|
type EmailTemplate,
|
||||||
type EmailLogEntry,
|
type EmailLogEntry,
|
||||||
} from "@/lib/api";
|
} from "@/lib/api";
|
||||||
@@ -42,6 +43,8 @@ export default function EmailPage() {
|
|||||||
const [testTo, setTestTo] = useState("");
|
const [testTo, setTestTo] = useState("");
|
||||||
const [testResult, setTestResult] = useState<{ ok: boolean; text: string } | null>(null);
|
const [testResult, setTestResult] = useState<{ ok: boolean; text: string } | null>(null);
|
||||||
const [testing, setTesting] = useState(false);
|
const [testing, setTesting] = useState(false);
|
||||||
|
const [syncing, setSyncing] = useState(false);
|
||||||
|
const [syncResult, setSyncResult] = useState<{ ok: boolean; text: string } | null>(null);
|
||||||
|
|
||||||
const fetchData = useCallback(async () => {
|
const fetchData = useCallback(async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -118,6 +121,24 @@ export default function EmailPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSync = async () => {
|
||||||
|
setSyncing(true);
|
||||||
|
setSyncResult(null);
|
||||||
|
try {
|
||||||
|
const r = await syncInboundEmail();
|
||||||
|
setSyncResult({
|
||||||
|
ok: r.success,
|
||||||
|
text: r.success
|
||||||
|
? `Revisados: ${r.checkedCount}, agregados al ticket: ${r.inserted}, omitidos: ${r.skipped}${r.error ? ` (${r.error})` : ""}`
|
||||||
|
: r.error || "Error en la sincronización",
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
setSyncResult({ ok: false, text: err instanceof Error ? err.message : "Error en la sincronización" });
|
||||||
|
} finally {
|
||||||
|
setSyncing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (!authLoading && user?.role !== "admin") {
|
if (!authLoading && user?.role !== "admin") {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -243,6 +264,37 @@ export default function EmailPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="card mb-4">
|
||||||
|
<div className="card-body">
|
||||||
|
<h6 className="fw-semibold mb-3">
|
||||||
|
<i className="bi bi-inbox me-2"></i>
|
||||||
|
Respuestas por correo
|
||||||
|
</h6>
|
||||||
|
{syncResult && (
|
||||||
|
<div className={`alert ${syncResult.ok ? "alert-success" : "alert-danger"} py-2`} role="alert">
|
||||||
|
{syncResult.text}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="d-flex gap-2">
|
||||||
|
<button className="btn btn-outline-primary" onClick={handleSync} disabled={syncing}>
|
||||||
|
{syncing ? (
|
||||||
|
<>
|
||||||
|
<span className="spinner-border spinner-border-sm me-2" role="status" />
|
||||||
|
Sincronizando...
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
"Sincronizar ahora"
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<small className="text-muted d-block mt-2">
|
||||||
|
Lee la casilla Gmail y agrega como comentarios las respuestas con
|
||||||
|
etiqueta [HelpDesk HD-000123]. El worker lo hace solo cada 5 minutos.
|
||||||
|
Requiere scope gmail.readonly autorizado en admin.google.com.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h6 className="fw-semibold mb-2">
|
<h6 className="fw-semibold mb-2">
|
||||||
<i className="bi bi-clock-history me-2"></i>
|
<i className="bi bi-clock-history me-2"></i>
|
||||||
Últimos envíos
|
Últimos envíos
|
||||||
|
|||||||
@@ -383,3 +383,13 @@ export async function sendTestEmail(to: string) {
|
|||||||
body: JSON.stringify({ to }),
|
body: JSON.stringify({ to }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function syncInboundEmail() {
|
||||||
|
return fetchApi<{
|
||||||
|
success: boolean;
|
||||||
|
checkedCount: number;
|
||||||
|
inserted: number;
|
||||||
|
skipped: number;
|
||||||
|
error?: string;
|
||||||
|
}>("/api/helpdesk/email/inbound/sync", { method: "POST" });
|
||||||
|
}
|
||||||
Reference in new issue
Block a user