Aggiunge fascia oraria, prova manuale obbligatoria e cruscotto invii email.
CI / lint (push) Failing after 16m2s
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled

Le campagne rispettano orario e giorni lavorativi, richiedono una mail di test con dati inseriti a mano prima dell'invio massivo e offrono una dashboard per monitorare l'avanzamento.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-18 00:04:33 +02:00
co-authored by Cursor
parent 4ddf534a0c
commit 98dcdbbf82
33 changed files with 882 additions and 56 deletions
@@ -0,0 +1,20 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = { interval: { type: Number, default: 10000 } }
connect() {
this.timer = setInterval(() => {
if (document.hidden) return
if (window.Turbo?.visit) {
window.Turbo.visit(window.location.href, { action: "replace" })
} else {
window.location.reload()
}
}, this.intervalValue)
}
disconnect() {
clearInterval(this.timer)
}
}
@@ -0,0 +1,20 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["checkbox", "panel"]
connect() {
this.sync()
}
toggle() {
this.sync()
}
sync() {
if (!this.hasCheckboxTarget) return
const on = this.checkboxTarget.checked
this.panelTargets.forEach((el) => el.classList.toggle("hidden", !on))
}
}
@@ -0,0 +1,28 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["frame"]
static values = { previewUrl: String }
connect() {
this.loadPreview()
}
preview() {
clearTimeout(this.timer)
this.timer = setTimeout(() => this.loadPreview(), 350)
}
loadPreview() {
if (!this.hasFrameTarget) return
const params = new URLSearchParams(new FormData(this.element))
params.delete("authenticity_token")
params.delete("commit")
this.frameTarget.src = `${this.previewUrlValue}?${params.toString()}`
}
disconnect() {
clearTimeout(this.timer)
}
}