mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 17:01:16 +00:00
Update stacked role view
This commit is contained in:
@@ -427,6 +427,40 @@ final class User extends Authenticatable
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pending stacked role changes for this user.
|
||||
* Returns an array of stacked role changes that haven't been activated yet (effective_date is in the future).
|
||||
*
|
||||
* @return \Illuminate\Support\Collection<int, array{
|
||||
* role: Role|null,
|
||||
* role_name: string,
|
||||
* start_date: Carbon,
|
||||
* end_date: Carbon,
|
||||
* is_current_pending: bool
|
||||
* }>
|
||||
*/
|
||||
public function getAllPendingStackedRoles(): \Illuminate\Support\Collection
|
||||
{
|
||||
// Get all stacked role changes from history where effective_date is in the future
|
||||
$stackedHistory = UserRoleHistory::where('user_id', $this->id)
|
||||
->where('is_stacked', true)
|
||||
->where('effective_date', '>', now())
|
||||
->orderBy('effective_date', 'asc')
|
||||
->get();
|
||||
|
||||
return $stackedHistory->map(function ($history) {
|
||||
$role = Role::find($history->new_role_id);
|
||||
return [
|
||||
'role' => $role,
|
||||
'role_name' => $role?->name ?? 'Unknown Role',
|
||||
'start_date' => $history->effective_date,
|
||||
'end_date' => $history->new_expiry_date,
|
||||
'is_current_pending' => $this->pending_roles_id === $history->new_role_id
|
||||
&& $this->pending_role_start_date?->equalTo($history->effective_date),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comprehensive role expiry information.
|
||||
*
|
||||
|
||||
@@ -322,51 +322,117 @@
|
||||
</div>
|
||||
|
||||
<!-- Pending Role Information -->
|
||||
@if(!is_array($user) && !empty($user->pending_roles_id) && !empty($user->pending_role_start_date))
|
||||
<div class="border-2 border-blue-300 dark:border-blue-600 rounded-lg p-4 bg-gradient-to-br from-blue-50 via-blue-50 to-white dark:from-blue-900/30 dark:via-blue-900/20 dark:to-gray-800 shadow-md">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
||||
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
||||
Pending Stacked Role
|
||||
</label>
|
||||
<span class="px-3 py-1 inline-flex items-center text-xs leading-5 font-bold rounded-full bg-blue-200 dark:bg-blue-800 text-blue-800 dark:text-blue-100 animate-pulse">
|
||||
<i class="fa fa-clock mr-1"></i> SCHEDULED
|
||||
</span>
|
||||
@if(!is_array($user))
|
||||
@php
|
||||
$allPendingRoles = $user->getAllPendingStackedRoles();
|
||||
@endphp
|
||||
@if($allPendingRoles->count() > 0)
|
||||
<div class="border-2 border-blue-300 dark:border-blue-600 rounded-lg p-4 bg-gradient-to-br from-blue-50 via-blue-50 to-white dark:from-blue-900/30 dark:via-blue-900/20 dark:to-gray-800 shadow-md">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
||||
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
||||
Pending Stacked Role{{ $allPendingRoles->count() > 1 ? 's' : '' }}
|
||||
<span class="ml-2 px-2 py-0.5 bg-blue-600 text-white text-xs rounded-full">{{ $allPendingRoles->count() }}</span>
|
||||
</label>
|
||||
<span class="px-3 py-1 inline-flex items-center text-xs leading-5 font-bold rounded-full bg-blue-200 dark:bg-blue-800 text-blue-800 dark:text-blue-100 animate-pulse">
|
||||
<i class="fa fa-clock mr-1"></i> SCHEDULED
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
@foreach($allPendingRoles as $index => $pendingRoleInfo)
|
||||
<div class="bg-white dark:bg-gray-700 rounded-md p-3 border border-blue-200 dark:border-blue-700 @if(!$loop->last) mb-2 @endif">
|
||||
<div class="flex items-center mb-2">
|
||||
<span class="flex items-center justify-center w-6 h-6 bg-blue-600 text-white text-xs font-bold rounded-full mr-2">
|
||||
{{ $index + 1 }}
|
||||
</span>
|
||||
<span class="text-sm font-bold text-blue-700 dark:text-blue-300">{{ $pendingRoleInfo['role_name'] }}</span>
|
||||
</div>
|
||||
<div class="ml-8 space-y-1 text-sm">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">
|
||||
<i class="fa fa-play-circle text-green-500 mr-1"></i>Starts:
|
||||
</span>
|
||||
<span class="font-semibold text-gray-900 dark:text-gray-100">{{ $pendingRoleInfo['start_date']->format('M j, Y g:i A') }}</span>
|
||||
</div>
|
||||
@if($pendingRoleInfo['end_date'])
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">
|
||||
<i class="fa fa-stop-circle text-red-400 mr-1"></i>Ends:
|
||||
</span>
|
||||
<span class="font-semibold text-gray-900 dark:text-gray-100">{{ $pendingRoleInfo['end_date']->format('M j, Y g:i A') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs text-gray-600 dark:text-gray-400">Time until activation:</span>
|
||||
<span class="text-sm font-semibold text-blue-600 dark:text-blue-400">{{ $pendingRoleInfo['start_date']->diffForHumans() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between mt-3">
|
||||
<p class="text-xs text-blue-700 dark:text-blue-300">
|
||||
<i class="fa fa-info-circle mr-1"></i>
|
||||
These roles will automatically activate in sequence as each previous role expires
|
||||
</p>
|
||||
@if(!empty($user->pending_roles_id))
|
||||
<label class="inline-flex items-center px-3 py-2 rounded-md bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-700 hover:bg-red-100 dark:hover:bg-red-900/50 cursor-pointer transition-all">
|
||||
<input type="checkbox" name="cancel_pending_role" value="1"
|
||||
class="rounded border-red-300 dark:border-red-600 bg-white dark:bg-gray-700 text-red-600 dark:text-red-500 shadow-sm focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500 dark:focus:border-red-400 cursor-pointer">
|
||||
<span class="ml-2 text-xs text-red-700 dark:text-red-300 font-semibold">Cancel all pending roles</span>
|
||||
</label>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$pendingRole = \Spatie\Permission\Models\Role::find($user->pending_roles_id);
|
||||
$pendingStartDate = \Carbon\Carbon::parse($user->pending_role_start_date);
|
||||
$daysUntilActivation = $pendingStartDate->diffInDays(now());
|
||||
@endphp
|
||||
|
||||
<div class="bg-white dark:bg-gray-700 rounded-md p-3 mb-3 border border-blue-200 dark:border-blue-700">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Will change to:</span>
|
||||
<span class="text-sm font-bold text-blue-700 dark:text-blue-300">{{ $pendingRole->name ?? 'Unknown' }}</span>
|
||||
@elseif(!empty($user->pending_roles_id) && !empty($user->pending_role_start_date))
|
||||
{{-- Fallback to old display if no history records but pending_roles_id is set --}}
|
||||
<div class="border-2 border-blue-300 dark:border-blue-600 rounded-lg p-4 bg-gradient-to-br from-blue-50 via-blue-50 to-white dark:from-blue-900/30 dark:via-blue-900/20 dark:to-gray-800 shadow-md">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
||||
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
||||
Pending Stacked Role
|
||||
</label>
|
||||
<span class="px-3 py-1 inline-flex items-center text-xs leading-5 font-bold rounded-full bg-blue-200 dark:bg-blue-800 text-blue-800 dark:text-blue-100 animate-pulse">
|
||||
<i class="fa fa-clock mr-1"></i> SCHEDULED
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Activation date:</span>
|
||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ $pendingStartDate->format('M j, Y g:i A') }}</span>
|
||||
|
||||
@php
|
||||
$pendingRole = \Spatie\Permission\Models\Role::find($user->pending_roles_id);
|
||||
$pendingStartDate = \Carbon\Carbon::parse($user->pending_role_start_date);
|
||||
$daysUntilActivation = $pendingStartDate->diffInDays(now());
|
||||
@endphp
|
||||
|
||||
<div class="bg-white dark:bg-gray-700 rounded-md p-3 mb-3 border border-blue-200 dark:border-blue-700">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Will change to:</span>
|
||||
<span class="text-sm font-bold text-blue-700 dark:text-blue-300">{{ $pendingRole->name ?? 'Unknown' }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Activation date:</span>
|
||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ $pendingStartDate->format('M j, Y g:i A') }}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs text-gray-600 dark:text-gray-400">Time until activation:</span>
|
||||
<span class="text-sm font-semibold text-blue-600 dark:text-blue-400">{{ $pendingStartDate->diffForHumans() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-xs text-gray-600 dark:text-gray-400">Time until activation:</span>
|
||||
<span class="text-sm font-semibold text-blue-600 dark:text-blue-400">{{ $pendingStartDate->diffForHumans() }}</span>
|
||||
<p class="text-xs text-blue-700 dark:text-blue-300">
|
||||
<i class="fa fa-info-circle mr-1"></i>
|
||||
This role will automatically activate when the current role expires
|
||||
</p>
|
||||
<label class="inline-flex items-center px-3 py-2 rounded-md bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-700 hover:bg-red-100 dark:hover:bg-red-900/50 cursor-pointer transition-all">
|
||||
<input type="checkbox" name="cancel_pending_role" value="1"
|
||||
class="rounded border-red-300 dark:border-red-600 bg-white dark:bg-gray-700 text-red-600 dark:text-red-500 shadow-sm focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500 dark:focus:border-red-400 cursor-pointer">
|
||||
<span class="ml-2 text-xs text-red-700 dark:text-red-300 font-semibold">Cancel pending role</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-xs text-blue-700 dark:text-blue-300">
|
||||
<i class="fa fa-info-circle mr-1"></i>
|
||||
This role will automatically activate when the current role expires
|
||||
</p>
|
||||
<label class="inline-flex items-center px-3 py-2 rounded-md bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-700 hover:bg-red-100 dark:hover:bg-red-900/50 cursor-pointer transition-all">
|
||||
<input type="checkbox" name="cancel_pending_role" value="1"
|
||||
class="rounded border-red-300 dark:border-red-600 bg-white dark:bg-gray-700 text-red-600 dark:text-red-500 shadow-sm focus:ring-2 focus:ring-red-500 dark:focus:ring-red-400 focus:border-red-500 dark:focus:border-red-400 cursor-pointer">
|
||||
<span class="ml-2 text-xs text-red-700 dark:text-red-300 font-semibold">Cancel pending role</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<!-- Role Stacking Option -->
|
||||
|
||||
@@ -139,7 +139,50 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($user->hasPendingRole())
|
||||
@php
|
||||
$allPendingRoles = $user->getAllPendingStackedRoles();
|
||||
@endphp
|
||||
@if($allPendingRoles->count() > 0)
|
||||
<div class="flex border-b border-gray-200 dark:border-gray-700 pb-3">
|
||||
<div class="w-1/3 text-gray-600">Pending Role{{ $allPendingRoles->count() > 1 ? 's' : '' }}</div>
|
||||
<div class="w-2/3">
|
||||
<div class="space-y-3">
|
||||
@foreach($allPendingRoles as $index => $pendingRoleInfo)
|
||||
<div class="@if(!$loop->last) pb-3 border-b border-gray-100 dark:border-gray-700 @endif">
|
||||
<div class="flex items-center">
|
||||
<span class="flex items-center justify-center w-6 h-6 bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-400 text-xs font-bold rounded-full mr-2">
|
||||
{{ $index + 1 }}
|
||||
</span>
|
||||
<i class="fa fa-layer-group text-blue-400 mr-2"></i>
|
||||
<span class="font-medium text-blue-600 dark:text-blue-400">{{ $pendingRoleInfo['role_name'] }}</span>
|
||||
<span class="ml-2 px-2 py-1 bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 text-xs rounded">
|
||||
<i class="fa fa-clock mr-1"></i>Scheduled
|
||||
</span>
|
||||
</div>
|
||||
<div class="ml-8 mt-1 text-sm text-gray-600 dark:text-gray-400">
|
||||
<div>
|
||||
<i class="fa fa-play-circle text-green-500 mr-1"></i>
|
||||
<span class="font-medium">Starts:</span> {{ $pendingRoleInfo['start_date']->format('M d, Y g:i A') }}
|
||||
<span class="text-gray-400">({{ $pendingRoleInfo['start_date']->diffForHumans() }})</span>
|
||||
</div>
|
||||
@if($pendingRoleInfo['end_date'])
|
||||
<div class="mt-1">
|
||||
<i class="fa fa-stop-circle text-red-400 mr-1"></i>
|
||||
<span class="font-medium">Ends:</span> {{ $pendingRoleInfo['end_date']->format('M d, Y g:i A') }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div class="text-xs text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 p-2 rounded mt-2">
|
||||
<i class="fa fa-info-circle mr-1"></i>
|
||||
These roles will automatically activate in sequence as each previous role expires
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@elseif($user->hasPendingRole())
|
||||
{{-- Fallback to old display if no history records but pending_roles_id is set --}}
|
||||
<div class="flex border-b border-gray-200 dark:border-gray-700 pb-3">
|
||||
<div class="w-1/3 text-gray-600">Pending Role</div>
|
||||
<div class="w-2/3">
|
||||
|
||||
Reference in New Issue
Block a user