Files
usher-manage-stack/resources/views/member/submit-payment.blade.php
Gbanyan 642b879dd4 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>
2025-12-01 09:56:01 +08:00

159 lines
11 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
{{ __('Submit Membership Payment') }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-2xl sm:px-6 lg:px-8">
<div class="bg-white shadow sm:rounded-lg dark:bg-gray-800 px-4 py-5 sm:p-6">
{{-- Fee Summary --}}
<div class="mb-6 bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg p-4">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100 mb-4">會費明細</h3>
<div class="space-y-2">
<div class="flex justify-between text-sm">
<span class="text-gray-600 dark:text-gray-400">會費類型</span>
<span class="font-medium text-gray-900 dark:text-gray-100">
{{ $feeDetails['fee_type'] === 'entrance_fee' ? '入會會費' : '常年會費' }}
</span>
</div>
<div class="flex justify-between text-sm">
<span class="text-gray-600 dark:text-gray-400">原始金額</span>
<span class="text-gray-900 dark:text-gray-100">NT$ {{ number_format($feeDetails['base_amount']) }}</span>
</div>
@if($feeDetails['disability_discount'])
<div class="flex justify-between text-sm text-green-600 dark:text-green-400">
<span>身心障礙優惠</span>
<span>-NT$ {{ number_format($feeDetails['discount_amount']) }}</span>
</div>
@endif
<div class="border-t border-gray-200 dark:border-gray-600 pt-2 mt-2">
<div class="flex justify-between text-base font-semibold">
<span class="text-gray-900 dark:text-gray-100">應繳金額</span>
<span class="text-indigo-600 dark:text-indigo-400">NT$ {{ number_format($feeDetails['final_amount']) }}</span>
</div>
</div>
</div>
@if(!$feeDetails['disability_discount'] && !$member->hasApprovedDisability())
<div class="mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/30 rounded-md">
<p class="text-sm text-yellow-800 dark:text-yellow-200">
<strong>提示:</strong>若您持有身心障礙手冊,請先至
<a href="{{ route('profile.edit') }}" class="underline">個人資料頁面</a>
上傳手冊以享有 50% 優惠。
</p>
</div>
@endif
</div>
{{-- Payment Instructions --}}
<div class="mb-6 bg-blue-50 dark:bg-blue-900/30 border-l-4 border-blue-400 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">
<h3 class="text-sm font-medium text-blue-800 dark:text-blue-200">繳費說明</h3>
<div class="mt-2 text-sm text-blue-700 dark:text-blue-300">
<p>請上傳您的繳費收據(銀行轉帳、超商繳費等)</p>
<p class="mt-1">我們的工作人員將審核您的繳費紀錄,審核通過後會以 Email 通知您。</p>
</div>
</div>
</div>
</div>
<form method="POST" action="{{ route('member.payments.store') }}" enctype="multipart/form-data" class="space-y-6">
@csrf
{{-- Amount --}}
<div>
<label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
繳費金額 (TWD) <span class="text-red-500">*</span>
</label>
<input type="number" name="amount" id="amount" value="{{ old('amount', $feeDetails['final_amount']) }}" required min="{{ $feeDetails['final_amount'] }}" step="1"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 @error('amount') border-red-300 @enderror">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">最低繳費金額NT$ {{ number_format($feeDetails['final_amount']) }}</p>
@error('amount')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Payment Date --}}
<div>
<label for="paid_at" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ __('Payment Date') }} <span class="text-red-500">*</span>
</label>
<input type="date" name="paid_at" id="paid_at" value="{{ old('paid_at', today()->format('Y-m-d')) }}" required max="{{ today()->format('Y-m-d') }}"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 @error('paid_at') border-red-300 @enderror">
@error('paid_at')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Payment Method --}}
<div>
<label for="payment_method" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ __('Payment Method') }} <span class="text-red-500">*</span>
</label>
<select name="payment_method" id="payment_method" required
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 @error('payment_method') border-red-300 @enderror">
<option value="">{{ __('Select payment method') }}</option>
<option value="bank_transfer" {{ old('payment_method') == 'bank_transfer' ? 'selected' : '' }}>{{ __('Bank Transfer / ATM') }}</option>
<option value="convenience_store" {{ old('payment_method') == 'convenience_store' ? 'selected' : '' }}>{{ __('Convenience Store (7-11, FamilyMart, etc.)') }}</option>
<option value="cash" {{ old('payment_method') == 'cash' ? 'selected' : '' }}>{{ __('Cash (In-person)') }}</option>
<option value="credit_card" {{ old('payment_method') == 'credit_card' ? 'selected' : '' }}>{{ __('Credit Card') }}</option>
</select>
@error('payment_method')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Reference Number --}}
<div>
<label for="reference" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ __('Transaction / Reference Number') }}
</label>
<input type="text" name="reference" id="reference" value="{{ old('reference') }}" maxlength="255"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 @error('reference') border-red-300 @enderror"
placeholder="{{ __('e.g., Bank transaction number, receipt number') }}">
@error('reference')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Receipt Upload --}}
<div>
<label for="receipt" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ __('Payment Receipt') }} <span class="text-red-500">*</span>
</label>
<input type="file" name="receipt" id="receipt" required accept="image/*,.pdf"
class="mt-1 block w-full text-sm text-gray-900 border border-gray-300 rounded-md cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 @error('receipt') border-red-300 @enderror">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">{{ __('Upload your payment receipt (JPG, PNG, or PDF, max 10MB)') }}</p>
@error('receipt')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Notes --}}
<div>
<label for="notes" class="block text-sm font-medium text-gray-700 dark:text-gray-300">
{{ __('Notes (Optional)') }}
</label>
<textarea name="notes" id="notes" rows="3" maxlength="500"
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-gray-100 @error('notes') border-red-300 @enderror"
placeholder="{{ __('Any additional information...') }}">{{ old('notes') }}</textarea>
@error('notes')<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>@enderror
</div>
{{-- Submit Buttons --}}
<div class="flex items-center justify-end gap-x-4 border-t border-gray-200 pt-6 dark:border-gray-700">
<a href="{{ route('member.dashboard') }}"
class="rounded-md bg-white px-3 py-2 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-100 dark:ring-gray-600">
{{ __('Cancel') }}
</a>
<button type="submit"
class="inline-flex justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400">
{{ __('Submit Payment') }}
</button>
</div>
</form>
</div>
</div>
</div>
</x-app-layout>