diff --git a/MEMORY.md b/MEMORY.md
index 48dedc63..b833e27c 100644
--- a/MEMORY.md
+++ b/MEMORY.md
@@ -705,3 +705,18 @@ php artisan route:list --name=email
- `resources/views/eventi/show.blade.php`
- `resources/views/eventi/index.blade.php`
- `resources/views/eventi/calendar.blade.php`
+
+### 27 Maggio 2026 - Mittenti Aggiuntivi in Sezione Email di /impostazioni
+
+- **Modifica**: Spostata gestione sender accounts (Mittenti Aggiuntivi) da pagina dedicata `/impostazioni/email` a **sottosezione della sezione Email** nella pagina principale `/impostazioni`
+- **Sub-tab aggiunto**: pill "Mittenti Aggiuntivi" dopo Firma nei sottotab della sezione Email
+- **Tab-pane `email-mittenti`**: tabella sender con colonne Email, Nome, SMTP, Reply-To, Verify, Stato, Azioni; stessi campi CRUD della vista dedicata
+- **Form puliti**: pulsanti Elimina usano fetch AJAX (`deleteSender()`) invece di form annidati per evitare HTML invalido (nested forms dentro il form principale Email)
+- **Controller**: `ImpostazioniController@index` ora passa `$senderAccounts` alla view
+- **`senderDestroy()`** in `EmailSettingsController`: ora ritorna JSON per richieste AJAX (`expectsJson()`)
+- **Sidebar**: rimossa voce "Impostazioni Email" aggiunta in precedenza sotto Email (non serve — le impostazioni email sono accessibili dalla sezione Email in `/impostazioni`)
+- **Files modificati**:
+ - `app/Http/Controllers/ImpostazioniController.php`: import + compact SenderAccount
+ - `resources/views/impostazioni/index.blade.php`: pill Mittenti Aggiuntivi, tab-pane email-mittenti, modale sender modifica/crea, funzioni JS (resetSenderForm, editSender, deleteSender, testSenderSmtp)
+ - `app/Http/Controllers/Admin/EmailSettingsController.php`: senderDestroy() con expectsJson()
+ - `resources/views/layouts/adminlte.blade.php`: rimossa voce Impostazioni Email dal sidebar
diff --git a/app/Http/Controllers/Admin/EmailSettingsController.php b/app/Http/Controllers/Admin/EmailSettingsController.php
index d23aa526..3b16967b 100644
--- a/app/Http/Controllers/Admin/EmailSettingsController.php
+++ b/app/Http/Controllers/Admin/EmailSettingsController.php
@@ -250,6 +250,10 @@ class EmailSettingsController extends Controller
$sender = SenderAccount::findOrFail($id);
$sender->delete();
+ if (request()->expectsJson()) {
+ return response()->json(['success' => true, 'message' => 'Mittente eliminato.']);
+ }
+
return back()->with('success', 'Mittente eliminato.');
}
diff --git a/app/Http/Controllers/ImpostazioniController.php b/app/Http/Controllers/ImpostazioniController.php
index 7afaa2b0..791a426b 100644
--- a/app/Http/Controllers/ImpostazioniController.php
+++ b/app/Http/Controllers/ImpostazioniController.php
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Models\AppSetting;
use App\Models\EmailSetting;
use App\Models\Ruolo;
+use App\Models\SenderAccount;
use App\Models\TipologiaDocumento;
use App\Models\TipologiaEvento;
use Illuminate\Http\Request;
@@ -21,8 +22,9 @@ class ImpostazioniController extends Controller
$ruoli = Ruolo::orderBy('ordine')->get();
$appSettings = AppSetting::first();
$emailSettings = EmailSetting::first() ?? new EmailSetting();
+ $senderAccounts = SenderAccount::orderBy('email_address')->get();
- return view('impostazioni.index', compact('tipologie', 'tipologieEventi', 'ruoli', 'appSettings', 'emailSettings'));
+ return view('impostazioni.index', compact('tipologie', 'tipologieEventi', 'ruoli', 'appSettings', 'emailSettings', 'senderAccounts'));
}
public function saveAppSettings(Request $request)
diff --git a/resources/views/impostazioni/index.blade.php b/resources/views/impostazioni/index.blade.php
index 49806638..eec5fce4 100644
--- a/resources/views/impostazioni/index.blade.php
+++ b/resources/views/impostazioni/index.blade.php
@@ -190,6 +190,7 @@
Account
Sincronizzazione
Firma
+ Mittenti Aggiuntivi
@@ -427,6 +428,97 @@
+
+
+
+
+
+ @if(session('success'))
+
{{ session('success') }}
+ @endif
+ @if(session('error'))
+
{{ session('error') }}
+ @endif
+
+ @if($senderAccounts->count() > 0)
+
+
+
+
+ | Email |
+ Nome |
+ SMTP |
+ Reply-To |
+ Verify |
+ Stato |
+ Azioni |
+
+
+
+ @foreach($senderAccounts as $sender)
+
+ | {{ $sender->email_address }} |
+ {{ $sender->email_name ?: '-' }} |
+ {{ $sender->smtp_host ?: '-' }}:{{ $sender->smtp_port ?: '-' }} |
+ {{ $sender->reply_to ?: '-' }} |
+ {{ $sender->verify_email ?: '-' }} |
+
+ @if($sender->is_active)
+ Attivo
+ @else
+ Disattivo
+ @endif
+ |
+
+
+
+
+ |
+
+ @endforeach
+
+
+
+ @else
+
+
+
Nessun mittente aggiuntivo configurato.
+
Usa il pulsante "Nuovo Mittente" per aggiungere un account di invio dedicato (es. Newsletter).
+
+ @endif
+
+
+
+ @if($senderAccounts->count() > 0)
+
+
+
+
+ - I mittenti aggiuntivi sono account solo invio (SMTP) senza IMAP.
+ - Puoi selezionarli nel compose email o negli invii mailing.
+ - Il campo Reply-To imposta l'indirizzo di risposta (es.
no-reply@parrocchia.it).
+ - Il campo Verify Email riceve un report di riepilogo dopo ogni invio massivo con l'esito (ok/falliti).
+ - Se Reply-To non è impostato, viene usato Verify Email come fallback.
+
+
+
+ @endif
+
+
+{{-- ===== MODALE MITTENTI AGGIUNTIVI ===== --}}
+
@endsection
@section('scripts')
@@ -1007,6 +1206,92 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
}
});
+// ===== MITTENTI AGGIUNTIVI =====
+let senderAccounts = @json($senderAccounts);
+
+function resetSenderForm() {
+ document.getElementById('senderForm').action = '{{ route('impostazioni.sender.store') }}';
+ document.getElementById('senderMethod').value = 'POST';
+ document.getElementById('senderModalTitle').textContent = 'Nuovo Mittente';
+ document.getElementById('senderForm').reset();
+ document.getElementById('senderId').value = '';
+ document.getElementById('sender_is_active').checked = true;
+ document.getElementById('sender_smtp_password').placeholder = '';
+ document.getElementById('sender_smtp_password').required = false;
+}
+
+function editSender(id) {
+ const sender = senderAccounts.find(s => s.id === id);
+ if (!sender) return;
+
+ document.getElementById('senderForm').action = '{{ route('impostazioni.sender.update', '__ID__') }}'.replace('__ID__', id);
+ document.getElementById('senderMethod').value = 'PUT';
+ document.getElementById('senderModalTitle').textContent = 'Modifica Mittente - ' + sender.email_address;
+ document.getElementById('senderId').value = sender.id;
+ document.getElementById('sender_email').value = sender.email_address;
+ document.getElementById('sender_name').value = sender.email_name || '';
+ document.getElementById('sender_smtp_host').value = sender.smtp_host || '';
+ document.getElementById('sender_smtp_port').value = sender.smtp_port || 587;
+ document.getElementById('sender_smtp_encryption').value = sender.smtp_encryption || 'tls';
+ document.getElementById('sender_smtp_username').value = sender.smtp_username || '';
+ document.getElementById('sender_smtp_password').value = '';
+ document.getElementById('sender_smtp_password').placeholder = '......';
+ document.getElementById('sender_smtp_password').required = false;
+ document.getElementById('sender_reply_to').value = sender.reply_to || '';
+ document.getElementById('sender_verify_email').value = sender.verify_email || '';
+ document.getElementById('sender_note').value = sender.note || '';
+ document.getElementById('sender_is_active').checked = sender.is_active;
+
+ $('#senderModal').modal('show');
+}
+
+function deleteSender(id, email) {
+ if (!confirm('Eliminare il mittente ' + email + '?')) return;
+ var url = '{{ route('impostazioni.sender.destroy', '__ID__') }}'.replace('__ID__', id);
+ fetch(url, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': '{{ csrf_token() }}',
+ 'X-HTTP-Method-Override': 'DELETE'
+ }
+ }).then(function(r) { return r.json(); }).then(function(data) {
+ if (data.success) {
+ location.reload();
+ } else {
+ alert('❌ ' + (data.message || 'Errore'));
+ }
+ }).catch(function() {
+ alert('❌ Errore di rete');
+ });
+}
+
+function testSenderSmtp(id) {
+ const email = prompt('Inserisci l\'indirizzo email a cui inviare il test:');
+ if (!email || !email.includes('@')) return;
+
+ const btn = event.target;
+ btn.disabled = true;
+ btn.innerHTML = '';
+
+ $.ajax({
+ url: '{{ route('impostazioni.sender.test', '__ID__') }}'.replace('__ID__', id),
+ method: 'POST',
+ headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
+ data: { email: email },
+ timeout: 30000,
+ success: function(response) {
+ btn.disabled = false;
+ btn.innerHTML = '';
+ alert(response.success ? '✅ ' + response.message : '❌ ' + response.message);
+ },
+ error: function(xhr) {
+ btn.disabled = false;
+ btn.innerHTML = '';
+ const msg = xhr.responseJSON?.message || 'Errore di connessione';
+ alert('❌ ' + msg);
+ }
+ });
+}
// ===== EMAIL FUNCTIONS =====
function testConnection() {
$.ajax({
diff --git a/storage/framework/views/b8b9b66a1d90ca24f6e19777b0838604.php b/storage/framework/views/b8b9b66a1d90ca24f6e19777b0838604.php
index 3bdcf4f7..9a939330 100755
--- a/storage/framework/views/b8b9b66a1d90ca24f6e19777b0838604.php
+++ b/storage/framework/views/b8b9b66a1d90ca24f6e19777b0838604.php
@@ -188,6 +188,7 @@
Account
Sincronizzazione
Firma
+ Mittenti Aggiuntivi
@@ -426,6 +427,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ count() > 0): ?>
+
+
+
+
+ | Email |
+ Nome |
+ SMTP |
+ Reply-To |
+ Verify |
+ Stato |
+ Azioni |
+
+
+
+ addLoop($__currentLoopData); foreach($__currentLoopData as $sender): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
+
+ | email_address); ?> |
+ email_name ?: '-'); ?> |
+ smtp_host ?: '-'); ?>:smtp_port ?: '-'); ?> |
+ reply_to ?: '-'); ?> |
+ verify_email ?: '-'); ?> |
+
+ is_active): ?>
+ Attivo
+
+ Disattivo
+
+ |
+
+
+
+
+ |
+
+ popLoop(); $loop = $__env->getLastLoop(); ?>
+
+
+
+
+
+
+
Nessun mittente aggiuntivo configurato.
+
Usa il pulsante "Nuovo Mittente" per aggiungere un account di invio dedicato (es. Newsletter).
+
+
+
+
+
+ count() > 0): ?>
+
+
+
+
+ - I mittenti aggiuntivi sono account solo invio (SMTP) senza IMAP.
+ - Puoi selezionarli nel compose email o negli invii mailing.
+ - Il campo Reply-To imposta l'indirizzo di risposta (es.
no-reply@parrocchia.it).
+ - Il campo Verify Email riceve un report di riepilogo dopo ogni invio massivo con l'esito (ok/falliti).
+ - Se Reply-To non è impostato, viene usato Verify Email come fallback.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
stopSection(); ?>
startSection('scripts'); ?>
@@ -1006,6 +1205,92 @@ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
}
});
+// ===== MITTENTI AGGIUNTIVI =====
+let senderAccounts = ;
+
+function resetSenderForm() {
+ document.getElementById('senderForm').action = '';
+ document.getElementById('senderMethod').value = 'POST';
+ document.getElementById('senderModalTitle').textContent = 'Nuovo Mittente';
+ document.getElementById('senderForm').reset();
+ document.getElementById('senderId').value = '';
+ document.getElementById('sender_is_active').checked = true;
+ document.getElementById('sender_smtp_password').placeholder = '';
+ document.getElementById('sender_smtp_password').required = false;
+}
+
+function editSender(id) {
+ const sender = senderAccounts.find(s => s.id === id);
+ if (!sender) return;
+
+ document.getElementById('senderForm').action = ''.replace('__ID__', id);
+ document.getElementById('senderMethod').value = 'PUT';
+ document.getElementById('senderModalTitle').textContent = 'Modifica Mittente - ' + sender.email_address;
+ document.getElementById('senderId').value = sender.id;
+ document.getElementById('sender_email').value = sender.email_address;
+ document.getElementById('sender_name').value = sender.email_name || '';
+ document.getElementById('sender_smtp_host').value = sender.smtp_host || '';
+ document.getElementById('sender_smtp_port').value = sender.smtp_port || 587;
+ document.getElementById('sender_smtp_encryption').value = sender.smtp_encryption || 'tls';
+ document.getElementById('sender_smtp_username').value = sender.smtp_username || '';
+ document.getElementById('sender_smtp_password').value = '';
+ document.getElementById('sender_smtp_password').placeholder = '......';
+ document.getElementById('sender_smtp_password').required = false;
+ document.getElementById('sender_reply_to').value = sender.reply_to || '';
+ document.getElementById('sender_verify_email').value = sender.verify_email || '';
+ document.getElementById('sender_note').value = sender.note || '';
+ document.getElementById('sender_is_active').checked = sender.is_active;
+
+ $('#senderModal').modal('show');
+}
+
+function deleteSender(id, email) {
+ if (!confirm('Eliminare il mittente ' + email + '?')) return;
+ var url = ''.replace('__ID__', id);
+ fetch(url, {
+ method: 'POST',
+ headers: {
+ 'X-CSRF-TOKEN': '',
+ 'X-HTTP-Method-Override': 'DELETE'
+ }
+ }).then(function(r) { return r.json(); }).then(function(data) {
+ if (data.success) {
+ location.reload();
+ } else {
+ alert('❌ ' + (data.message || 'Errore'));
+ }
+ }).catch(function() {
+ alert('❌ Errore di rete');
+ });
+}
+
+function testSenderSmtp(id) {
+ const email = prompt('Inserisci l\'indirizzo email a cui inviare il test:');
+ if (!email || !email.includes('@')) return;
+
+ const btn = event.target;
+ btn.disabled = true;
+ btn.innerHTML = '';
+
+ $.ajax({
+ url: ''.replace('__ID__', id),
+ method: 'POST',
+ headers: { 'X-CSRF-TOKEN': '' },
+ data: { email: email },
+ timeout: 30000,
+ success: function(response) {
+ btn.disabled = false;
+ btn.innerHTML = '';
+ alert(response.success ? '✅ ' + response.message : '❌ ' + response.message);
+ },
+ error: function(xhr) {
+ btn.disabled = false;
+ btn.innerHTML = '';
+ const msg = xhr.responseJSON?.message || 'Errore di connessione';
+ alert('❌ ' + msg);
+ }
+ });
+}
// ===== EMAIL FUNCTIONS =====
function testConnection() {
$.ajax({