Feat: User Management
This commit is contained in:
@@ -12,6 +12,16 @@
|
||||
</a>
|
||||
</li>
|
||||
@if(auth()->user()->role->name === 'Admin')
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-1" href="{{ route('admin.users.index') }}">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<i class="fas fa-users text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">User Management</h6>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-1" href="{{ route('admin.ActivitiesAttendedResponses') }}">
|
||||
<div class="d-flex align-items-center">
|
||||
@@ -180,7 +190,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#activitiesAttendedCollapse" role="button" aria-expanded="false" aria-controls="activitiesAttendedCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-calendar-check text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Activities Attended</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -205,7 +215,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#activitiesOrganisedCollapse" role="button" aria-expanded="false" aria-controls="activitiesOrganisedCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-calendar-alt text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Activities Organised</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -230,7 +240,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#ivOrganisedCollapse" role="button" aria-expanded="false" aria-controls="ivOrganisedCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-industry text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">IV Organised</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -255,7 +265,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#publicationsCollapse" role="button" aria-expanded="false" aria-controls="publicationsCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-book text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Publications</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -280,7 +290,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#booksPublishedCollapse" role="button" aria-expanded="false" aria-controls="booksPublishedCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-book-open text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Books Published</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -305,7 +315,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#externalEngagementCollapse" role="button" aria-expanded="false" aria-controls="externalEngagementCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-handshake text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">External Engagement</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -330,7 +340,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#onlineCoursesCollapse" role="button" aria-expanded="false" aria-controls="onlineCoursesCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-laptop-code text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Online Courses</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
@@ -355,7 +365,7 @@
|
||||
<a class="nav-link py-1" data-bs-toggle="collapse" href="#patentsCollapse" role="button" aria-expanded="false" aria-controls="patentsCollapse">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{ asset('assets/frontend/images/students.svg') }}" alt="activities-icon" class="img-fluid" style="max-height: 20px;">
|
||||
<i class="fas fa-file-alt text-white"></i>
|
||||
</div>
|
||||
<h6 class="col-10 ps-2 m-0 textWhite sidebar-text small">Patents/Copyrights</h6>
|
||||
<i class="fas fa-chevron-down ms-auto small textWhite collapse-icon"></i>
|
||||
|
||||
501
resources/views/pages/users/index.blade.php
Normal file
501
resources/views/pages/users/index.blade.php
Normal file
@@ -0,0 +1,501 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-4">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h3 class="page-title m-0">
|
||||
<i class="fas fa-list-alt me-2 text-danger"></i>All Users
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Filter Controls -->
|
||||
<div class="row mb-4 align-items-center">
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light">Department</span>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light">Role</span>
|
||||
<select id="role-filter" class="form-select">
|
||||
<option value="">All Roles</option>
|
||||
<!-- Category options would be populated dynamically -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 d-flex justify-content-end">
|
||||
<!-- Column Selector -->
|
||||
<div id="columnsSelector" class="">
|
||||
@php
|
||||
use Illuminate\Support\Str;
|
||||
$labels = [
|
||||
'ID',
|
||||
'Name',
|
||||
'Email',
|
||||
'Department Name',
|
||||
'Orcid Id',
|
||||
'Scopus Id',
|
||||
'Mobile No',
|
||||
'Extension',
|
||||
'Role Name',
|
||||
'Actions',
|
||||
];
|
||||
$columns = [];
|
||||
foreach ($labels as $i => $label) {
|
||||
$columns[] = [
|
||||
'label' => $label,
|
||||
'id' => 'column-' . Str::slug($label, '-'),
|
||||
'value' => $i, // 0-based index
|
||||
'checked' => true,
|
||||
];
|
||||
}
|
||||
@endphp
|
||||
<x-column-selector :columns="$columns" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-responsive">
|
||||
<table id="responses-table" class="table table-striped table-hover"> <thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Department Name</th>
|
||||
<th>Orcid Id</th>
|
||||
<th>Scopus Id</th>
|
||||
<th>Mobile No</th>
|
||||
<th>Extension</th>
|
||||
<th>Role Name</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- Data will be loaded via AJAX -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@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 : 'ActivitiesAttended' }}";
|
||||
const csrf_token = "{{ csrf_token() }}";
|
||||
$(document).ready(function() {
|
||||
|
||||
const sheetName = "User Data"; // Default sheet name
|
||||
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 - FIXED to check if responsive is initialized
|
||||
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('#responses-table')) {
|
||||
$('#responses-table').DataTable().destroy();
|
||||
}
|
||||
|
||||
table = $("#responses-table").DataTable({
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
responsive: true,
|
||||
ajax: {
|
||||
url: route,
|
||||
data: function(d) { d.department = $('#department-filter').val();
|
||||
d.role = $('#role-filter').val();
|
||||
}
|
||||
}, columns: [
|
||||
{ data: 'id', name: 'id', searchable: false },
|
||||
{ data: 'name', name: 'name' },
|
||||
{ data: 'email', name: 'email' },
|
||||
{ data: 'department_name', name: 'department_name' },
|
||||
{ data: 'orcid_id', name: 'orcid_id' },
|
||||
{ data: 'scopus_id', name: 'scopus_id', searchable: false },
|
||||
{ data: 'mobile_no', name: 'mobile_no' },
|
||||
{ data: 'extension', name: 'extension' },
|
||||
{ data: 'role_name', name: 'role_name' },
|
||||
{
|
||||
data: 'action',
|
||||
name: 'action',
|
||||
orderable: false,
|
||||
searchable: false
|
||||
}
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
targets: '_all',
|
||||
className: 'text-center wrap-text'
|
||||
},
|
||||
{
|
||||
targets: 9,
|
||||
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,
|
||||
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_",
|
||||
searchPlaceholder: "Search records...",
|
||||
lengthMenu: "<i class='fas fa-list me-1'></i> _MENU_ records per page",
|
||||
info: "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
paginate: {
|
||||
first: "<i class='fas fa-angle-double-left'></i>",
|
||||
last: "<i class='fas fa-angle-double-right'></i>",
|
||||
next: "<i class='fas fa-angle-right'></i>",
|
||||
previous: "<i class='fas fa-angle-left'></i>"
|
||||
}
|
||||
},
|
||||
// Important: Initialize the column visibility after table is drawn
|
||||
initComplete: function() {
|
||||
// Now it's safe to set column visibility
|
||||
toggleColumnVisibility();
|
||||
},
|
||||
});
|
||||
|
||||
// Apply filters when they change
|
||||
$('#department-filter, #role-filter').change(function() {
|
||||
table.ajax.reload();
|
||||
});
|
||||
|
||||
return table;
|
||||
};
|
||||
|
||||
// Delete button handler
|
||||
$('#responses-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 inline role change
|
||||
$('#responses-table').on('change', '.user-role-dropdown', function() {
|
||||
const userId = $(this).data('user-id');
|
||||
const newRoleId = $(this).val();
|
||||
$.ajax({
|
||||
url: `/users/${userId}`,
|
||||
type: 'PATCH',
|
||||
data: {
|
||||
_token: csrf_token,
|
||||
role_id: newRoleId
|
||||
},
|
||||
success: function() {
|
||||
table.ajax.reload(null, false);
|
||||
showToast('Role updated successfully', 'success');
|
||||
},
|
||||
error: function() {
|
||||
showToast('Error updating role', 'danger');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 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 the appropriate data route based on user role
|
||||
const userRole = "{{ auth()->user()->role->name }}";
|
||||
let dataRoute = "{{ route('admin.users.data') }}";
|
||||
|
||||
|
||||
// Initialize the data table
|
||||
table = initAjaxRoute(dataRoute);
|
||||
|
||||
// Attach change event listener to column visibility checkboxes AFTER table is initialized
|
||||
$('.column-checkbox').on('change', function() {
|
||||
toggleColumnVisibility();
|
||||
});
|
||||
|
||||
// Ensure "Actions" column is always visible
|
||||
$('#column-actions').prop('disabled', true);
|
||||
|
||||
|
||||
// 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 */
|
||||
#responses-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