Files
usher-manage-stack/resources/views/member/dashboard.blade.php
Gbanyan c7a1f9130e Refactor 'My Membership' page scripts
- Replaced inline JS function generation in loops with Alpine.js event handlers.
- Improved safety of rejection reason output using json_encode.
2025-11-28 00:21:57 +08:00

244 lines
16 KiB
PHP

<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
{{ __('My Membership') }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8 space-y-6">
{{-- Pending Payment Alert --}}
@if($pendingPayment)
<div class="rounded-md bg-blue-50 dark:bg-blue-900/30 p-4">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3 flex-1">
<h3 class="text-sm font-medium text-blue-800 dark:text-blue-200">
{{ __('Payment Under Review') }}
</h3>
<div class="mt-2 text-sm text-blue-700 dark:text-blue-300">
<p>{{ __('Your payment of TWD :amount submitted on :date is currently being verified.', [
'amount' => number_format($pendingPayment->amount, 0),
'date' => $pendingPayment->paid_at->format('Y-m-d')
]) }}</p>
<p class="mt-1">{{ __('Current status') }}: <strong>{!! $pendingPayment->status_label !!}</strong></p>
</div>
</div>
</div>
</div>
@endif
{{-- Submit Payment CTA for Pending Members --}}
@if($member->canSubmitPayment())
<div class="rounded-md bg-yellow-50 dark:bg-yellow-900/30 p-4">
<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 flex-1">
<h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
{{ __('Activate Your Membership') }}
</h3>
<div class="mt-2 text-sm text-yellow-700 dark:text-yellow-300">
<p>{{ __('To activate your membership and access member-only resources, please submit your payment proof.') }}</p>
</div>
<div class="mt-4">
<a href="{{ route('member.payments.create') }}" class="inline-flex items-center rounded-md bg-yellow-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-yellow-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-yellow-600">
{{ __('Submit Payment') }}
</a>
</div>
</div>
</div>
</div>
@endif
<section aria-labelledby="membership-info-heading" class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<div class="flex items-center justify-between">
<h3 id="membership-info-heading" class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">
{{ __('Membership Information') }}
</h3>
{!! $member->membership_status_badge !!}
</div>
@if ($member->user?->profilePhotoUrl())
<div class="mt-4">
<img src="{{ $member->user->profilePhotoUrl() }}" alt="{{ __('Profile photo for :name', ['name' => $member->full_name ?? $member->user?->name]) }}" class="h-24 w-24 rounded-full object-cover ring-2 ring-indigo-500">
</div>
@endif
<dl class="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3">
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Member Name') }}
</dt>
<dd class="mt-1 text-xl font-semibold text-gray-900 dark:text-gray-100">
{{ $member->full_name ?? $member->user?->name }}
</dd>
</div>
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Membership Type') }}
</dt>
<dd class="mt-1 text-xl font-semibold text-gray-900 dark:text-gray-100">
{{ $member->membership_type_label }}
</dd>
</div>
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Membership Status') }}
</dt>
<dd class="mt-1 text-xl font-semibold text-gray-900 dark:text-gray-100">
{{ $member->membership_status_label }}
</dd>
</div>
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Membership Start Date') }}
</dt>
<dd class="mt-1 text-xl font-semibold text-gray-900 dark:text-gray-100">
@if ($member->membership_started_at)
{{ $member->membership_started_at->toDateString() }}
@else
<span class="text-sm text-gray-500 dark:text-gray-400">{{ __('Not set') }}</span>
@endif
</dd>
</div>
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Membership Expiry Date') }}
</dt>
<dd class="mt-1 text-xl font-semibold text-gray-900 dark:text-gray-100">
@if ($member->membership_expires_at)
{{ $member->membership_expires_at->toDateString() }}
@else
<span class="text-sm text-gray-500 dark:text-gray-400">{{ __('Not set') }}</span>
@endif
</dd>
</div>
<div class="overflow-hidden rounded-lg bg-gray-50 dark:bg-gray-700 px-4 py-5 sm:p-6">
<dt class="truncate text-sm font-medium text-gray-500 dark:text-gray-400">
{{ __('Emergency Contact') }}
</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">
@if ($member->emergency_contact_name)
<div>{{ $member->emergency_contact_name }}</div>
<div>{{ $member->emergency_contact_phone }}</div>
@else
<span class="text-gray-500 dark:text-gray-400">{{ __('Not set') }}</span>
@endif
</dd>
</div>
</dl>
</div>
</section>
<section aria-labelledby="payment-history-heading" class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-4 py-5 sm:p-6">
<div class="flex items-center justify-between">
<h3 id="payment-history-heading" class="text-lg font-medium leading-6 text-gray-900 dark:text-gray-100">
{{ __('Payment History') }}
</h3>
@if($member->canSubmitPayment())
<a href="{{ route('member.payments.create') }}" class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
<svg class="-ml-0.5 mr-1.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z" />
</svg>
{{ __('Submit Payment') }}
</a>
@endif
</div>
<div class="mt-5 overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700" role="table">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Paid At') }}
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Amount') }}
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Method') }}
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Status') }}
</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-300">
{{ __('Details') }}
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 dark:divide-gray-700 bg-white dark:bg-gray-800">
@forelse ($payments as $payment)
<tr>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ optional($payment->paid_at)->format('Y-m-d') }}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
TWD {{ number_format($payment->amount, 0) }}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-gray-900 dark:text-gray-100">
{{ $payment->payment_method_label ?? __('N/A') }}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm">
{!! $payment->status_label !!}
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm">
@if($payment->isRejected())
<button type="button"
@click="alert('{{ __('Rejection Reason') }}:\n\n' + {{ json_encode($payment->rejection_reason) }})"
class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300">
{{ __('View Reason') }}
</button>
@elseif($payment->isPending() || $payment->isApprovedByCashier() || $payment->isApprovedByAccountant())
<div class="text-xs text-gray-500 dark:text-gray-400">
@if($payment->verifiedByCashier)
<div> {{ __('Cashier') }}: {{ $payment->cashier_verified_at->format('Y-m-d') }}</div>
@endif
@if($payment->verifiedByAccountant)
<div> {{ __('Accountant') }}: {{ $payment->accountant_verified_at->format('Y-m-d') }}</div>
@endif
@if($payment->verifiedByChair)
<div> {{ __('Chair') }}: {{ $payment->chair_verified_at->format('Y-m-d') }}</div>
@endif
</div>
@elseif($payment->isFullyApproved())
<span class="text-xs text-green-600 dark:text-green-400">
{{ __('Approved on :date', ['date' => $payment->chair_verified_at->format('Y-m-d')]) }}
</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-sm text-gray-500 dark:text-gray-400">
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
</svg>
<p class="mt-2">{{ __('No payment records found.') }}</p>
@if($member->canSubmitPayment())
<p class="mt-1 text-xs">{{ __('Submit your first payment to activate your membership.') }}</p>
@endif
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</section>
</div>
</div>
</x-app-layout>