- 일정 유형(입금/지급) 전환 시 계좌 라벨 동적 변경 - create, edit, show 3개 뷰 모두 적용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
239 lines
12 KiB
PHP
239 lines
12 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', '일정 수정')
|
|
|
|
@section('content')
|
|
<div class="container mx-auto px-4 py-6 max-w-2xl">
|
|
{{-- 페이지 헤더 --}}
|
|
<div class="mb-6">
|
|
<a href="{{ route('finance.fund-schedules.index') }}" class="text-sm text-gray-500 hover:text-gray-700 inline-flex items-center gap-1 mb-2">
|
|
<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="M15 19l-7-7 7-7"/>
|
|
</svg>
|
|
자금계획일정으로
|
|
</a>
|
|
<h1 class="text-2xl font-bold text-gray-800">일정 수정</h1>
|
|
<p class="text-sm text-gray-500 mt-1">{{ $schedule->title }}</p>
|
|
</div>
|
|
|
|
{{-- 수정 폼 --}}
|
|
<div class="bg-white rounded-lg shadow-sm p-6">
|
|
<form id="scheduleForm"
|
|
hx-put="{{ route('api.admin.fund-schedules.update', $schedule->id) }}"
|
|
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}", "Accept": "application/json"}'
|
|
hx-target="#form-message"
|
|
hx-swap="innerHTML"
|
|
class="space-y-6">
|
|
|
|
{{-- 메시지 영역 --}}
|
|
<div id="form-message"></div>
|
|
|
|
{{-- 일정 유형 --}}
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
일정 유형 <span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="grid grid-cols-2 gap-4">
|
|
@foreach($types as $value => $label)
|
|
<label class="relative flex cursor-pointer rounded-lg border p-4 focus:outline-none
|
|
{{ $value === 'income' ? 'border-green-300 bg-green-50 has-[:checked]:border-green-500 has-[:checked]:ring-2 has-[:checked]:ring-green-500' : 'border-red-300 bg-red-50 has-[:checked]:border-red-500 has-[:checked]:ring-2 has-[:checked]:ring-red-500' }}">
|
|
<input type="radio" name="schedule_type" value="{{ $value }}"
|
|
class="sr-only" {{ $schedule->schedule_type === $value ? 'checked' : '' }}>
|
|
<span class="flex flex-1">
|
|
<span class="flex flex-col">
|
|
<span class="block text-sm font-medium {{ $value === 'income' ? 'text-green-900' : 'text-red-900' }}">
|
|
{{ $label }}
|
|
</span>
|
|
</span>
|
|
</span>
|
|
<svg class="h-5 w-5 {{ $value === 'income' ? 'text-green-600' : 'text-red-600' }} hidden [input:checked~&]:block" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" />
|
|
</svg>
|
|
</label>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 일정명 --}}
|
|
<div>
|
|
<label for="title" class="block text-sm font-medium text-gray-700 mb-1">
|
|
일정명 <span class="text-red-500">*</span>
|
|
</label>
|
|
<input type="text" name="title" id="title" required
|
|
value="{{ $schedule->title }}"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
</div>
|
|
|
|
{{-- 예정일 & 금액 --}}
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label for="scheduled_date" class="block text-sm font-medium text-gray-700 mb-1">
|
|
예정일 <span class="text-red-500">*</span>
|
|
</label>
|
|
<input type="date" name="scheduled_date" id="scheduled_date" required
|
|
value="{{ $schedule->scheduled_date->format('Y-m-d') }}"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
</div>
|
|
<div>
|
|
<label for="amount_display" class="block text-sm font-medium text-gray-700 mb-1">
|
|
금액 <span class="text-red-500">*</span>
|
|
</label>
|
|
<input type="text" id="amount_display" required
|
|
value="{{ number_format((int)$schedule->amount) }}" inputmode="numeric"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 text-right"
|
|
oninput="formatAmountInput(this)"
|
|
onblur="formatAmountInput(this)">
|
|
<input type="hidden" name="amount" id="amount" value="{{ (int)$schedule->amount }}">
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 거래상대방 --}}
|
|
<div>
|
|
<label for="counterparty" class="block text-sm font-medium text-gray-700 mb-1">
|
|
거래상대방
|
|
</label>
|
|
<input type="text" name="counterparty" id="counterparty"
|
|
value="{{ $schedule->counterparty }}"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
</div>
|
|
|
|
{{-- 입출금 계좌 --}}
|
|
<div>
|
|
<label for="related_bank_account_id" id="account-label" class="block text-sm font-medium text-gray-700 mb-1">
|
|
출금 계좌
|
|
</label>
|
|
<select name="related_bank_account_id" id="related_bank_account_id"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
<option value="">선택안함</option>
|
|
@foreach($accounts as $account)
|
|
<option value="{{ $account->id }}" {{ $schedule->related_bank_account_id == $account->id ? 'selected' : '' }}>
|
|
{{ $account->bank_name }} - {{ $account->account_number }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- 분류 --}}
|
|
<div>
|
|
<label for="category" class="block text-sm font-medium text-gray-700 mb-1">
|
|
분류
|
|
</label>
|
|
@php
|
|
$categories = ['매출', '매입', '급여', '임대료', '운영비', '세금', '대출', '투자', '기타'];
|
|
@endphp
|
|
<select name="category" id="category"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
<option value="">선택안함</option>
|
|
@foreach($categories as $cat)
|
|
<option value="{{ $cat }}" {{ $schedule->category === $cat ? 'selected' : '' }}>{{ $cat }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- 상태 --}}
|
|
<div>
|
|
<label for="status" class="block text-sm font-medium text-gray-700 mb-1">
|
|
상태
|
|
</label>
|
|
<select name="status" id="status"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">
|
|
@foreach($statuses as $value => $label)
|
|
<option value="{{ $value }}" {{ $schedule->status === $value ? 'selected' : '' }}>{{ $label }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- 설명 --}}
|
|
<div>
|
|
<label for="description" class="block text-sm font-medium text-gray-700 mb-1">
|
|
설명
|
|
</label>
|
|
<textarea name="description" id="description" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">{{ $schedule->description }}</textarea>
|
|
</div>
|
|
|
|
{{-- 메모 --}}
|
|
<div>
|
|
<label for="memo" class="block text-sm font-medium text-gray-700 mb-1">
|
|
메모
|
|
</label>
|
|
<textarea name="memo" id="memo" rows="2"
|
|
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500">{{ $schedule->memo }}</textarea>
|
|
</div>
|
|
|
|
{{-- 버튼 --}}
|
|
<div class="flex justify-between pt-4 border-t">
|
|
<button type="button"
|
|
hx-delete="{{ route('api.admin.fund-schedules.destroy', $schedule->id) }}"
|
|
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'
|
|
hx-confirm="이 일정을 삭제하시겠습니까?"
|
|
class="px-4 py-2 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-lg transition-colors">
|
|
삭제
|
|
</button>
|
|
<div class="flex gap-3">
|
|
<a href="{{ route('finance.fund-schedules.index') }}"
|
|
class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors">
|
|
취소
|
|
</a>
|
|
<button type="submit"
|
|
class="px-6 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg transition-colors">
|
|
저장
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
// 금액 입력 포맷팅 (콤마 추가, 소수점 제거)
|
|
function formatAmountInput(input) {
|
|
// 숫자만 추출
|
|
let value = input.value.replace(/[^\d]/g, '');
|
|
|
|
// 빈 값이면 0
|
|
if (!value) value = '0';
|
|
|
|
// 숫자로 변환 후 콤마 포맷
|
|
const numValue = parseInt(value, 10);
|
|
input.value = numValue.toLocaleString('ko-KR');
|
|
|
|
// hidden input에 실제 값 저장
|
|
document.getElementById('amount').value = numValue;
|
|
}
|
|
|
|
// 계좌 라벨 업데이트 (유형에 따라)
|
|
function updateAccountLabel() {
|
|
const label = document.getElementById('account-label');
|
|
const checked = document.querySelector('input[name="schedule_type"]:checked');
|
|
if (label && checked) {
|
|
label.textContent = checked.value === 'income' ? '입금 계좌' : '출금 계좌';
|
|
}
|
|
}
|
|
|
|
// 일정 유형 라디오 변경 시 라벨 업데이트
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.querySelectorAll('input[name="schedule_type"]').forEach(function(radio) {
|
|
radio.addEventListener('change', updateAccountLabel);
|
|
});
|
|
updateAccountLabel();
|
|
});
|
|
|
|
document.body.addEventListener('htmx:afterRequest', function(event) {
|
|
if (event.detail.successful) {
|
|
try {
|
|
const response = JSON.parse(event.detail.xhr.responseText);
|
|
if (response.success) {
|
|
window.location.href = '{{ route('finance.fund-schedules.index') }}';
|
|
}
|
|
} catch (e) {
|
|
// HTMX HTML 응답인 경우 (삭제 후 리다이렉트)
|
|
window.location.href = '{{ route('finance.fund-schedules.index') }}';
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|