284 lines
19 KiB
PHP
284 lines
19 KiB
PHP
<x-app-layout>
|
|
<x-slot name="header">
|
|
<h2 class="text-xl font-semibold leading-tight text-gray-800">
|
|
{{ __('Admin Dashboard') }}
|
|
</h2>
|
|
</x-slot>
|
|
|
|
<div class="py-12">
|
|
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
|
|
<div class="space-y-6">
|
|
{{-- My Pending Approvals Alert --}}
|
|
@if ($myPendingApprovals > 0)
|
|
<div class="rounded-md bg-yellow-50 p-4" role="alert" aria-live="polite">
|
|
<div class="flex">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-3">
|
|
<p class="text-sm font-medium text-yellow-800">
|
|
{{ __('You have :count finance document(s) waiting for your approval.', ['count' => $myPendingApprovals]) }}
|
|
<a href="{{ route('admin.finance.index') }}" class="font-semibold underline hover:text-yellow-700">
|
|
{{ __('View pending approvals') }}
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Stats Grid --}}
|
|
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-4">
|
|
{{-- Total Members --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Total Members') }}</dt>
|
|
<dd class="text-2xl font-semibold text-gray-900">{{ number_format($totalMembers) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm">
|
|
<a href="{{ route('admin.members.index') }}" class="font-medium text-indigo-600 hover:text-indigo-900">
|
|
{{ __('View all') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Active Members --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-green-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Active Members') }}</dt>
|
|
<dd class="text-2xl font-semibold text-green-600">{{ number_format($activeMembers) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm">
|
|
<a href="{{ route('admin.members.index', ['status' => 'active']) }}" class="font-medium text-indigo-600 hover:text-indigo-900">
|
|
{{ __('View active') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Expired Members --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-red-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Expired Members') }}</dt>
|
|
<dd class="text-2xl font-semibold text-red-600">{{ number_format($expiredMembers) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm">
|
|
<a href="{{ route('admin.members.index', ['status' => 'expired']) }}" class="font-medium text-indigo-600 hover:text-indigo-900">
|
|
{{ __('View expired') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Expiring Soon --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-yellow-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Expiring in 30 Days') }}</dt>
|
|
<dd class="text-2xl font-semibold text-yellow-600">{{ number_format($expiringSoon) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm">
|
|
<span class="text-gray-500">{{ __('Renewal reminders needed') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Revenue Stats --}}
|
|
<div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
|
{{-- Total Revenue --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v12m-3-2.818l.879.659c1.171.879 3.07.879 4.242 0 1.172-.879 1.172-2.303 0-3.182C13.536 12.219 12.768 12 12 12c-.725 0-1.45-.22-2.003-.659-1.106-.879-1.106-2.303 0-3.182s2.9-.879 4.006 0l.415.33M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Total Revenue') }}</dt>
|
|
<dd class="text-2xl font-semibold text-gray-900">${{ number_format($totalRevenue, 2) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm text-gray-500">
|
|
{{ number_format($totalPayments) }} {{ __('total payments') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- This Month Revenue --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-green-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('This Month') }}</dt>
|
|
<dd class="text-2xl font-semibold text-green-600">${{ number_format($revenueThisMonth, 2) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm text-gray-500">
|
|
{{ number_format($paymentsThisMonth) }} {{ __('payments this month') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Pending Approvals --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="p-5">
|
|
<div class="flex items-center">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-6 w-6 text-blue-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z" />
|
|
</svg>
|
|
</div>
|
|
<div class="ml-5 w-0 flex-1">
|
|
<dl>
|
|
<dt class="truncate text-sm font-medium text-gray-500">{{ __('Finance Documents') }}</dt>
|
|
<dd class="text-2xl font-semibold text-blue-600">{{ number_format($pendingApprovals) }}</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-gray-50 px-5 py-3">
|
|
<div class="text-sm">
|
|
<a href="{{ route('admin.finance.index') }}" class="font-medium text-indigo-600 hover:text-indigo-900">
|
|
{{ __('View pending') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Recent Payments & Finance Stats --}}
|
|
<div class="grid grid-cols-1 gap-5 lg:grid-cols-2">
|
|
{{-- Recent Payments --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<h3 class="text-lg font-medium leading-6 text-gray-900">{{ __('Recent Payments') }}</h3>
|
|
<div class="mt-4 flow-root">
|
|
@if ($recentPayments->count() > 0)
|
|
<ul role="list" class="-my-5 divide-y divide-gray-200">
|
|
@foreach ($recentPayments as $payment)
|
|
<li class="py-4">
|
|
<div class="flex items-center space-x-4">
|
|
<div class="min-w-0 flex-1">
|
|
<p class="truncate text-sm font-medium text-gray-900">
|
|
{{ $payment->member?->full_name ?? __('N/A') }}
|
|
</p>
|
|
<p class="truncate text-sm text-gray-500">
|
|
{{ $payment->paid_at?->format('Y-m-d') ?? __('N/A') }}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<span class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
|
|
${{ number_format($payment->amount, 2) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
@else
|
|
<p class="text-sm text-gray-500">{{ __('No recent payments.') }}</p>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Finance Document Stats --}}
|
|
<div class="overflow-hidden rounded-lg bg-white shadow">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<h3 class="text-lg font-medium leading-6 text-gray-900">{{ __('Finance Document Status') }}</h3>
|
|
<div class="mt-6 space-y-4">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<span class="flex h-3 w-3 rounded-full bg-yellow-400"></span>
|
|
<span class="ml-3 text-sm font-medium text-gray-900">{{ __('Pending Approval') }}</span>
|
|
</div>
|
|
<span class="text-sm font-semibold text-gray-900">{{ number_format($pendingApprovals) }}</span>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<span class="flex h-3 w-3 rounded-full bg-green-400"></span>
|
|
<span class="ml-3 text-sm font-medium text-gray-900">{{ __('Fully Approved') }}</span>
|
|
</div>
|
|
<span class="text-sm font-semibold text-gray-900">{{ number_format($fullyApprovedDocs) }}</span>
|
|
</div>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<span class="flex h-3 w-3 rounded-full bg-red-400"></span>
|
|
<span class="ml-3 text-sm font-medium text-gray-900">{{ __('Rejected') }}</span>
|
|
</div>
|
|
<span class="text-sm font-semibold text-gray-900">{{ number_format($rejectedDocs) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-app-layout>
|