mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 00:01:21 +00:00
Improve notifications
This commit is contained in:
@@ -216,10 +216,12 @@ class AdminUserController extends BasePageController
|
||||
{
|
||||
if ($request->has('id')) {
|
||||
$user = User::find($request->input('id'));
|
||||
$username = $user->username; // Store username before deletion
|
||||
|
||||
$user->delete();
|
||||
|
||||
return redirect()->to('admin/user-list');
|
||||
// Redirect with username to display in notification
|
||||
return redirect()->to('admin/user-list?deleted=1&username='.urlencode($username));
|
||||
}
|
||||
|
||||
if ($request->has('redir')) {
|
||||
|
||||
@@ -94,9 +94,12 @@
|
||||
<td>{$user->deleted_at|date_format:"%Y-%m-%d %H:%M"}</td>
|
||||
<td>{if $user->lastlogin != ""}{$user->lastlogin|date_format:"%Y-%m-%d %H:%M"}{else}Never{/if}</td>
|
||||
<td>
|
||||
<a href="{$smarty.const.WWW_TOP}/admin/deleted-users/restore/{$user->id}" class="btn btn-success btn-sm me-2" title="Restore User">
|
||||
<button class="btn btn-success btn-sm me-2 restore-user"
|
||||
data-user-id="{$user->id}"
|
||||
data-username="{$user->username}"
|
||||
title="Restore User">
|
||||
<i class="fas fa-user-check"></i> Restore
|
||||
</a>
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm delete-permanently"
|
||||
data-user-id="{$user->id}"
|
||||
data-username="{$user->username}"
|
||||
@@ -158,6 +161,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Restore User Confirmation Modal -->
|
||||
<div class="modal fade" id="restoreUserModal" tabindex="-1" aria-labelledby="restoreUserModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-success text-white">
|
||||
<h5 class="modal-title" id="restoreUserModalLabel">Confirm User Restoration</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle"></i> Please confirm this action
|
||||
</div>
|
||||
<p>You are about to restore user <strong id="restoreUserName"></strong>.</p>
|
||||
<p>This will reactivate the user account and grant them access to the system again.</p>
|
||||
<p>Are you sure you want to continue?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<a href="#" id="confirmRestoreBtn" class="btn btn-success">
|
||||
<i class="fas fa-user-check"></i> Restore User
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Set up delete confirmation modal
|
||||
@@ -175,5 +204,21 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
deleteUserModal.show();
|
||||
});
|
||||
});
|
||||
|
||||
// Set up restore confirmation modal
|
||||
const restoreUserModal = new bootstrap.Modal(document.getElementById('restoreUserModal'));
|
||||
const restoreButtons = document.querySelectorAll('.restore-user');
|
||||
|
||||
restoreButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const userId = this.getAttribute('data-user-id');
|
||||
const username = this.getAttribute('data-username');
|
||||
|
||||
document.getElementById('restoreUserName').textContent = username;
|
||||
document.getElementById('confirmRestoreBtn').href = '{$smarty.const.WWW_TOP}/admin/deleted-users/restore/' + userId;
|
||||
|
||||
restoreUserModal.show();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
</a>
|
||||
{/if}
|
||||
{if $user->roles_id != "2"}
|
||||
<a href="{{url("/admin/user-delete?id={$user->id}")}}" class="btn btn-sm btn-outline-danger confirm_action" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete user">
|
||||
<a href="{{url("/admin/user-delete?id={$user->id}")}}" class="btn btn-sm btn-outline-danger custom_delete_action" data-bs-toggle="tooltip" data-bs-placement="top" title="Delete user">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
{/if}
|
||||
@@ -265,94 +265,132 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{literal}
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize tooltips
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
<!-- Delete User Confirmation Modal -->
|
||||
<div class="modal fade" id="deleteUserModal" tabindex="-1" aria-labelledby="deleteUserModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title" id="deleteUserModalLabel">
|
||||
<i class="fa fa-exclamation-triangle me-2"></i>Delete User Confirmation
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="fw-bold mb-2">You are about to delete the following user:</p>
|
||||
<div class="alert alert-info d-flex align-items-center">
|
||||
<i class="fa fa-user me-2 fs-5"></i>
|
||||
<span id="deleteUserName" class="fw-bold fs-5"></span>
|
||||
</div>
|
||||
<p>This action will soft-delete the user account. The user will no longer be able to log in, but their data will remain in the database.</p>
|
||||
<p class="text-danger fw-bold">Are you absolutely sure you want to proceed?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||
<a href="#" id="confirmDeleteBtn" class="btn btn-danger">
|
||||
<i class="fa fa-trash me-1"></i>Delete User
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
// Confirm action for delete
|
||||
document.querySelectorAll('.confirm_action').forEach(function(element) {
|
||||
element.addEventListener('click', function(e) {
|
||||
if (!confirm('Are you sure you want to delete this user? This cannot be undone.')) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
<script>
|
||||
{literal}
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Initialize tooltips
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
|
||||
// Enhanced delete confirmation
|
||||
document.querySelectorAll('.custom_delete_action').forEach(function(element) {
|
||||
element.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Get the user details
|
||||
const row = this.closest('tr');
|
||||
const username = row.querySelector('td:first-child a').textContent.trim();
|
||||
const deleteUrl = this.getAttribute('href');
|
||||
|
||||
// Set the modal content
|
||||
document.getElementById('deleteUserName').textContent = username;
|
||||
document.getElementById('confirmDeleteBtn').setAttribute('href', deleteUrl);
|
||||
|
||||
// Show the modal
|
||||
const deleteModal = new bootstrap.Modal(document.getElementById('deleteUserModal'));
|
||||
deleteModal.show();
|
||||
});
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
{literal}
|
||||
/* Sort controls styling */
|
||||
.sort-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 0.8rem;
|
||||
margin-left: 0.3rem;
|
||||
// Toast notification system
|
||||
function showToast(message, type) {
|
||||
const toastContainer = document.getElementById('toast-container');
|
||||
|
||||
const toastElement = document.createElement('div');
|
||||
toastElement.className = `toast align-items-center text-white bg-${type} border-0`;
|
||||
toastElement.setAttribute('role', 'alert');
|
||||
toastElement.setAttribute('aria-live', 'assertive');
|
||||
toastElement.setAttribute('aria-atomic', 'true');
|
||||
|
||||
const toastFlex = document.createElement('div');
|
||||
toastFlex.className = 'd-flex';
|
||||
|
||||
const toastBody = document.createElement('div');
|
||||
toastBody.className = 'toast-body';
|
||||
toastBody.innerHTML = message;
|
||||
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.type = 'button';
|
||||
closeButton.className = 'btn-close btn-close-white me-2 m-auto';
|
||||
closeButton.setAttribute('data-bs-dismiss', 'toast');
|
||||
closeButton.setAttribute('aria-label', 'Close');
|
||||
|
||||
toastFlex.appendChild(toastBody);
|
||||
toastFlex.appendChild(closeButton);
|
||||
toastElement.appendChild(toastFlex);
|
||||
toastContainer.appendChild(toastElement);
|
||||
|
||||
const toast = new bootstrap.Toast(toastElement, {
|
||||
delay: 5000
|
||||
});
|
||||
toast.show();
|
||||
|
||||
toastElement.addEventListener('hidden.bs.toast', function () {
|
||||
toastElement.remove();
|
||||
});
|
||||
}
|
||||
|
||||
.sort-icon {
|
||||
color: #6c757d;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
// If there's a success parameter in URL (will be added by our controller)
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('deleted')) {
|
||||
const username = urlParams.get('username');
|
||||
showToast(`User "${username}" has been successfully deleted.`, 'success');
|
||||
}
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
||||
|
||||
.sort-icon:hover, .sort-icon.active {
|
||||
color: #0d6efd;
|
||||
opacity: 1;
|
||||
}
|
||||
<!-- Toast container for notifications -->
|
||||
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||
|
||||
/* Table styling improvements */
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
<style>
|
||||
{literal}
|
||||
/* Sort controls styling */
|
||||
.sort-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 0.8rem;
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
/* Badge styling */
|
||||
.badge {
|
||||
font-weight: 500;
|
||||
padding: 0.4em 0.6em;
|
||||
}
|
||||
.sort-icon {
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
/* Pagination container */
|
||||
.pagination-container {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Improve buttons spacing in small screens */
|
||||
@media (max-width: 767.98px) {
|
||||
.btn-group .btn {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
.card-footer .d-flex {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
justify-content: center !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Improve search form on small screens */
|
||||
@media (max-width: 767.98px) {
|
||||
#user-search-form .row {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#user-search-form .col-md-12 {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
{/literal}
|
||||
</style>
|
||||
/* Toast styling */
|
||||
.toast {
|
||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
{/literal}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user