138 lines
6.4 KiB
PHP
138 lines
6.4 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', '보유계좌관리')
|
|
|
|
@section('content')
|
|
<div class="px-4 py-6">
|
|
{{-- 페이지 헤더 --}}
|
|
<div class="flex flex-col lg:flex-row lg:justify-between lg:items-center gap-4 mb-6">
|
|
<div>
|
|
<h1 class="text-2xl font-bold text-gray-800">보유계좌관리</h1>
|
|
<p class="text-sm text-gray-500 mt-1">{{ now()->format('Y년 n월 j일') }} 현재</p>
|
|
</div>
|
|
<div class="flex flex-wrap items-center gap-2 sm:gap-3">
|
|
<a href="{{ route('finance.accounts.create') }}"
|
|
class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
|
|
</svg>
|
|
계좌 등록
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 요약 카드 (선택사항) --}}
|
|
@if(isset($summary) && $summary['total_accounts'] > 0)
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">총 계좌 수</div>
|
|
<div class="text-2xl font-bold text-gray-800">{{ $summary['total_accounts'] }}개</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">총 잔액</div>
|
|
<div class="text-2xl font-bold text-emerald-600" data-total-balance>{{ $summary['formatted_total_balance'] }}</div>
|
|
</div>
|
|
<div class="bg-white rounded-lg shadow-sm p-4">
|
|
<div class="text-sm text-gray-500">은행 수</div>
|
|
<div class="text-2xl font-bold text-gray-800">{{ count($summary['by_bank']) }}개</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- 테이블 컨테이너 --}}
|
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden">
|
|
{{-- 테이블 헤더 --}}
|
|
<div class="px-6 py-4 border-b border-gray-200 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
<h2 class="text-lg font-semibold text-gray-800">보유 계좌 목록</h2>
|
|
|
|
{{-- 필터/검색 --}}
|
|
<form id="filterForm" class="flex flex-col sm:flex-row gap-2 sm:gap-3">
|
|
<input type="text" name="search" placeholder="검색..."
|
|
value="{{ request('search') }}"
|
|
class="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
<select name="is_active" class="px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
<option value="">전체 상태</option>
|
|
<option value="1" {{ request('is_active') === '1' ? 'selected' : '' }}>활성</option>
|
|
<option value="0" {{ request('is_active') === '0' ? 'selected' : '' }}>비활성</option>
|
|
</select>
|
|
<button type="submit"
|
|
hx-get="{{ route('api.admin.bank-accounts.index') }}"
|
|
hx-target="#accounts-table"
|
|
hx-include="#filterForm"
|
|
class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white text-sm rounded-lg transition-colors">
|
|
검색
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
{{-- HTMX 테이블 영역 --}}
|
|
<div id="accounts-table"
|
|
hx-get="{{ route('api.admin.bank-accounts.index') }}"
|
|
hx-trigger="load"
|
|
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'
|
|
class="min-h-[200px]">
|
|
{{-- 로딩 스피너 --}}
|
|
<div class="flex justify-center items-center p-12">
|
|
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-emerald-600"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
// 필터 폼 제출 시 HTMX 트리거
|
|
document.getElementById('filterForm')?.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
htmx.trigger('#accounts-table', 'htmx:trigger');
|
|
});
|
|
|
|
// 바로빌 잔액 조회 및 업데이트
|
|
async function refreshAccountBalances() {
|
|
try {
|
|
const res = await fetch('{{ route("barobill.eaccount.latest-balances") }}');
|
|
const data = await res.json();
|
|
|
|
if (data.success && data.balances && data.balances.length > 0) {
|
|
const balanceMap = {};
|
|
data.balances.forEach(b => {
|
|
const num = (b.bankAccountNum || '').replace(/-/g, '');
|
|
balanceMap[num] = b.balance || 0;
|
|
});
|
|
|
|
let totalBalance = 0;
|
|
document.querySelectorAll('#accounts-table [data-account-number]').forEach(td => {
|
|
const accNum = td.dataset.accountNumber;
|
|
const balanceEl = td.querySelector('.account-balance');
|
|
if (balanceEl && balanceMap.hasOwnProperty(accNum)) {
|
|
const newBalance = balanceMap[accNum];
|
|
balanceEl.textContent = new Intl.NumberFormat('ko-KR').format(newBalance) + '원';
|
|
balanceEl.classList.remove('text-gray-900');
|
|
balanceEl.classList.add(newBalance >= 100000000 ? 'text-emerald-600' : 'text-gray-900');
|
|
totalBalance += newBalance;
|
|
} else if (balanceEl) {
|
|
totalBalance += parseFloat(balanceEl.dataset.original || 0);
|
|
}
|
|
});
|
|
|
|
// 요약 카드의 총 잔액 업데이트
|
|
const totalBalanceEl = document.querySelector('[data-total-balance]');
|
|
if (totalBalanceEl) {
|
|
totalBalanceEl.textContent = new Intl.NumberFormat('ko-KR').format(totalBalance) + '원';
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error('잔액 조회 오류:', e);
|
|
}
|
|
}
|
|
|
|
// HTMX 테이블 로드 완료 후 잔액 조회
|
|
document.body.addEventListener('htmx:afterSwap', function(e) {
|
|
if (e.detail.target.id === 'accounts-table') {
|
|
refreshAccountBalances();
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|