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.
|
* Get comprehensive role expiry information.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -322,51 +322,117 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Pending Role Information -->
|
<!-- Pending Role Information -->
|
||||||
@if(!is_array($user) && !empty($user->pending_roles_id) && !empty($user->pending_role_start_date))
|
@if(!is_array($user))
|
||||||
<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">
|
@php
|
||||||
<div class="flex items-center justify-between mb-3">
|
$allPendingRoles = $user->getAllPendingStackedRoles();
|
||||||
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
@endphp
|
||||||
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
@if($allPendingRoles->count() > 0)
|
||||||
Pending Stacked Role
|
<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">
|
||||||
</label>
|
<div class="flex items-center justify-between mb-3">
|
||||||
<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">
|
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
||||||
<i class="fa fa-clock mr-1"></i> SCHEDULED
|
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
||||||
</span>
|
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>
|
</div>
|
||||||
|
@elseif(!empty($user->pending_roles_id) && !empty($user->pending_role_start_date))
|
||||||
@php
|
{{-- Fallback to old display if no history records but pending_roles_id is set --}}
|
||||||
$pendingRole = \Spatie\Permission\Models\Role::find($user->pending_roles_id);
|
<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">
|
||||||
$pendingStartDate = \Carbon\Carbon::parse($user->pending_role_start_date);
|
<div class="flex items-center justify-between mb-3">
|
||||||
$daysUntilActivation = $pendingStartDate->diffInDays(now());
|
<label class="text-sm font-semibold text-blue-700 dark:text-blue-300 flex items-center">
|
||||||
@endphp
|
<i class="fa fa-layer-group mr-2 text-lg"></i>
|
||||||
|
Pending Stacked Role
|
||||||
<div class="bg-white dark:bg-gray-700 rounded-md p-3 mb-3 border border-blue-200 dark:border-blue-700">
|
</label>
|
||||||
<div class="flex items-center justify-between mb-2">
|
<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">
|
||||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-300">Will change to:</span>
|
<i class="fa fa-clock mr-1"></i> SCHEDULED
|
||||||
<span class="text-sm font-bold text-blue-700 dark:text-blue-300">{{ $pendingRole->name ?? 'Unknown' }}</span>
|
</span>
|
||||||
</div>
|
</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>
|
@php
|
||||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ $pendingStartDate->format('M j, Y g:i A') }}</span>
|
$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>
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<span class="text-xs text-gray-600 dark:text-gray-400">Time until activation:</span>
|
<p class="text-xs text-blue-700 dark:text-blue-300">
|
||||||
<span class="text-sm font-semibold text-blue-600 dark:text-blue-400">{{ $pendingStartDate->diffForHumans() }}</span>
|
<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>
|
</div>
|
||||||
|
@endif
|
||||||
<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 -->
|
<!-- Role Stacking Option -->
|
||||||
|
|||||||
@@ -139,7 +139,50 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@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="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-1/3 text-gray-600">Pending Role</div>
|
||||||
<div class="w-2/3">
|
<div class="w-2/3">
|
||||||
|
|||||||
Reference in New Issue
Block a user