All pages updated with all features including filters
This commit is contained in:
@@ -9,13 +9,90 @@
|
||||
<h3 class="page-title m-0">
|
||||
<i class="fas fa-file-alt me-2 text-primary"></i>All Patents
|
||||
</h3>
|
||||
<!-- Include the reusable send-email component -->
|
||||
<x-send-email />
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Filter Controls -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light">Department</span>
|
||||
@if(auth()->user()->role_id == 1)
|
||||
{{-- Admin: can choose any department --}}
|
||||
<select id="department-filter" class="form-select">
|
||||
<option value="">All Departments</option>
|
||||
@foreach($departments as $department)
|
||||
<option value="{{ $department->id }}">{{ $department->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@else
|
||||
{{-- Coordinator/Faculty: department is fixed --}}
|
||||
<select id="department-filter" class="form-select" disabled>
|
||||
<option value="{{ auth()->user()->department_id }}">
|
||||
{{ auth()->user()->department->name }}
|
||||
</option>
|
||||
</select>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light">Status</span>
|
||||
<select id="status-filter" class="form-select">
|
||||
<option value="">Both</option>
|
||||
<option value="Granted">Granted</option>
|
||||
<option value="Filed">Filed</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light">Date Range</span>
|
||||
<input type="date" id="date-from" class="form-control">
|
||||
<span class="input-group-text bg-light">to</span>
|
||||
<input type="date" id="date-to" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column Selector -->
|
||||
<div class="flex justify-between col-md-12 mt-3 mb-4">
|
||||
<!-- Include the reusable download-proofs component -->
|
||||
<x-download-proofs :route="route('admin.downloadProofs')" :model="'Patent'" />
|
||||
@php
|
||||
use Illuminate\Support\Str;
|
||||
$labels = [
|
||||
'Faculty',
|
||||
'Department',
|
||||
'Title',
|
||||
'Investigator',
|
||||
'Application No',
|
||||
'Type',
|
||||
'Date Of Submission',
|
||||
'Date Of Filling',
|
||||
'Status',
|
||||
];
|
||||
$columns = [];
|
||||
foreach ($labels as $i => $label) {
|
||||
$columns[] = [
|
||||
'label' => $label,
|
||||
'id' => 'column-' . Str::slug($label, '-'),
|
||||
'value' => $i + 2,
|
||||
'checked' => $label !== 'Date Of Filling',
|
||||
];
|
||||
}
|
||||
@endphp
|
||||
<x-column-selector :columns="$columns" />
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-responsive">
|
||||
<table id="patents-table" class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="select-checkbox"></th>
|
||||
<th>ID</th>
|
||||
<th>Faculty</th>
|
||||
<th>Department</th>
|
||||
@@ -42,11 +119,81 @@
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/js/all.min.js" integrity="sha512-Tn2m0TIpgVyTzzvmxLNuqbSJH3JP8jm+Cy3hvHrW7ndTDcJ1w5mBiksqDBb8GpE2ksktFvDB/ykZ0mDpsZj20w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script>
|
||||
const downloadProofsRoute = "{{ route('admin.downloadProofs') }}";
|
||||
const currentModel = "{{ isset($model) ? $model : 'Patent' }}";
|
||||
const csrf_token = "{{ csrf_token() }}";
|
||||
$(document).ready(function() {
|
||||
const sheetName = "Patents";
|
||||
// Handle "Select All" checkbox for missing proofs modal
|
||||
$('#selectAll').change(function() {
|
||||
const isChecked = $(this).prop('checked');
|
||||
$('input[name="categories[]"]').prop('checked', isChecked);
|
||||
});
|
||||
|
||||
// Update "Select All" when individual checkboxes change
|
||||
$('input[name="categories[]"]').change(function() {
|
||||
const totalCheckboxes = $('input[name="categories[]"]').length;
|
||||
const checkedCheckboxes = $('input[name="categories[]"]:checked').length;
|
||||
$('#selectAll').prop('checked', totalCheckboxes === checkedCheckboxes);
|
||||
});
|
||||
|
||||
// Form validation for the modal
|
||||
const form = document.getElementById('missingProofsForm');
|
||||
if (form) {
|
||||
form.addEventListener('submit', function(e) {
|
||||
const checkboxes = form.querySelectorAll('input[type="checkbox"]:checked');
|
||||
|
||||
if (checkboxes.length === 0) {
|
||||
e.preventDefault();
|
||||
alert('Please select at least one category before sending emails.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const sheetName = "Patents Report";
|
||||
let table; // Declare table variable in the outer scope
|
||||
|
||||
function exportOptions() {
|
||||
return {
|
||||
columns: ':visible',
|
||||
format: {
|
||||
body: function(data, row, column, node) {
|
||||
if ($(node).find('select').length) {
|
||||
return $(node).find("select option:selected").text();
|
||||
}
|
||||
return $(node).text();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Function to toggle column visibility
|
||||
function toggleColumnVisibility() {
|
||||
$('.column-checkbox').each(function() {
|
||||
const columnIndex = $(this).val();
|
||||
const isChecked = $(this).is(':checked');
|
||||
|
||||
// Show or hide the column based on checkbox state
|
||||
if (table) {
|
||||
table.column(columnIndex).visible(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
// Adjust table layout only if table and responsive are initialized
|
||||
if (table && table.responsive) {
|
||||
table.columns.adjust().responsive.recalc();
|
||||
} else if (table) {
|
||||
table.columns.adjust();
|
||||
}
|
||||
}
|
||||
|
||||
var initAjaxRoute = function(route) {
|
||||
// If table already exists, destroy it before re-initializing
|
||||
if ($.fn.DataTable.isDataTable('#patents-table')) {
|
||||
$('#patents-table').DataTable().destroy();
|
||||
}
|
||||
|
||||
table = $("#patents-table").DataTable({
|
||||
fnDestroy: true,
|
||||
processing: true,
|
||||
@@ -54,8 +201,20 @@
|
||||
responsive: true,
|
||||
ajax: {
|
||||
url: route,
|
||||
data: function(d) {
|
||||
d.department = $('#department-filter').val();
|
||||
d.status = $('#status-filter').val();
|
||||
d.dateFrom = $('#date-from').val();
|
||||
d.dateTo = $('#date-to').val();
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
data: null,
|
||||
defaultContent: '',
|
||||
orderable: false,
|
||||
searchable: false
|
||||
},
|
||||
{ data: 'id', name: 'id', searchable: false },
|
||||
{ data: 'user_name', name: 'user_name', orderable: true },
|
||||
{ data: 'department_name', name: 'department_name', orderable: true },
|
||||
@@ -69,15 +228,66 @@
|
||||
{ data: 'action', name: 'action', orderable: false, searchable: false },
|
||||
],
|
||||
columnDefs: [
|
||||
{ targets: '_all', className: 'text-center wrap-text' },
|
||||
{
|
||||
targets: 0,
|
||||
orderable: false,
|
||||
className: 'select-checkbox',
|
||||
render: function(data, type, row) {
|
||||
return row.proof ?
|
||||
'<input type="checkbox" class="row-checkbox" data-id="' + row.id + '">' :
|
||||
'<input type="checkbox" disabled>';
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: '_all',
|
||||
className: 'text-center wrap-text'
|
||||
},
|
||||
{
|
||||
targets: 11,
|
||||
render: function(data, type, row) {
|
||||
return '<div class="btn-group" role="group">' +
|
||||
data +
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
],
|
||||
dom: '<"d-flex justify-content-between align-items-center mb-3"<"d-flex align-items-center"l><"d-flex"f<"ms-2"B>>>rtip',
|
||||
buttons: [
|
||||
{ extend: 'copy', text: '<i class="fas fa-copy me-1"></i> Copy', className: 'btn btn-sm btn-outline-white', title: sheetName },
|
||||
{ extend: 'csv', text: '<i class="fas fa-file-csv me-1"></i> CSV', className: 'btn btn-sm btn-outline-white', title: sheetName },
|
||||
{ extend: 'excel', text: '<i class="fas fa-file-excel me-1"></i> Excel', className: 'btn btn-sm btn-outline-white', title: sheetName },
|
||||
{ extend: 'pdf', text: '<i class="fas fa-file-pdf me-1"></i> PDF', className: 'btn btn-sm btn-outline-white', title: sheetName },
|
||||
{ extend: 'print', text: '<i class="fas fa-print me-1"></i> Print', className: 'btn btn-sm btn-outline-white', title: sheetName },
|
||||
{
|
||||
extend: 'copy',
|
||||
text: '<i class="fas fa-copy me-1"></i> Copy',
|
||||
className: 'btn btn-sm btn-outline-white',
|
||||
title: sheetName,
|
||||
exportOptions: exportOptions()
|
||||
},
|
||||
{
|
||||
extend: 'csv',
|
||||
text: '<i class="fas fa-file-csv me-1"></i> CSV',
|
||||
className: 'btn btn-sm btn-outline-white',
|
||||
title: sheetName,
|
||||
exportOptions: exportOptions()
|
||||
},
|
||||
{
|
||||
extend: 'excel',
|
||||
text: '<i class="fas fa-file-excel me-1"></i> Excel',
|
||||
className: 'btn btn-sm btn-outline-white',
|
||||
title: sheetName,
|
||||
exportOptions: exportOptions()
|
||||
},
|
||||
{
|
||||
extend: 'pdf',
|
||||
text: '<i class="fas fa-file-pdf me-1"></i> PDF',
|
||||
className: 'btn btn-sm btn-outline-white',
|
||||
title: sheetName,
|
||||
exportOptions: exportOptions()
|
||||
},
|
||||
{
|
||||
extend: 'print',
|
||||
text: '<i class="fas fa-print me-1"></i> Print',
|
||||
className: 'btn btn-sm btn-outline-white',
|
||||
title: sheetName,
|
||||
exportOptions: exportOptions()
|
||||
}
|
||||
],
|
||||
language: {
|
||||
search: "<i class='fas fa-search'></i> _INPUT_",
|
||||
@@ -90,10 +300,162 @@
|
||||
next: "<i class='fas fa-angle-right'></i>",
|
||||
previous: "<i class='fas fa-angle-left'></i>"
|
||||
}
|
||||
},
|
||||
// Initialize the column visibility after table is drawn
|
||||
initComplete: function() {
|
||||
// Set column visibility
|
||||
toggleColumnVisibility();
|
||||
|
||||
// Add select-all checkbox
|
||||
addSelectAllCheckbox();
|
||||
},
|
||||
drawCallback: function() {
|
||||
// Ensure select-all checkbox is present on redraw
|
||||
addSelectAllCheckbox();
|
||||
}
|
||||
});
|
||||
|
||||
// Apply filters when they change
|
||||
$('#department-filter, #status-filter, #date-from, #date-to').change(function() {
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
return table;
|
||||
};
|
||||
|
||||
// Delete button handler
|
||||
$('#patents-table').on('click', '.delete-btn', function() {
|
||||
if (confirm('Are you sure you want to delete this record?')) {
|
||||
const id = $(this).data('id');
|
||||
const url = $(this).data('url');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'DELETE',
|
||||
data: {
|
||||
"_token": "{{ csrf_token() }}"
|
||||
},
|
||||
success: function(result) {
|
||||
table.ajax.reload();
|
||||
showToast('Record deleted successfully', 'success');
|
||||
},
|
||||
error: function(error) {
|
||||
console.error(error);
|
||||
showToast('Error deleting record', 'danger');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Handle row selection and Download button state
|
||||
$('#patents-table').on('change', '.row-checkbox', function() {
|
||||
const selectedRows = $('.row-checkbox:checked').length;
|
||||
$('#download-proofs').prop('disabled', selectedRows === 0);
|
||||
});
|
||||
|
||||
// Download proofs button handler
|
||||
$('#download-proofs').on('click', function() {
|
||||
const selectedIds = [];
|
||||
|
||||
$('.row-checkbox:checked').each(function() {
|
||||
const id = $(this).data('id');
|
||||
if (id) selectedIds.push(id);
|
||||
});
|
||||
|
||||
if (selectedIds.length > 0) {
|
||||
// Create a form to submit the request
|
||||
const form = $('<form></form>')
|
||||
.attr('method', 'POST')
|
||||
.attr('action', downloadProofsRoute)
|
||||
.css('display', 'none');
|
||||
|
||||
// Add CSRF token
|
||||
$('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', '_token')
|
||||
.attr('value', csrf_token)
|
||||
.appendTo(form);
|
||||
|
||||
// Add selected IDs
|
||||
$('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'ids')
|
||||
.attr('value', JSON.stringify(selectedIds))
|
||||
.appendTo(form);
|
||||
|
||||
// Add model name
|
||||
$('<input>')
|
||||
.attr('type', 'hidden')
|
||||
.attr('name', 'model')
|
||||
.attr('value', currentModel)
|
||||
.appendTo(form);
|
||||
|
||||
$('body').append(form);
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
|
||||
// Function to add select-all checkbox to the table header
|
||||
function addSelectAllCheckbox() {
|
||||
// Only add if it doesn't exist yet
|
||||
if ($('#select-all-checkbox').length === 0) {
|
||||
const selectAllCheckbox = $('<input>', {
|
||||
type: 'checkbox',
|
||||
id: 'select-all-checkbox',
|
||||
class: 'form-check-input'
|
||||
});
|
||||
|
||||
// Add to the first header column
|
||||
$('#patents-table thead th.select-checkbox').html(selectAllCheckbox);
|
||||
|
||||
// Handle the select all functionality
|
||||
$('#select-all-checkbox').on('change', function() {
|
||||
const isChecked = $(this).prop('checked');
|
||||
$('.row-checkbox:not(:disabled)').prop('checked', isChecked);
|
||||
|
||||
// Update download button state
|
||||
const selectedRows = $('.row-checkbox:checked').length;
|
||||
$('#download-proofs').prop('disabled', selectedRows === 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Toast notification function
|
||||
function showToast(message, type) {
|
||||
const toastContainer = document.createElement('div');
|
||||
toastContainer.className = 'position-fixed bottom-0 start-0 p-3';
|
||||
toastContainer.style.zIndex = '1050';
|
||||
|
||||
const toastEl = document.createElement('div');
|
||||
toastEl.className = `toast align-items-center text-white bg-${type} border-0`;
|
||||
toastEl.setAttribute('role', 'alert');
|
||||
toastEl.setAttribute('aria-live', 'assertive');
|
||||
toastEl.setAttribute('aria-atomic', 'true');
|
||||
|
||||
toastEl.innerHTML = `
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">
|
||||
${message}
|
||||
</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
toastContainer.appendChild(toastEl);
|
||||
document.body.appendChild(toastContainer);
|
||||
|
||||
const toast = new bootstrap.Toast(toastEl, {
|
||||
autohide: true,
|
||||
delay: 3000
|
||||
});
|
||||
|
||||
toast.show();
|
||||
|
||||
toastEl.addEventListener('hidden.bs.toast', function() {
|
||||
document.body.removeChild(toastContainer);
|
||||
});
|
||||
}
|
||||
|
||||
// Set appropriate route based on user role
|
||||
const userRole = "{{ auth()->user()->role->name }}";
|
||||
let dataRoute = "{{ route('admin.PatentsResponses.data') }}";
|
||||
@@ -105,7 +467,178 @@
|
||||
dataRoute = "{{ route('faculty.PatentsResponses.data') }}";
|
||||
}
|
||||
|
||||
initAjaxRoute(dataRoute);
|
||||
// Initialize the data table
|
||||
table = initAjaxRoute(dataRoute);
|
||||
|
||||
// Attach change event listener to column visibility checkboxes
|
||||
$('.column-checkbox').on('change', function() {
|
||||
toggleColumnVisibility();
|
||||
});
|
||||
|
||||
// Ensure "Actions" column is always visible
|
||||
$('#column-actions').prop('disabled', true);
|
||||
|
||||
// Select all columns button
|
||||
$('#select-all-columns').click(function() {
|
||||
$('.column-checkbox').prop('checked', true).trigger('change');
|
||||
});
|
||||
|
||||
// Deselect all columns button
|
||||
$('#deselect-all-columns').click(function() {
|
||||
$('.column-checkbox').prop('checked', false).trigger('change');
|
||||
});
|
||||
|
||||
// Prevent dropdown from closing when clicking inside it
|
||||
$('.dropdown-menu').on('click', function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// Set department filter from query string if present
|
||||
$(document).ready(function() {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const departmentId = urlParams.get('department_id');
|
||||
if (departmentId) {
|
||||
$('#department-filter').val(departmentId).trigger('change');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.form-check-input:checked {
|
||||
background-color: #b7202e;
|
||||
border-color: #ed1c24;
|
||||
}
|
||||
|
||||
|
||||
.dropdown-menu {
|
||||
background-color: #fff;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:checked {
|
||||
background-color: #b7202e;
|
||||
border-color: #ed1c24;
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:checked:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:checked:focus-visible {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:checked {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked) {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):checked {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):not(:checked) {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):not(:checked):checked {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):not(:checked):not(:checked) {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):not(:checked):not(:checked):checked {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.dropdown-menu .form-check-input:focus-visible:not(:checked):not(:checked):not(:checked):not(:checked) {
|
||||
box-shadow: 0 0 0 0.2rem rgba(189, 72, 46, 0.25);
|
||||
}
|
||||
|
||||
.form-switch .form-check-input {
|
||||
width: 2.5em;
|
||||
margin-left: -2.8em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-switch .form-check-input:focus {
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.form-switch .form-check-input:checked {
|
||||
background-position: right center;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
|
||||
transition: background-position 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
/* Enhance the toggle appearance */
|
||||
.form-switch .form-check-input {
|
||||
background-size: contain;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Ensure the table container is responsive */
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Ensure the table fits within the container */
|
||||
#patents-table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
|
||||
.select-checkbox {
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select-checkbox input[type="checkbox"] {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select-checkbox input[type="checkbox"]:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Style the Download button */
|
||||
#download-proofs {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
}
|
||||
|
||||
#download-proofs:hover:not(:disabled) {
|
||||
background-color: #218838;
|
||||
border-color: #218838;
|
||||
}
|
||||
|
||||
#download-proofs:disabled {
|
||||
opacity: 0.65;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user