Add membership fee system with disability discount and fix document permissions
Features: - Implement two fee types: entrance fee and annual fee (both NT$1,000) - Add 50% discount for disability certificate holders - Add disability certificate upload in member profile - Integrate disability verification into cashier approval workflow - Add membership fee settings in system admin Document permissions: - Fix hard-coded role logic in Document model - Use permission-based authorization instead of role checks Additional features: - Add announcements, general ledger, and trial balance modules - Add income management and accounting entries - Add comprehensive test suite with factories - Update UI translations to Traditional Chinese 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<x-app-layout>
|
||||
<x-slot name="header">
|
||||
<h2 class="text-xl font-semibold leading-tight text-gray-800">
|
||||
{{ __('Admin Dashboard') }}
|
||||
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
|
||||
管理後台
|
||||
</h2>
|
||||
</x-slot>
|
||||
|
||||
@@ -10,18 +10,18 @@
|
||||
<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="rounded-md bg-yellow-50 dark:bg-yellow-900/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">
|
||||
<svg class="h-5 w-5 text-yellow-400 dark:text-yellow-300" 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') }}
|
||||
<p class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
您有 {{ $myPendingApprovals }} 個報銷單等待您的核准。
|
||||
<a href="{{ route('admin.finance.index') }}" class="font-semibold underline hover:text-yellow-700 dark:hover:text-yellow-100">
|
||||
查看待核准項目
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -32,103 +32,103 @@
|
||||
{{-- 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="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-gray-400 dark:text-gray-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">會員總數</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-gray-100">{{ number_format($totalMembers) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-5 py-3">
|
||||
<div class="bg-gray-50 dark:bg-gray-700 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 href="{{ route('admin.members.index') }}" class="font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看全部
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Active Members --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-green-400 dark:text-green-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">使用中會員</dt>
|
||||
<dd class="text-2xl font-semibold text-green-600 dark:text-green-400">{{ number_format($activeMembers) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-5 py-3">
|
||||
<div class="bg-gray-50 dark:bg-gray-700 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 href="{{ route('admin.members.index', ['status' => 'active']) }}" class="font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看使用中
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Expired Members --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-red-400 dark:text-red-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">已過期會員</dt>
|
||||
<dd class="text-2xl font-semibold text-red-600 dark:text-red-400">{{ number_format($expiredMembers) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-5 py-3">
|
||||
<div class="bg-gray-50 dark:bg-gray-700 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 href="{{ route('admin.members.index', ['status' => 'expired']) }}" class="font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看已過期
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Expiring Soon --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-yellow-400 dark:text-yellow-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">30天內到期</dt>
|
||||
<dd class="text-2xl font-semibold text-yellow-600 dark:text-yellow-400">{{ number_format($expiringSoon) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-5 py-3">
|
||||
<div class="bg-gray-50 dark:bg-gray-700 px-5 py-3">
|
||||
<div class="text-sm">
|
||||
<span class="text-gray-500">{{ __('Renewal reminders needed') }}</span>
|
||||
<span class="text-gray-500 dark:text-gray-400">需要更新提醒</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,74 +137,74 @@
|
||||
{{-- 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="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-gray-400 dark:text-gray-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">總收入</dt>
|
||||
<dd class="text-2xl font-semibold text-gray-900 dark:text-gray-100">${{ 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 class="bg-gray-50 dark:bg-gray-700 px-5 py-3">
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ number_format($totalPayments) }} 總付款
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- This Month Revenue --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-green-400 dark:text-green-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">本月</dt>
|
||||
<dd class="text-2xl font-semibold text-green-600 dark:text-green-400">${{ 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 class="bg-gray-50 dark:bg-gray-700 px-5 py-3">
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ number_format($paymentsThisMonth) }} 本月付款
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Pending Approvals --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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">
|
||||
<svg class="h-6 w-6 text-blue-400 dark:text-blue-500" 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>
|
||||
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">報銷單</dt>
|
||||
<dd class="text-2xl font-semibold text-blue-600 dark:text-blue-400">{{ number_format($pendingApprovals) }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-5 py-3">
|
||||
<div class="bg-gray-50 dark:bg-gray-700 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 href="{{ route('admin.finance.index') }}" class="font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看待處理
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -214,25 +214,25 @@
|
||||
{{-- 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="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow">
|
||||
<div class="px-4 py-5 sm:p-6">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">{{ __('Recent Payments') }}</h3>
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">最近付款</h3>
|
||||
<div class="mt-4 flow-root">
|
||||
@if ($recentPayments->count() > 0)
|
||||
<ul role="list" class="-my-5 divide-y divide-gray-200">
|
||||
<ul role="list" class="-my-5 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
@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">
|
||||
<p class="truncate text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ $payment->member?->full_name ?? __('N/A') }}
|
||||
</p>
|
||||
<p class="truncate text-sm text-gray-500">
|
||||
<p class="truncate text-sm text-gray-500 dark:text-gray-400">
|
||||
{{ $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">
|
||||
<span class="inline-flex items-center rounded-full bg-green-100 dark:bg-green-900 px-2.5 py-0.5 text-xs font-medium text-green-800 dark:text-green-200">
|
||||
${{ number_format($payment->amount, 2) }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -241,43 +241,96 @@
|
||||
@endforeach
|
||||
</ul>
|
||||
@else
|
||||
<p class="text-sm text-gray-500">{{ __('No recent payments.') }}</p>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">沒有最近的付款記錄。</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Finance Document Stats --}}
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 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>
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">報銷單狀態</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>
|
||||
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-100">待核准</span>
|
||||
</div>
|
||||
<span class="text-sm font-semibold text-gray-900">{{ number_format($pendingApprovals) }}</span>
|
||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ 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>
|
||||
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-100">完全核准</span>
|
||||
</div>
|
||||
<span class="text-sm font-semibold text-gray-900">{{ number_format($fullyApprovedDocs) }}</span>
|
||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ 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>
|
||||
<span class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-100">已拒絕</span>
|
||||
</div>
|
||||
<span class="text-sm font-semibold text-gray-900">{{ number_format($rejectedDocs) }}</span>
|
||||
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ number_format($rejectedDocs) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Recent Announcements --}}
|
||||
@if($recentAnnouncements->isNotEmpty())
|
||||
<div class="mt-8">
|
||||
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
|
||||
<div class="border-b border-gray-200 dark:border-gray-700 px-4 py-5 sm:px-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">📢 最新公告</h3>
|
||||
@can('view_announcements')
|
||||
<a href="{{ route('admin.announcements.index') }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看全部 →
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
<ul role="list" class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
@foreach($recentAnnouncements as $announcement)
|
||||
<li class="px-4 py-4 sm:px-6 hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center mb-1">
|
||||
@if($announcement->is_pinned)
|
||||
<span class="mr-2 text-blue-500" title="置頂公告">📌</span>
|
||||
@endif
|
||||
<h4 class="text-sm font-semibold text-gray-900 dark:text-gray-100 truncate">
|
||||
{{ $announcement->title }}
|
||||
</h4>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 line-clamp-2">
|
||||
{{ $announcement->getExcerpt(120) }}
|
||||
</p>
|
||||
<div class="mt-2 flex items-center space-x-4 text-xs text-gray-500 dark:text-gray-400">
|
||||
<span>{{ $announcement->published_at?->diffForHumans() ?? $announcement->created_at->diffForHumans() }}</span>
|
||||
<span>•</span>
|
||||
<span>{{ $announcement->getAccessLevelLabel() }}</span>
|
||||
@if($announcement->view_count > 0)
|
||||
<span>•</span>
|
||||
<span>👁 {{ $announcement->view_count }} 次瀏覽</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@can('view_announcements')
|
||||
<a href="{{ route('admin.announcements.show', $announcement) }}" class="ml-4 flex-shrink-0 text-sm font-medium text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
|
||||
查看 →
|
||||
</a>
|
||||
@endcan
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
</x-app-layout>
|
||||
Reference in New Issue
Block a user