Files
sam-manage/resources/views/barobill/settings/index.blade.php

369 lines
22 KiB
PHP

@extends('layouts.app')
@section('title', '바로빌 설정')
@section('content')
<!-- 현재 테넌트 정보 카드 -->
@if($currentTenant)
<div class="rounded-xl shadow-lg p-5 mb-6" style="background: linear-gradient(to right, #4f46e5, #7c3aed); color: white;">
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
<div class="flex items-center gap-4">
<div class="p-3 rounded-xl" style="background: rgba(255,255,255,0.2);">
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</div>
<div>
<div class="flex items-center gap-2 mb-1">
<span class="px-2 py-0.5 rounded-full text-xs font-bold" style="background: rgba(255,255,255,0.2);">T-ID: {{ $currentTenant->id }}</span>
@if($currentTenant->id == 1)
<span class="px-2 py-0.5 rounded-full text-xs font-bold" style="background: #facc15; color: #713f12;">파트너사</span>
@endif
</div>
<h2 class="text-xl font-bold">{{ $currentTenant->company_name }}</h2>
</div>
</div>
@if($barobillMember)
<div class="grid grid-cols-2 lg:grid-cols-4 gap-3 text-sm">
<div class="rounded-lg p-2" style="background: rgba(255,255,255,0.1);">
<p class="text-xs" style="color: rgba(255,255,255,0.6);">사업자번호</p>
<p class="font-medium">{{ $barobillMember->biz_no }}</p>
</div>
<div class="rounded-lg p-2" style="background: rgba(255,255,255,0.1);">
<p class="text-xs" style="color: rgba(255,255,255,0.6);">대표자</p>
<p class="font-medium">{{ $barobillMember->ceo_name ?? '-' }}</p>
</div>
<div class="rounded-lg p-2" style="background: rgba(255,255,255,0.1);">
<p class="text-xs" style="color: rgba(255,255,255,0.6);">담당자</p>
<p class="font-medium">{{ $barobillMember->manager_name ?? '-' }}</p>
</div>
<div class="rounded-lg p-2" style="background: rgba(255,255,255,0.1);">
<p class="text-xs" style="color: rgba(255,255,255,0.6);">바로빌 ID</p>
<p class="font-medium">{{ $barobillMember->barobill_id }}</p>
</div>
</div>
@else
<div class="flex items-center gap-2" style="color: #fef08a;">
<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 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<span class="text-sm">바로빌 회원사 미연동</span>
</div>
@endif
</div>
</div>
@endif
<div class="flex flex-col h-full">
<!-- 페이지 헤더 -->
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4 mb-6 flex-shrink-0">
<div>
<h1 class="text-2xl font-bold text-gray-800">바로빌 설정</h1>
<p class="text-sm text-gray-500 mt-1">이메일 주소 기타 자료의 수정 동기화</p>
</div>
</div>
<!-- 설정 카드 -->
<form id="settings-form" class="space-y-6">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 서비스 이용 설정 -->
<div class="bg-white rounded-lg shadow-sm p-6 lg:col-span-2">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-indigo-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div>
<h3 class="font-semibold text-gray-800">서비스 이용 설정</h3>
<p class="text-xs text-gray-500">이용할 바로빌 서비스를 선택하세요</p>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<!-- 전자세금계산서 -->
<label class="flex items-start gap-3 p-4 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition border-2 border-transparent has-[:checked]:border-blue-500 has-[:checked]:bg-blue-50">
<input type="checkbox" name="use_tax_invoice" id="use_tax_invoice" class="service-checkbox mt-1 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500" onchange="saveServiceSetting('use_tax_invoice', this.checked)">
<div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<span class="font-medium text-gray-800">전자세금계산서</span>
</div>
<p class="text-xs text-gray-500 mt-1">세금계산서 발행/수신 서비스</p>
</div>
</label>
<!-- 계좌조회 -->
<label class="flex items-start gap-3 p-4 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition border-2 border-transparent has-[:checked]:border-green-500 has-[:checked]:bg-green-50">
<input type="checkbox" name="use_bank_account" id="use_bank_account" class="service-checkbox mt-1 w-4 h-4 text-green-600 bg-gray-100 border-gray-300 rounded focus:ring-green-500" onchange="saveServiceSetting('use_bank_account', this.checked)">
<div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<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>
<span class="font-medium text-gray-800">계좌조회</span>
</div>
<p class="text-xs text-gray-500 mt-1">은행 계좌 거래내역 조회</p>
</div>
</label>
<!-- 카드사용내역 -->
<label class="flex items-start gap-3 p-4 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition border-2 border-transparent has-[:checked]:border-purple-500 has-[:checked]:bg-purple-50">
<input type="checkbox" name="use_card_usage" id="use_card_usage" class="service-checkbox mt-1 w-4 h-4 text-purple-600 bg-gray-100 border-gray-300 rounded focus:ring-purple-500" onchange="saveServiceSetting('use_card_usage', this.checked)">
<div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<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>
<span class="font-medium text-gray-800">카드사용내역</span>
</div>
<p class="text-xs text-gray-500 mt-1">카드 결제내역 조회</p>
</div>
</label>
<!-- 홈텍스매입/매출 -->
<label class="flex items-start gap-3 p-4 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition border-2 border-transparent has-[:checked]:border-orange-500 has-[:checked]:bg-orange-50">
<input type="checkbox" name="use_hometax" id="use_hometax" class="service-checkbox mt-1 w-4 h-4 text-orange-600 bg-gray-100 border-gray-300 rounded focus:ring-orange-500" onchange="saveServiceSetting('use_hometax', this.checked)">
<div>
<div class="flex items-center gap-2">
<svg class="w-5 h-5 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>
<span class="font-medium text-gray-800">홈텍스매입/매출</span>
</div>
<p class="text-xs text-gray-500 mt-1">홈텍스 매입/매출 자료 조회</p>
</div>
</label>
</div>
</div>
<!-- 담당자 정보 -->
<div class="bg-white rounded-lg shadow-sm p-6">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
</div>
<div>
<h3 class="font-semibold text-gray-800">담당자 정보</h3>
<p class="text-xs text-gray-500">세금계산서 담당자 정보</p>
</div>
</div>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-600 mb-1">담당자명</label>
<input type="text" name="contact_name" id="contact_name" class="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="홍길동">
</div>
<div>
<label class="block text-sm font-medium text-gray-600 mb-1">연락처</label>
<input type="tel" name="contact_tel" id="contact_tel" class="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="02-1234-5678">
</div>
<div>
<label class="block text-sm font-medium text-gray-600 mb-1">담당자 이메일</label>
<input type="email" name="contact_id" id="contact_id" class="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="manager@company.com">
</div>
</div>
</div>
<!-- 동기화 설정 -->
<div class="bg-white rounded-lg shadow-sm p-6">
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 bg-green-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
</div>
<div>
<h3 class="font-semibold text-gray-800">데이터 동기화</h3>
<p class="text-xs text-gray-500">바로빌 데이터 동기화 설정</p>
</div>
</div>
<div class="space-y-4">
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div>
<p class="text-sm font-medium text-gray-700">자동 동기화</p>
<p class="text-xs text-gray-500">매일 자정 자동 동기화</p>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input type="checkbox" class="sr-only peer">
<div class="w-11 h-6 bg-gray-200 peer-focus:ring-2 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div>
</label>
</div>
<button type="button" class="w-full px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition flex items-center justify-center gap-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="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
지금 동기화
</button>
</div>
</div>
</div>
<!-- 저장 버튼 -->
<div class="flex justify-end gap-3">
<button type="button" id="btn-reset" class="px-6 py-2.5 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition font-medium">
초기화
</button>
<button type="submit" id="btn-save" class="px-6 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition font-medium flex items-center gap-2">
<svg class="w-4 h-4 hidden animate-spin" id="save-spinner" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
설정 저장
</button>
</div>
</form>
<!-- 토스트 메시지 -->
<div id="toast" class="fixed bottom-4 right-4 px-4 py-3 rounded-lg shadow-lg transform translate-y-full opacity-0 transition-all duration-300 z-50"></div>
</div>
@endsection
@push('scripts')
<script>
// 서비스 설정 개별 저장 (체크박스 변경 시 즉시 저장)
async function saveServiceSetting(field, value) {
const toast = document.getElementById('toast');
try {
const response = await fetch('/api/admin/barobill/settings/service', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
body: JSON.stringify({ field: field, value: value }),
});
const result = await response.json();
if (result.success) {
showToast(result.message || '설정이 저장되었습니다.', 'success');
} else {
showToast(result.message || '설정 저장에 실패했습니다.', 'error');
// 실패 시 체크박스 원상복구
document.getElementById(field).checked = !value;
}
} catch (error) {
console.error('설정 저장 실패:', error);
showToast('설정 저장 중 오류가 발생했습니다.', 'error');
// 실패 시 체크박스 원상복구
document.getElementById(field).checked = !value;
}
}
// 토스트 표시 (전역 함수)
function showToast(message, type = 'success') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = 'fixed bottom-4 right-4 px-4 py-3 rounded-lg shadow-lg transform transition-all duration-300 z-50';
if (type === 'success') {
toast.classList.add('bg-green-600', 'text-white');
} else {
toast.classList.add('bg-red-600', 'text-white');
}
toast.classList.remove('translate-y-full', 'opacity-0');
setTimeout(() => {
toast.classList.add('translate-y-full', 'opacity-0');
}, 3000);
}
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('settings-form');
const saveSpinner = document.getElementById('save-spinner');
const btnSave = document.getElementById('btn-save');
const btnReset = document.getElementById('btn-reset');
// 설정 로드
async function loadSettings() {
try {
const response = await fetch('/api/admin/barobill/settings');
const result = await response.json();
if (result.success && result.data) {
const data = result.data;
// 서비스 이용 설정
document.getElementById('use_tax_invoice').checked = data.use_tax_invoice || false;
document.getElementById('use_bank_account').checked = data.use_bank_account || false;
document.getElementById('use_card_usage').checked = data.use_card_usage || false;
document.getElementById('use_hometax').checked = data.use_hometax || false;
// 담당자 정보
document.getElementById('contact_name').value = data.contact_name || '';
document.getElementById('contact_tel').value = data.contact_tel || '';
document.getElementById('contact_id').value = data.contact_id || '';
}
} catch (error) {
console.error('설정 로드 실패:', error);
}
}
// 설정 저장
async function saveSettings(e) {
e.preventDefault();
saveSpinner.classList.remove('hidden');
btnSave.disabled = true;
const formData = {
use_tax_invoice: document.getElementById('use_tax_invoice').checked,
use_bank_account: document.getElementById('use_bank_account').checked,
use_card_usage: document.getElementById('use_card_usage').checked,
use_hometax: document.getElementById('use_hometax').checked,
contact_name: document.getElementById('contact_name').value,
contact_tel: document.getElementById('contact_tel').value,
contact_id: document.getElementById('contact_id').value,
};
try {
const response = await fetch('/api/admin/barobill/settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
body: JSON.stringify(formData),
});
const result = await response.json();
if (result.success) {
showToast(result.message || '설정이 저장되었습니다.', 'success');
} else {
showToast(result.message || '설정 저장에 실패했습니다.', 'error');
}
} catch (error) {
console.error('설정 저장 실패:', error);
showToast('설정 저장 중 오류가 발생했습니다.', 'error');
} finally {
saveSpinner.classList.add('hidden');
btnSave.disabled = false;
}
}
// 초기화 버튼
btnReset.addEventListener('click', function() {
document.getElementById('use_tax_invoice').checked = false;
document.getElementById('use_bank_account').checked = false;
document.getElementById('use_card_usage').checked = false;
document.getElementById('use_hometax').checked = false;
document.getElementById('contact_name').value = '';
document.getElementById('contact_tel').value = '';
document.getElementById('contact_id').value = '';
showToast('설정이 초기화되었습니다.', 'success');
});
// 이벤트 리스너
form.addEventListener('submit', saveSettings);
// 초기 로드
loadSettings();
});
</script>
@endpush