781 lines
44 KiB
PHP
781 lines
44 KiB
PHP
@extends('layouts.app')
|
||
|
||
@section('title', '바로빌 연동 관리')
|
||
|
||
@section('content')
|
||
<!-- 현재 테넌트 정보 카드 -->
|
||
<x-barobill-tenant-header
|
||
:currentTenant="$currentTenant"
|
||
:barobillMember="$barobillMember"
|
||
:isTestMode="$isTestMode"
|
||
gradientFrom="#4f46e5"
|
||
gradientTo="#7c3aed"
|
||
:icon="'<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>'"
|
||
/>
|
||
|
||
<!-- 서버 모드 제어 위젯 -->
|
||
@if($barobillMember)
|
||
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
|
||
<div class="flex items-center gap-3 mb-4">
|
||
<div class="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center">
|
||
<svg class="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-semibold text-gray-800">바로빌 서버 모드</h3>
|
||
<p class="text-xs text-gray-500">현재 바로빌 API 연결 서버 설정</p>
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<span class="text-sm text-gray-600">현재:</span>
|
||
@if($isTestMode)
|
||
<span id="server-mode-badge" class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-sm font-semibold bg-amber-100 text-amber-800">
|
||
<span class="w-2 h-2 rounded-full bg-amber-500"></span>
|
||
테스트 서버
|
||
</span>
|
||
@else
|
||
<span id="server-mode-badge" class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-sm font-semibold bg-green-100 text-green-800">
|
||
<span class="w-2 h-2 rounded-full bg-green-500"></span>
|
||
운영 서버
|
||
</span>
|
||
@endif
|
||
</div>
|
||
@if(session('selected_tenant_id', 1) == 1)
|
||
<button type="button" id="btn-toggle-server-mode" onclick="toggleServerMode()" class="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition text-sm font-medium">
|
||
<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="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
|
||
</svg>
|
||
서버 변경
|
||
</button>
|
||
@endif
|
||
</div>
|
||
@if($isTestMode)
|
||
<div class="mt-4 p-3 bg-amber-50 border border-amber-200 rounded-lg">
|
||
<div class="flex items-start gap-2">
|
||
<svg class="w-4 h-4 text-amber-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
</svg>
|
||
<p class="text-sm text-amber-700">테스트 서버 사용 중입니다. 테스트 데이터는 실제 국세청에 전송되지 않습니다.</p>
|
||
</div>
|
||
</div>
|
||
@else
|
||
<div class="mt-4 p-3 bg-green-50 border border-green-200 rounded-lg">
|
||
<div class="flex items-start gap-2">
|
||
<svg class="w-4 h-4 text-green-600 mt-0.5 flex-shrink-0" 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>
|
||
<p class="text-sm text-green-700">운영 서버에 연결되어 있습니다. 모든 데이터가 실제 국세청에 전송됩니다.</p>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
@endif
|
||
|
||
<!-- 바로빌 연동 -->
|
||
<div class="mb-6">
|
||
<h2 class="text-lg font-bold text-gray-800 mb-3">바로빌 연동</h2>
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||
<!-- 카드 1: 바로빌 로그인 정보 -->
|
||
<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-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="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>
|
||
@if($hasBarobillLogin)
|
||
<div class="space-y-3">
|
||
<div class="flex items-center gap-2">
|
||
<span class="text-sm text-gray-500 shrink-0" style="width: 60px;">아이디</span>
|
||
<span class="text-sm font-medium text-gray-800">{{ $barobillMember->barobill_id }}</span>
|
||
</div>
|
||
<div class="flex items-center gap-2">
|
||
<span class="text-sm text-gray-500 shrink-0" style="width: 60px;">비밀번호</span>
|
||
<span class="text-sm font-medium text-gray-800">●●●●●●●●</span>
|
||
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">설정됨</span>
|
||
</div>
|
||
<button type="button" onclick="openBarobillLoginModal('edit')"
|
||
class="mt-2 w-full px-4 py-2 bg-indigo-50 text-indigo-700 rounded-lg hover:bg-indigo-100 transition text-sm font-medium 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="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||
</svg>
|
||
로그인 정보 수정
|
||
</button>
|
||
</div>
|
||
@else
|
||
<div class="text-center py-4">
|
||
<div class="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-3">
|
||
<svg class="w-6 h-6 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||
</svg>
|
||
</div>
|
||
<h4 class="font-medium text-gray-800 mb-1">바로빌 회원이신가요?</h4>
|
||
<p class="text-sm text-gray-500 mb-4">바로빌 ID와 비밀번호를 등록하면<br>계좌/카드 연동 서비스를 이용할 수 있습니다.</p>
|
||
<button type="button" onclick="openBarobillLoginModal('register')"
|
||
class="w-full px-4 py-2.5 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition text-sm font-medium 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="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||
</svg>
|
||
바로빌 로그인 정보 등록
|
||
</button>
|
||
</div>
|
||
@endif
|
||
</div>
|
||
|
||
<!-- 카드 2: 바로빌 회원가입 안내 -->
|
||
<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="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-semibold text-gray-800">바로빌 회원가입</h3>
|
||
<p class="text-xs text-gray-500">바로빌 서비스 신규 가입</p>
|
||
</div>
|
||
</div>
|
||
<div class="text-center py-4">
|
||
<div class="w-12 h-12 bg-blue-50 rounded-full flex items-center justify-center mx-auto mb-3">
|
||
<svg class="w-6 h-6 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
</svg>
|
||
</div>
|
||
<h4 class="font-medium text-gray-800 mb-1">바로빌 회원이 아니신가요?</h4>
|
||
<p class="text-sm text-gray-500 mb-4">바로빌 회원가입 후<br>전자세금계산서, 계좌조회 등의 서비스를 이용하세요.</p>
|
||
<a href="https://www.barobill.co.kr" target="_blank" rel="noopener noreferrer"
|
||
class="inline-flex w-full px-4 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition text-sm font-medium 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||
</svg>
|
||
바로빌 회원가입
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 계좌 연동 -->
|
||
<div class="mb-6">
|
||
<h2 class="text-lg font-bold text-gray-800 mb-3">계좌 연동</h2>
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||
<!-- 은행 빠른조회 서비스 등록 -->
|
||
<div class="bg-white rounded-lg shadow-sm p-6 {{ !$hasBarobillLogin ? 'opacity-50' : '' }}">
|
||
<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="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>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-semibold text-gray-800">은행 빠른조회 서비스</h3>
|
||
<p class="text-xs text-gray-500">은행 계좌 빠른조회 서비스 등록</p>
|
||
</div>
|
||
</div>
|
||
@if($hasBarobillLogin)
|
||
<button type="button" onclick="openBarobillUrl('bank-account-url')"
|
||
class="w-full px-4 py-2 bg-green-50 text-green-700 rounded-lg hover:bg-green-100 transition text-sm font-medium 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||
</svg>
|
||
서비스 등록하기
|
||
</button>
|
||
@else
|
||
<p class="text-sm text-gray-400 text-center py-2">바로빌 로그인 정보를 먼저 등록하세요.</p>
|
||
@endif
|
||
</div>
|
||
|
||
<!-- 계좌 연동 등록 -->
|
||
<div class="bg-white rounded-lg shadow-sm p-6 {{ !$hasBarobillLogin ? 'opacity-50' : '' }}">
|
||
<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="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>
|
||
@if($hasBarobillLogin)
|
||
<button type="button" onclick="openBarobillUrl('bank-account-manage-url')"
|
||
class="w-full px-4 py-2 bg-green-50 text-green-700 rounded-lg hover:bg-green-100 transition text-sm font-medium 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||
</svg>
|
||
계좌 관리하기
|
||
</button>
|
||
@else
|
||
<p class="text-sm text-gray-400 text-center py-2">바로빌 로그인 정보를 먼저 등록하세요.</p>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 카드 연동 -->
|
||
<div class="mb-6">
|
||
<h2 class="text-lg font-bold text-gray-800 mb-3">카드 연동</h2>
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||
<!-- 카드 연동 등록 -->
|
||
<div class="bg-white rounded-lg shadow-sm p-6 {{ !$hasBarobillLogin ? 'opacity-50' : '' }}">
|
||
<div class="flex items-center gap-3 mb-4">
|
||
<div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center">
|
||
<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>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-semibold text-gray-800">카드 연동 관리</h3>
|
||
<p class="text-xs text-gray-500">카드 연동 등록 및 관리</p>
|
||
</div>
|
||
</div>
|
||
@if($hasBarobillLogin)
|
||
<button type="button" onclick="openBarobillUrl('card-url')"
|
||
class="w-full px-4 py-2 bg-purple-50 text-purple-700 rounded-lg hover:bg-purple-100 transition text-sm font-medium 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||
</svg>
|
||
카드 관리하기
|
||
</button>
|
||
@else
|
||
<p class="text-sm text-gray-400 text-center py-2">바로빌 로그인 정보를 먼저 등록하세요.</p>
|
||
@endif
|
||
</div>
|
||
|
||
<!-- 공인인증서 등록 -->
|
||
<div class="bg-white rounded-lg shadow-sm p-6 {{ !$hasBarobillLogin ? 'opacity-50' : '' }}">
|
||
<div class="flex items-center gap-3 mb-4">
|
||
<div class="w-10 h-10 bg-amber-100 rounded-lg flex items-center justify-center">
|
||
<svg class="w-5 h-5 text-amber-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-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<h3 class="font-semibold text-gray-800">공인인증서 등록</h3>
|
||
<p class="text-xs text-gray-500">공인인증서 등록 및 관리</p>
|
||
</div>
|
||
</div>
|
||
@if($hasBarobillLogin)
|
||
<button type="button" onclick="openBarobillUrl('certificate-url')"
|
||
class="w-full px-4 py-2 bg-amber-50 text-amber-700 rounded-lg hover:bg-amber-100 transition text-sm font-medium 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||
</svg>
|
||
인증서 관리하기
|
||
</button>
|
||
@else
|
||
<p class="text-sm text-gray-400 text-center py-2">바로빌 로그인 정보를 먼저 등록하세요.</p>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<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>
|
||
|
||
<!-- 바로빌 로그인 정보 등록/수정 모달 -->
|
||
<div id="barobill-login-modal" class="fixed inset-0 z-50 hidden">
|
||
<div class="fixed inset-0 bg-black/50" onclick="closeBarobillLoginModal()"></div>
|
||
<div class="fixed inset-0 flex items-center justify-center p-4">
|
||
<div class="bg-white rounded-xl shadow-2xl w-full max-w-md relative">
|
||
<div class="flex items-center justify-between p-6 border-b border-gray-100">
|
||
<h3 id="barobill-login-modal-title" class="text-lg font-bold text-gray-800">바로빌 로그인 정보</h3>
|
||
<button type="button" onclick="closeBarobillLoginModal()" class="text-gray-400 hover:text-gray-600">
|
||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<div class="p-6 space-y-4">
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">바로빌 아이디</label>
|
||
<input type="text" id="modal-barobill-id" class="w-full px-3 py-2.5 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="바로빌 아이디를 입력하세요">
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-gray-700 mb-1">바로빌 비밀번호</label>
|
||
<input type="password" id="modal-barobill-pwd" class="w-full px-3 py-2.5 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" placeholder="비밀번호를 입력하세요">
|
||
</div>
|
||
</div>
|
||
<div class="flex gap-3 p-6 border-t border-gray-100">
|
||
<button type="button" onclick="closeBarobillLoginModal()" class="flex-1 px-4 py-2.5 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition text-sm font-medium">취소</button>
|
||
<button type="button" id="btn-save-barobill-login" onclick="saveBarobillLogin()" class="flex-1 px-4 py-2.5 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition text-sm font-medium flex items-center justify-center gap-2">
|
||
<svg class="w-4 h-4 hidden animate-spin" id="barobill-login-spinner" viewBox="0 0 24 24">
|
||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"></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>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endsection
|
||
|
||
@push('scripts')
|
||
<script>
|
||
// 바로빌 로그인 모달
|
||
function openBarobillLoginModal(mode) {
|
||
const modal = document.getElementById('barobill-login-modal');
|
||
const title = document.getElementById('barobill-login-modal-title');
|
||
const idInput = document.getElementById('modal-barobill-id');
|
||
const pwdInput = document.getElementById('modal-barobill-pwd');
|
||
|
||
if (mode === 'edit') {
|
||
title.textContent = '바로빌 로그인 정보 수정';
|
||
idInput.value = @json($barobillMember?->barobill_id ?? '');
|
||
pwdInput.value = '';
|
||
pwdInput.placeholder = '변경할 비밀번호를 입력하세요 (미입력 시 유지)';
|
||
} else {
|
||
title.textContent = '바로빌 로그인 정보 등록';
|
||
idInput.value = '';
|
||
pwdInput.value = '';
|
||
pwdInput.placeholder = '비밀번호를 입력하세요';
|
||
}
|
||
|
||
modal.classList.remove('hidden');
|
||
}
|
||
|
||
function closeBarobillLoginModal() {
|
||
document.getElementById('barobill-login-modal').classList.add('hidden');
|
||
}
|
||
|
||
async function saveBarobillLogin() {
|
||
const memberId = @json($barobillMember?->id);
|
||
if (!memberId) {
|
||
showToast('바로빌 회원사 정보가 없습니다.', 'error');
|
||
return;
|
||
}
|
||
|
||
const barobillId = document.getElementById('modal-barobill-id').value.trim();
|
||
const barobillPwd = document.getElementById('modal-barobill-pwd').value;
|
||
|
||
if (!barobillId) {
|
||
showToast('바로빌 아이디를 입력하세요.', 'error');
|
||
return;
|
||
}
|
||
|
||
const spinner = document.getElementById('barobill-login-spinner');
|
||
const btn = document.getElementById('btn-save-barobill-login');
|
||
spinner.classList.remove('hidden');
|
||
btn.disabled = true;
|
||
|
||
try {
|
||
const body = { barobill_id: barobillId };
|
||
if (barobillPwd) {
|
||
body.barobill_pwd = barobillPwd;
|
||
}
|
||
|
||
const response = await fetch(`/api/admin/barobill/members/${memberId}`, {
|
||
method: 'PUT',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||
},
|
||
body: JSON.stringify(body),
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
showToast('바로빌 로그인 정보가 저장되었습니다.', 'success');
|
||
closeBarobillLoginModal();
|
||
setTimeout(() => location.reload(), 1000);
|
||
} else {
|
||
showToast(result.message || '저장에 실패했습니다.', 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('바로빌 로그인 정보 저장 실패:', error);
|
||
showToast('저장 중 오류가 발생했습니다.', 'error');
|
||
} finally {
|
||
spinner.classList.add('hidden');
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
|
||
// 바로빌 URL API 호출 (계좌/카드/인증서)
|
||
async function openBarobillUrl(urlType) {
|
||
const memberId = @json($barobillMember?->id);
|
||
if (!memberId) {
|
||
showToast('바로빌 회원사 정보가 없습니다.', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/api/admin/barobill/members/${memberId}/${urlType}`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||
},
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success && result.data?.url) {
|
||
window.open(result.data.url, '_blank', 'width=900,height=700');
|
||
} else {
|
||
showToast(result.message || 'URL을 가져오는데 실패했습니다.', 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('바로빌 URL 호출 실패:', error);
|
||
showToast('서비스 연결 중 오류가 발생했습니다.', 'error');
|
||
}
|
||
}
|
||
|
||
// 서버 모드 전환
|
||
async function toggleServerMode() {
|
||
const isCurrentlyTest = @json($isTestMode);
|
||
const targetMode = isCurrentlyTest ? 'production' : 'test';
|
||
const targetLabel = isCurrentlyTest ? '운영' : '테스트';
|
||
|
||
let confirmMessage = `서버를 "${targetLabel}" 모드로 변경하시겠습니까?`;
|
||
if (targetMode === 'production') {
|
||
confirmMessage += '\n\n⚠️ 운영 서버로 전환하면 실제 요금이 부과되며, 발행된 세금계산서가 국세청에 전송됩니다.';
|
||
}
|
||
|
||
if (!confirm(confirmMessage)) return;
|
||
|
||
const memberId = @json($barobillMember?->id);
|
||
if (!memberId) {
|
||
showToast('바로빌 회원사 정보가 없습니다.', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`/api/admin/barobill/members/${memberId}/server-mode`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||
},
|
||
body: JSON.stringify({ server_mode: targetMode }),
|
||
});
|
||
|
||
const result = await response.json();
|
||
|
||
if (result.success) {
|
||
showToast(`서버 모드가 "${targetLabel}"(으)로 변경되었습니다.`, 'success');
|
||
setTimeout(() => location.reload(), 1000);
|
||
} else {
|
||
showToast(result.message || '서버 모드 변경에 실패했습니다.', 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('서버 모드 변경 실패:', error);
|
||
showToast('서버 모드 변경 중 오류가 발생했습니다.', 'error');
|
||
}
|
||
}
|
||
|
||
// 서비스 설정 개별 저장 (체크박스 변경 시 즉시 저장)
|
||
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
|