Commit e11ab21d authored by Mahmoud Aglan's avatar Mahmoud Aglan

Fix dashboard security: redirect roles + hide financial data

- Trainers/head trainers redirect to /trainer dashboard on login
- Receptionists redirect to /receptionist dashboard
- Guardians (parents) redirect to /guardian dashboard
- Financial data (revenue, invoices, payments) only queried if user
  has 'invoices.list' permission — returns null/empty otherwise
- Blade sections wrapped in @can('invoices.list') so even direct
  URL access shows no sensitive financial info to unauthorized roles
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 38768a29
......@@ -25,6 +25,25 @@ class Dashboard extends Component
{
use UsesBranchScope;
public function mount(): void
{
$user = auth()->user();
$roleSlug = $user->primaryRole?->slug;
// Redirect non-management roles to their dedicated dashboards
$redirectMap = [
'trainer' => 'trainer.dashboard',
'head_trainer' => 'trainer.dashboard',
'receptionist' => 'receptionist.dashboard',
'parent' => 'guardian.dashboard',
];
if (isset($redirectMap[$roleSlug])) {
$this->redirect(route($redirectMap[$roleSlug]));
return;
}
}
public function render()
{
$today = now()->toDateString();
......@@ -42,7 +61,9 @@ public function render()
->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))->count(),
];
$financial = [
$canViewFinancials = auth()->user()->hasPermission('invoices.list');
$financial = $canViewFinancials ? [
'revenue_this_month' => Payment::where('status', 'confirmed')
->whereDate('created_at', '>=', $thisMonth)
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->sum('amount'),
......@@ -53,7 +74,7 @@ public function render()
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->sum('total_amount'),
'pos_today_count' => POSTransaction::whereDate('processed_at', $today)
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))->count(),
];
] : null;
$todaySessions = TrainingSession::where('session_date', $today)
->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
......@@ -89,12 +110,12 @@ public function render()
->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
->count();
$overdueInvoices = Invoice::where('status', InvoiceStatus::Overdue)
$overdueInvoices = $canViewFinancials ? Invoice::where('status', InvoiceStatus::Overdue)
->when($branchId, fn ($q) => $q->whereHasMorph('billable', [Participant::class], fn ($p) => $p->where('branch_id', $branchId)))
->with('billable')
->orderBy('due_date')
->limit(5)
->get();
->get() : collect();
$todaySchedule = TrainingSession::where('session_date', $today)
->when($branchId, fn ($q) => $q->whereHas('group', fn ($g) => $g->where('branch_id', $branchId)))
......@@ -116,12 +137,12 @@ public function render()
->limit(5)
->get();
$recentPayments = Payment::where('status', 'confirmed')
$recentPayments = $canViewFinancials ? Payment::where('status', 'confirmed')
->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
->with('creator')
->orderByDesc('created_at')
->limit(5)
->get();
->get() : collect();
return view('livewire.dashboard', [
'stats' => $stats,
......
......@@ -67,7 +67,8 @@
</div>
</div>
<!-- Row 2: Financial Summary -->
<!-- Row 2: Financial Summary (owner/admin only) -->
@can('invoices.list')
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 mb-4 sm:mb-6">
<!-- Revenue This Month -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6">
......@@ -101,6 +102,7 @@
<p class="text-lg sm:text-2xl font-bold {{ $financial['outstanding_invoices'] > 0 ? 'text-red-600' : 'text-gray-800' }}" dir="ltr">{{ number_format($financial['outstanding_invoices'] / 100, 2) }} {{ __('ج.م') }}</p>
</div>
</div>
@endcan
<!-- Row 3: Attendance Summary -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6 mb-4 sm:mb-6">
......@@ -185,6 +187,7 @@
</div>
<!-- Overdue Invoices -->
@can('invoices.list')
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6">
<h3 class="text-base sm:text-lg font-semibold text-gray-800 mb-3 sm:mb-4">{{ __('فواتير متأخرة') }}</h3>
@if($overdueInvoices->isEmpty())
......@@ -203,11 +206,13 @@
</div>
@endif
</div>
@endcan
</div>
<!-- Row 6: Recent Payments + Upcoming Birthdays -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3 sm:gap-4">
<!-- Recent Payments -->
@can('invoices.list')
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6">
<h3 class="text-base sm:text-lg font-semibold text-gray-800 mb-3 sm:mb-4">{{ __('آخر المدفوعات') }}</h3>
@if($recentPayments->isEmpty())
......@@ -226,6 +231,7 @@
</div>
@endif
</div>
@endcan
<!-- Upcoming Birthdays -->
<div class="bg-white rounded-xl shadow-sm border border-gray-200 p-4 sm:p-6">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment