| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- <div class="col card--ui" id="card--dashboard">
- <header id="title--section" style="display:none !important" class="d-flex align-items-center justify-content-between">
- <div class="title--section_name d-flex align-items-center justify-content-between">
- <i class="ico--ui title_section utenti me-2"></i>
- <h2 class="primary">Emails</h2>
- </div>
- @if(!$showForm)
- <div class="title--section_addButton" wire:click="add()" style="cursor: pointer;" wire:ignore>
- <div class="btn--ui entrata d-flex justify-items-between">
- <a href="#" style="color:white;">Aggiungi</a>
- </div>
- </div>
- @endif
- </header>
- <a class="btn--ui lightGrey" @if(!$showForm) href="/settings?type=comunicazioni" @else href="/mail_comunications" @endif><i class="fa-solid fa-arrow-left"></i></a><br/><br/>
- {{-- LISTA MESSAGGI --}}
- <section id="resume-table" @if($showForm) style="display:none" @endif>
- <div wire:ignore>
- <table class="table tablesaw tableHead tablesaw-stack" id="tablesaw-350" width="100%">
- <thead>
- <tr>
- <th>ID</th>
- <th>Oggetto</th>
- <th># Attachments</th>
- <th># Destinatari</th>
- <th>Stato</th>
- <th>Programmata per</th>
- <th>Data invio</th>
- <th>Data creazione</th>
- <th>...</th>
- </tr>
- </thead>
- <tbody id="checkall-target">
- @foreach($records as $record)
- @php
- $state = $record->status;
- if (!$state) {
- if (($record->recipients_sent_count ?? 0) > 0 && ($record->recipients_failed_count ?? 0) > 0) {
- $state = 'partial';
- } elseif (($record->recipients_sent_count ?? 0) > 0) {
- $state = 'sent';
- } elseif (!empty($record->schedule_at)) {
- $state = 'scheduled';
- } else {
- $state = 'draft';
- }
- }
- $badgeMap = [
- 'draft' => 'secondary',
- 'processing' => 'info',
- 'scheduled' => 'primary',
- 'partial' => 'warning',
- 'sent' => 'success',
- 'failed' => 'danger',
- ];
- @endphp
- <tr id="row_email_{{ $record->id }}">
- <td>{{ $record->id }}</td>
- <td><strong>{{ $record->subject }}</strong></td>
- <td style="padding-right: 20px">{{ $record->attachments_count ?? $record->attachments()->count() }}</td>
- <td style="padding-right: 20px">{{ $record->recipients_count ?? $record->recipients()->count() }}</td>
- <td><span class="badge bg-{{$badgeMap[$state]}}">{{ $record->status }}</span></td>
- <td>
- @if(!empty($record->schedule_at))
- {{ optional($record->schedule_at)->setTimezone('Europe/Rome')->format('d M Y - H:i') }}
- @endif
- </td>
- <td>
- @if(!empty($record->sent_at))
- {{ optional($record->sent_at)->setTimezone('Europe/Rome')->format('d M Y - H:i') }}
- @endif
- </td>
- <td>{{ optional($record->created_at)->setTimezone('Europe/Rome')->format('d M Y - H:i') }}</td>
- <td class="d-flex gap-2">
- <button type="button" class="btn" wire:click="edit({{ $record->id }})" data-bs-toggle="tooltip" data-bs-trigger="hover focus" data-bs-placement="bottom" title="Modifica">
- <i class="fa-regular fa-pen-to-square"></i>
- </button>
- <button type="button" class="btn" wire:click="duplicate({{ $record->id }})" data-bs-toggle="tooltip" data-bs-trigger="hover focus" data-bs-placement="bottom" title="Duplica">
- <i class="fa-solid fa-copy"></i>
- </button>
-
- @if(in_array($record->status, ['draft','failed']))
- <button type="button" class="btn text-danger"
- onclick="if (confirm('Eliminare definitivamente questa email?')) { Livewire.find('{{ $this->id }}').call('deleteMessage', {{ $record->id }}); }"
- data-bs-toggle="tooltip" title="Elimina">
- <i class="fa-solid fa-trash"></i>
- </button>
- @endif
- </td>
- </tr>
- @endforeach
- </tbody>
- </table>
- </div>
- </section>
- {{-- FORM MESSAGGIO --}}
- <section wire:key="email-form" @if(!$showForm) style="display:none" @endif>
- <div class="container">
- @if ($error)
- <div class="alert alert-danger" role="alert">{{ $error }}</div>
- @endif
- @if ($success)
- <div class="alert alert-success" role="alert">{{ $success }}</div>
- @endif
- <div class="row">
- <div class="col">
- <form>
- {{-- Oggetto --}}
- <div class="row mb-5">
- <div class="col">
- <div class="form--item">
- <h4>Oggetto</h4>
- <input type="text" class="form-control @error('subject') is-invalid @enderror" id="subject" wire:model.defer="subject" placeholder="Oggetto email" @if($locked) disabled @endif>
- @error('subject')
- <div class="invalid-feedback">{{ $message }}</div>
- @enderror
- </div>
- </div>
- </div>
- {{-- Messaggio (CKEditor → content_html) --}}
- <div class="row mb-5">
- <div class="col">
- <div wire:ignore class="form--item">
- <h4>Messaggio</h4>
- <textarea class="form-control" id="message"></textarea>
- @error('content_html')
- <div class="invalid-feedback d-block">{{ $message }}</div>
- @enderror
- </div>
- </div>
- </div>
- {{-- Destinatari (selezionati) --}}
- <div class="row mb-5">
- <div class="col-12 mb-2">
- <h4>Destinatari</h4>
- <div class="recipients">
- @if (empty($recipients))
- <span>Nessun destinatario selezionato</span>
- @else
- @foreach ($recipients as $r)
- @php
- $fullName = trim(($r['last_name'] ?? '').' '.($r['first_name'] ?? ''));
- @endphp
- <div class="recipient">
- <span class="recipient-name">{{ $fullName !== '' ? $fullName : '—' }}</span>
- <span class="recipient-email">({{ $r['email_address'] }})</span>
- </div>
- @endforeach
- @endif
- </div>
- @error('recipients') <div class="invalid-feedback d-block">{{ $message }}</div> @enderror
- </div>
- @if(!$locked)
- <div class="col"></div>
- <div class="col-auto">
- <a style="cursor:pointer" class="addRecipients btn--ui"><i class="fa-solid fa-plus"></i></a>
- </div>
- @endif
- </div>
- {{-- FILTRI + TABELLA DESTINATARI --}}
- <div class="row mb-5" wire:ignore id="addRecipientsRow" style="display: none">
- <div class="col-xs-12">
- <div class="showFilter" style="display: none">
- <hr size="1">
- <div class="row g-3">
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Età</b></div>
- <div class="col-12">
- <div class="row mb-2">
- <div class="col-3"><label class="form-check-label ms-2">Da</label></div>
- <div class="col-9"><input class="form-control" type="number" name="txtFromYear"></div>
- </div>
- </div>
- <div class="col-12">
- <div class="row">
- <div class="col-3"><label class="form-check-label ms-2">A</label></div>
- <div class="col-9"><input class="form-control" type="number" name="txtToYear"></div>
- </div>
- </div>
- </div>
- </div>
- {{-- Altri filtri come da tua UI esistente --}}
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Tipologia di tesseramento</b></div>
- <div class="col-12">
- <select name="filterCards" class="form-select filterCards">
- <option value="">Tutte
- @foreach(getCards() as $card)
- <option value="{{$card->id}}">{{$card->name}}
- @endforeach
- </select>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Stato tesseramento</b></div>
- <div class="col-12">
- <select name="filterStatus" class="form-select filterStatus" multiple="multiple">
- <option value="2">Attivo
- <option value="1">Sospeso
- <option value="0">Non tesserato
- </select>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Gruppo di interesse</b></div>
- <div class="col-12">
- <select name="filterCategories" class="form-select filterCategories" multiple="multiple">
- <option value="">Tutte</option>
- @foreach($categories as $category)
- <option value="{{$category["id"]}}">
- {!! str_repeat('• ', $category["indentation"] ?? 0) !!}{{$category["name"]}}
- </option>
- @endforeach
- </select>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Anno di nascita</b></div>
- <div class="col-12">
- <div class="row mb-2">
- <div class="col-3"><label class="form-check-label ms-2" >Da</label></div>
- <div class="col-9"><input class="form-control " type="number" name="txtFromYearYear"></div>
- </div>
- </div>
- <div class="col-12">
- <div class="row">
- <div class="col-3"><label class="form-check-label ms-2" >A</label></div>
- <div class="col-9"><input class="form-control " type="number" name="txtToYearYear"></div>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Corso</b></div>
- <div class="col-12">
- <select name="filterCourses" class="form-select filterCourses" multiple="multiple">
- <option value="">Tutti</option>
- @foreach($courses as $course)
- <option value="{{ $course['id'] }}">
- {!! str_repeat('• ', $course['indentation'] ?? 0) !!}{{ $course['name'] }}
- </option>
- @endforeach
- </select>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Scadenza certificato medico</b></div>
- <div class="col-12">
- <select name="filterScadenza" class="form-select filterScadenza" multiple="multiple">
- <option value="1">Scaduti
- <option value="2">In scadenza
- <option value="3">Non consegnato
- <option value="4">Validi
- </select>
- </div>
- </div>
- </div>
- <div class="col-md-3">
- <div class="row">
- <div class="col-md-12 mb-2"><b>Tipologia certificato medico</b></div>
- <div class="col-12">
- <select name="filterCertificateType" class="form-select filterCertificateType" multiple="multiple">
- <option value="">Tutti
- <option value="N">Non agonistico
- <option value="A">Agonistico
- </select>
- </div>
- </div>
- </div>
- </div>
- <div class="row g-3">
- <div class="col-md-12" style="text-align:right">
- <button class="btn--ui lightGrey" onclick="resetFilters(event)">Reset</button>
- <button class="btn--ui" onclick="event.preventDefault();loadDataTable()">FILTRA</button>
- </div>
- </div>
- <hr size="1">
- </div>
- </div>
- <div class="col-xs-12">
- <table id="recipients-table" class="table tablesaw tableHead tablesaw-stack w-100">
- <thead>
- <tr>
- <th></th>
- <th>Cognome</th>
- <th>Nome</th>
- <th>Email</th>
- <th>Telefono</th>
- <th>Età</th>
- <th>Anno</th>
- <th>Stato</th>
- <th>Certificato</th>
- <th>Gruppi</th>
- {{-- <th>Corsi</th> --}}
- </tr>
- </thead>
- <tbody></tbody>
- </table>
- </div>
- </div>
- {{-- Allegati --}}
- <div class="row mb-5">
- <div class="col">
- <div class="form--item">
- <h4>Allegati</h4>
- <input type="file" class="form-control @error('newAttachments.*') is-invalid @enderror" wire:model="newAttachments" multiple @if($locked) disabled @endif>
- <small class="text-muted d-block mt-1">Formati: pdf, docx, jpg, png</small>
- @error('newAttachments.*')
- <div class="invalid-feedback d-block">{{ $message }}</div>
- @enderror
- @if(!empty($existingAttachments))
- <ul class="list-group mt-2">
- @foreach($existingAttachments as $att)
- <li class="list-group-item d-flex justify-content-between align-items-center gap-3">
- <div class="d-flex align-items-center gap-3 text-truncate" style="min-width:0">
- @if(!empty($att['img']) && !empty($att['url']))
- <img src="{{ $att['url'] }}" alt="" style="width:40px;height:40px;object-fit:cover;border-radius:6px;border:1px solid #eee">
- @else
- <i class="fa-regular fa-file" style="font-size:20px;width:40px;text-align:center"></i>
- @endif
- <div class="text-truncate d-flex ">
- @if(!empty($att['url']))
- <a href="{{ $att['url'] }}" target="_blank" class="text-decoration-none text-truncate d-inline-block" style="max-width:420px">
- {{ $att['name'] }}
- </a>
- @else
- <span class="text-truncate d-inline-block" style="max-width:420px">{{ $att['name'] }}</span>
- @endif
- @if(!empty($att['size']))
- <small class="text-muted ms-2">({{ $att['size'] }})</small>
- @endif
- </div>
- </div>
- @unless($locked)
- <button type="button"
- class="btn btn-sm btn-outline-danger"
- wire:click="removeExistingAttachment({{ (int)$att['id'] }})"
- title="Rimuovi">
- <i class="fa-solid fa-trash"></i>
- </button>
- @endunless
- </li>
- @endforeach
- </ul>
- @endif
- {{-- File appena selezionati (non salvati) --}}
- @if(is_array($newAttachments) && count($newAttachments))
- <ul class="list-group mt-2">
- @foreach($newAttachments as $idx => $tmp)
- <li class="list-group-item d-flex justify-content-between align-items-center">
- <div class="text-truncate d-flex ">
- <i class="fa-regular fa-file me-2"></i>
- {{ $tmp->getClientOriginalName() }}
- <small class="text-muted ms-2">({{ number_format($tmp->getSize()/1024,1) }} KB) — non ancora salvato</small>
- </div>
- <button type="button" class="btn btn-sm btn-outline-danger" wire:click="removeNewAttachment({{ $idx }})">
- <i class="fa-solid fa-xmark"></i>
- </button>
- </li>
- @endforeach
- </ul>
- @endif
- </div>
- </div>
- </div>
- {{-- Opzioni invio --}}
- <div class="row mb-5">
- <div class="col">
- <h4>Opzioni di Invio</h4>
- <div class="d-flex gap-3 comunication-send-options">
- <label class="form-check">
- <input class="form-check-input" type="radio" wire:model="mode" value="now">
- <i class="fas fa-envelope me-2"></i> <span>Invia subito</span>
- </label>
- <label class="form-check">
- <input class="form-check-input" type="radio" wire:model="mode" value="schedule">
- <i class="fas fa-clock me-2"></i> <span>Programma</span>
- </label>
- </div>
- </div>
- </div>
- @if(!$locked && $mode === 'schedule')
- <div class="row mb-5">
- <div class="col-md-6">
- <label for="scheduledDateTime" class="form-label">Data e Ora di Invio</label>
- <input type="datetime-local" class="form-control @error('schedule_at') is-invalid @enderror" id="scheduledDateTime" wire:model="schedule_at">
- @error('schedule_at') <div class="invalid-feedback">{{ $message }}</div> @enderror
- </div>
- </div>
- @endif
- <div class="form--item mt-5 mb-5 d-flex gap-2">
- @if(!$locked)
- <a class="btn--ui lightGrey" href="/mail_comunications">Annulla</a>
- <button type="button" class="btn--ui" onclick="submitEmail('draft')" style="margin-right: auto">Salva bozza</button>
- @if($mode==='now')
- <button type="button" class="btn--ui" onclick="submitEmail('send')">Invia ora</button>
- @else
- <button type="button" class="btn--ui" onclick="submitEmail('schedule')">Salva & Programma</button>
- @endif
- @else
- <a class="btn--ui lightGrey" href="/mail_comunications">Torna indietro</a>
- @endif
- </div>
- </form>
- </div>
- </div>
- </div>
- </section>
- <input type="hidden" name="timezone" id="timezone" wire:model="timezone">
- </div>
- @if (session()->has('success'))
- <div class="alert alert-success alert-dismissible fade show mt-3" role="alert">
- {{ session('success') }}
- <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
- </div>
- @endif
- @if (session()->has('error'))
- <div class="alert alert-danger alert-dismissible fade show mt-3" role="alert">
- {{ session('error') }}
- <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
- </div>
- @endif
- @push('scripts')
- <link href="/css/datatables.css" rel="stylesheet" />
- <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
- <script src="/assets/js/datatables.js"></script>
- <script src="https://cdn.datatables.net/buttons/3.0.2/js/buttons.dataTables.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
- <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
- <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
- @endpush
- @push('scripts')
- <script type="text/javascript">
- document.addEventListener('livewire:load', () => {
- if (!$.fn.DataTable.isDataTable('#tablesaw-350')) {
- loadArchiveDataTable();
- }
- window.addEventListener('email-deleted', (e) => {
- const id = e.detail?.id;
- const table = $('#tablesaw-350');
- if (!id || !$.fn.DataTable.isDataTable(table)) return;
- const dt = table.DataTable();
- const rowEl = document.getElementById('row_email_' + id);
- if (rowEl) {
- dt.row(rowEl).remove().draw(false);
- }
- });
- const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
- @this.set('timezone', tz);
- });
- window.addEventListener('init-recipients-table', (e) => {
- const selected = e.detail?.selected || [];
- loadDataTable(selected);
-
- const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
- @this.set('timezone', tz);
- });
- function loadArchiveDataTable(){
- let date = new Date();
- let date_export = `${date.getFullYear()}${date.getMonth()}${date.getDate()}_`;
- let table = $('#tablesaw-350').DataTable();
- if ( $.fn.DataTable.isDataTable('#tablesaw-350') ) {
- table.destroy();
- }
- $('#tablesaw-350').DataTable({
- processing: true,
- thead: {
- 'th': {'background-color': 'blue'}
- },
- order: [[7, 'desc']],
- layout: {
- topStart : null,
- topEnd : null,
- top1A: {
- // buttons: [
- // {
- // extend: 'collection',
- // text: 'ESPORTA',
- buttons: [
- {
- extend: 'excelHtml5',
- text: '<i class="fa-solid fa-file-excel"></i>',
- action: newexportaction,
- title: date_export + 'Email',
- exportOptions: {
- columns: ":not(':last')"
- }
- },
- {
- extend: 'pdfHtml5',
- text: '<i class="fa-solid fa-file-pdf"></i>',
- action: newexportaction,
- title: date_export + 'Email',
- exportOptions: {
- columns: ":not(':last')"
- }
- },
- {
- extend: 'print',
- action: newexportaction,
- text: '<i class="fa-solid fa-print"></i>',
- title: date_export + 'Email',
- exportOptions: {
- columns: ":not(':last')"
- }
- }
- ],
- // dropup: true
- // }
- // ]
- },
- top1B : {
- pageLength: {
- menu: [[10, 25, 50, 100, 100000], [10, 25, 50, 100, "Tutti"]]
- }
- },
- top1C :'search',
- },
- pagingType: 'first_last_numbers',
- language: {
- "url": "/assets/js/Italian.json",
- paginate: {
- first: '<i class="fa-solid fa-angles-left"></i>',
- last: '<i class="fa-solid fa-angles-right"></i>',
- }
- },
- fnInitComplete: function (oSettings, json) {
- var html = ' <a href="#" class="addData btn--ui"><i class="fa-solid fa-plus"></i></a>';
- $(".dt-search").append(html);
- }
- });
- $('#tablesaw-350 thead tr th').addClass('col').css("background-color", "#f6f8fa");
- $(document).on("click",".addData",function() {
- @this.add();
- });
- }
- $(document).on("click",".showHideFilter",function() {
- $(".showFilter").toggle();
- $('.filterCards,.filterStatus,.filterScadenza,.filterCertificateType,.filterCategories,.filterCourses').each(function(){
- $(this).select2({
- language: { noResults: ()=>"Nessun risultato" }
- });
- });
- });
- $(document).on("click", ".addRecipients", function() {
- $("#addRecipientsRow").toggle();
- });
- window.resetFilters = function(event){
- if (event) event.preventDefault();
- $('.filterCards').val('').trigger('change');
- $('.filterStatus').val('').trigger('change');
- $('.filterScadenza').val('-1').trigger('change');
- $('.filterCertificateType').val('-1').trigger('change');
- $('.filterCategories').val('-1').trigger('change');
- $('.filterCourses').val('-1').trigger('change');
- $('input[name="txtFromYear"]').val('');
- $('input[name="txtToYear"]').val('');
- $('input[name="txtFromYearYear"]').val('');
- $('input[name="txtToYearYear"]').val('');
- loadDataTable();
- }
- function loadDataTable(preselected = []) {
- const selectedIds = new Set((preselected || []).map(x => parseInt(x, 10)).filter(Boolean));
- if ($.fn.DataTable.isDataTable('#recipients-table')) {
- $('#recipients-table').DataTable().destroy();
- }
- var fromYear = $('input[name="txtFromYear"]').val();
- var toYear = $('input[name="txtToYear"]').val();
- var fromYearYear = $('input[name="txtFromYearYear"]').val();
- var toYearYear = $('input[name="txtToYearYear"]').val();
- var filterCards = $('.filterCards').val();
- var filterStatus = $('.filterStatus').val();
- var filterScadenza = $('.filterScadenza').val();
- var filterCertificateType = $('.filterCertificateType').val();
- var filterCategories = $('.filterCategories').val();
- var filterCourses = $('.filterCourses').val();
- const dataTable = $('#recipients-table').DataTable({
- serverSide: true,
- ajax: '/get_recipients?cards=' + filterCards + "&filterCategories=" + filterCategories + "&filterCertificateType=" + filterCertificateType + "&filterScadenza=" + filterScadenza + "&filterStatus=" + filterStatus + "&fromYear=" + fromYear + "&toYear=" + toYear + "&fromYearYear=" + fromYearYear + "&toYearYear=" + toYearYear + "&filterCourses=" + (filterCourses || ""),
- columns: [
- {
- orderable: false,
- data: "id",
- render: function (data){
- const id = parseInt(data, 10);
- const checked = selectedIds.has(id) ? 'checked' : '';
- return `<input type="checkbox" value="${id}" ${checked} onclick="toggleRecipient(${id})" id="recipient_${id}"/>`;
- }
- },
- {
- data: "last_name",
- render: function (data){
- const d = data.split("|");
- const id = d[1], value = d[0];
- return `<label for="recipient_${id}">${value}</label>`;
- }
- },
- {
- data: "first_name",
- render: function (data){
- const d = data.split("|");
- const id = d[1], value = d[0];
- return `<label for="recipient_${id}">${value}</label>`;
- }
- },
- {
- data: "email",
- render: function (data){
- const d = data.split("|");
- const id = d[1], value = d[0];
- return `<label for="recipient_${id}">${value}</label>`;
- }
- },
- { data: "phone"},
- { data: "age", "type": "num", className:"dt-type-numeric"},
- { data: "year", className:"dt-type-numeric"},
- {
- data: "status",
- render: function (data){
- const d = data.split("|");
- return '<span class="tablesaw-cell-content"><span class="badge tessera-badge ' + d[0] + '">' + d[1] + '</span></span>';
- }
- },
- {
- data: "certificate",
- render: function (data){
- if (!data) return '<span class="tablesaw-cell-content d-flex align-items-center"><i class="ico--ui check absent me-2"></i>Non consegnato</span>';
- const d = data.split("|");
- const icon = d[0] === "0" ? "suspended" : (d[0] === "1" ? "due" : "active");
- const label = d[0] === "0" ? "Scaduto" : (d[0] === "1" ? "In scadenza" : "Scadenza");
- return '<span class="tablesaw-cell-content d-flex align-items-center"><i class="ico--ui check '+icon+' me-2"></i>'+label+' : '+d[1]+'</span>';
- }
- },
- { data: "categories" },
- ],
- order: [
- [1, 'asc']
- ],
- fixedHeader: false,
- thead: {
- 'th': {'background-color': 'blue'}
- },
- layout: {
- topStart : null,
- topEnd : null,
- top1A: null,
- top1B : {
- pageLength: {
- menu: [[10, 25, 50, 100, 100000], [10, 25, 50, 100, "Tutti"]]
- }
- },
- top1C :'search',
- },
- pagingType: 'first_last_numbers',
- language: {
- "url": "/assets/js/Italian.json",
- paginate: {
- first: '<i class="fa-solid fa-angles-left"></i>',
- last: '<i class="fa-solid fa-angles-right"></i>',
- }
- },
- fnInitComplete: function (oSettings, json) {
- var html = ' <a style="cursor:pointer" class="showHideFilter btn--ui"><i class="fa-solid fa-sliders"></i></a>';
- $(".dt-search").append(html);
- }
- });
- $('#recipients-table thead tr th').addClass('col').css("background-color", "#f6f8fa");
- $('#recipients-table').on('draw.dt', function() { $('[data-bs-toggle="popover"]').popover() });
- }
- window.toggleRecipient = function(id) { @this.toggleRecipient(id); }
- </script>
- {{-- CKEditor --}}
- <link rel="stylesheet" href="/assets/libraries/ckeditor5/ckeditor5.css" />
- <script type="importmap">
- {
- "imports": {
- "ckeditor5": "/assets/libraries/ckeditor5/ckeditor5.js",
- "ckeditor5/": "/assets/libraries/ckeditor5/"
- }
- }
- </script>
- <script type="module">
- import { ClassicEditor } from "ckeditor5";
- import { editorConfig } from "/assets/libraries/ckeditor5/config.js";
- window.addEventListener("load-editor", (e) => {
- let detail = e.detail || {};
- let latestLocked = !!detail.locked;
- let html = detail.html ?? '';
- let el = document.querySelector('#message');
- if (el.ckeditorInstance) el.ckeditorInstance.destroy();
-
- editorConfig.simpleUpload = {
- uploadUrl: "{{ route('ckeditor.upload', ['_token' => csrf_token()]) }}"
- };
- ClassicEditor
- .create(el, editorConfig)
- .then(editor => {
- el.ckeditorInstance = editor;
- editor.setData(html);
- if (latestLocked) {
- editor.enableReadOnlyMode('locked');
- return;
- }
- })
- .catch(console.error)
- });
- window.submitEmail = function(action){
- const ed = document.querySelector('#message')?.ckeditorInstance;
- const html = ed ? ed.getData() : '';
- if (action === 'draft') {
- @this.call('saveDraft', html);
- } else if (action === 'send') {
- @this.call('sendNow', html);
- } else {
- @this.call('scheduleMessage', html);
- }
- };
- window.addEventListener("scroll-top", (e) => {
- let wrapper = document.querySelector('#card--dashboard');
- if (wrapper) {
- wrapper.scrollTo({top: 0, behavior: 'smooth'});
- }
- });
- </script>
- {{-- END CKEditor --}}
- @endpush
|