231 lines
13 KiB
PHP
231 lines
13 KiB
PHP
@extends('admin.layouts.app')
|
|
|
|
@section('title', '판매 코드 관리')
|
|
@section('page_title', 'API 연동 판매 코드 관리')
|
|
@section('page_desc', '외부 연동사(다날 등)와 해당 업체의 고유 상품 코드를 매핑합니다.')
|
|
|
|
@push('head')
|
|
<style>
|
|
.grid-layout { display: grid; grid-template-columns: 1fr 350px; gap: 20px; align-items: start; }
|
|
@media (max-width: 980px) { .grid-layout { grid-template-columns: 1fr; } }
|
|
|
|
.cat-list { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10); border-radius: 12px; }
|
|
.cat-item { padding: 10px 16px; border-bottom: 1px solid rgba(255,255,255,.05); display: flex; justify-content: space-between; align-items: center; transition: background 0.2s; }
|
|
.cat-group:last-child > .cat-item, .cat-children > .cat-item:last-child { border-bottom: none; }
|
|
.depth-2 { padding-left: 40px; background: rgba(0,0,0,.15); }
|
|
|
|
.cat-info { display: flex; align-items: center; gap: 10px; }
|
|
.cat-actions { display: flex; align-items: center; gap: 4px; }
|
|
.btn-sort { padding: 4px 8px; font-size: 11px; }
|
|
</style>
|
|
@endpush
|
|
|
|
@section('content')
|
|
<div class="grid-layout">
|
|
<div class="a-card" style="padding:16px;">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:16px;">🏢 연동사 및 📦 상품코드 목록</div>
|
|
|
|
<div class="cat-list">
|
|
@forelse($tree as $pv)
|
|
<div class="cat-group">
|
|
<div class="cat-item" style="background: rgba(59,130,246,.1);">
|
|
<div class="cat-info">
|
|
<span class="pill {{ $pv['is_active'] ? 'pill--ok' : 'pill--muted' }}">
|
|
{{ $pv['is_active'] ? 'ON' : 'OFF' }}
|
|
</span>
|
|
<strong style="color:#60a5fa;">{{ $pv['name'] }}</strong>
|
|
<span class="mono">[{{ $pv['code'] }}]</span>
|
|
</div>
|
|
<div class="cat-actions">
|
|
<button type="button" class="lbtn lbtn--sm lbtn--ghost" onclick="editProvider({{ json_encode($pv) }})">연동사 수정</button>
|
|
<form action="{{ route('admin.sale-codes.provider.destroy', $pv['id']) }}" method="POST" onsubmit="return confirm('이 연동사를 삭제하시겠습니까?\n하위에 등록된 상품 코드가 없어야 삭제 가능합니다.');" style="margin:0;">
|
|
@csrf @method('DELETE')
|
|
<button type="submit" class="lbtn lbtn--sm lbtn--danger">삭제</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="cat-children">
|
|
@foreach($pv['children'] as $cd)
|
|
<div class="cat-item depth-2" data-id="{{ $cd['id'] }}">
|
|
<div class="cat-info">
|
|
└
|
|
<span class="pill {{ $cd['is_active'] ? 'pill--ok' : 'pill--muted' }}">
|
|
{{ $cd['is_active'] ? 'ON' : 'OFF' }}
|
|
</span>
|
|
<span>{{ $cd['name'] }}</span>
|
|
<span class="a-muted" style="font-size:12px;">({{ $cd['api_code'] }})</span>
|
|
</div>
|
|
<div class="cat-actions">
|
|
<button type="button" class="lbtn lbtn--ghost btn-sort" onclick="moveRow(this, -1)">▲</button>
|
|
<button type="button" class="lbtn lbtn--ghost btn-sort" onclick="moveRow(this, 1)">▼</button>
|
|
<button type="button" class="lbtn lbtn--sm lbtn--ghost" style="margin-left:8px;" onclick="editCode({{ json_encode($cd) }})">수정</button>
|
|
<form action="{{ route('admin.sale-codes.code.destroy', $cd['id']) }}" method="POST" onsubmit="return confirm('이 상품 코드를 매핑에서 삭제하시겠습니까?');" style="margin:0;">
|
|
@csrf @method('DELETE')
|
|
<button type="submit" class="lbtn lbtn--sm lbtn--danger">삭제</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div style="padding: 20px; text-align: center;" class="a-muted">등록된 연동사 및 코드가 없습니다.</div>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div class="a-card" style="padding:16px; margin-bottom:20px; border-top: 3px solid rgba(52,211,153,.8);">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:16px;" id="codeTitle">📦 상품 코드 등록</div>
|
|
|
|
<form id="codeForm" method="POST" action="{{ route('admin.sale-codes.code.store') }}">
|
|
@csrf
|
|
<input type="hidden" name="_method" id="codeMethod" value="POST">
|
|
|
|
<div style="display:grid; gap:12px;">
|
|
<div class="a-field">
|
|
<label class="a-label">연동사 선택</label>
|
|
<select class="a-input" name="provider_id" id="codeProviderId" required>
|
|
<option value="">-- 연동사 선택 --</option>
|
|
@foreach($tree as $pv)
|
|
<option value="{{ $pv['id'] }}">{{ $pv['name'] }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">실제 API 상품 코드 (예: CULTURE)</label>
|
|
<input class="a-input" name="api_code" id="codeApi" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">상품 매핑 명칭 (예: 문화상품권)</label>
|
|
<input class="a-input" name="name" id="codeName" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">사용 여부</label>
|
|
<select class="a-input" name="is_active" id="codeActive">
|
|
<option value="1">ON (사용)</option>
|
|
<option value="0">OFF (숨김)</option>
|
|
</select>
|
|
</div>
|
|
<div style="display:flex; gap:10px; margin-top:10px;">
|
|
<button type="button" class="lbtn lbtn--ghost" style="flex:1;" onclick="resetCodeForm()">신규등록 초기화</button>
|
|
<button type="submit" class="lbtn lbtn--primary" style="flex:1;">저장</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="a-card" style="padding:16px; border-top: 3px solid rgba(96,165,250,.8);">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:16px;" id="pvTitle">🏢 신규 연동사 (Provider) 등록</div>
|
|
|
|
<form id="pvForm" method="POST" action="{{ route('admin.sale-codes.provider.store') }}">
|
|
@csrf
|
|
<input type="hidden" name="_method" id="pvMethod" value="POST">
|
|
|
|
<div style="display:grid; gap:12px;">
|
|
<div class="a-field">
|
|
<label class="a-label">연동사 코드 (예: DANAL)</label>
|
|
<input class="a-input" name="code" id="pvCode" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">연동사 노출명 (예: 다날)</label>
|
|
<input class="a-input" name="name" id="pvName" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">사용 여부</label>
|
|
<select class="a-input" name="is_active" id="pvActive">
|
|
<option value="1">ON (전체 사용)</option>
|
|
<option value="0">OFF (전체 장애/중단)</option>
|
|
</select>
|
|
</div>
|
|
<div style="display:flex; gap:10px; margin-top:10px;">
|
|
<button type="button" class="lbtn lbtn--ghost" style="flex:1;" onclick="resetPvForm()">신규등록 초기화</button>
|
|
<button type="submit" class="lbtn lbtn--primary" style="flex:1;">저장</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
const baseUrl = '{{ route('admin.sale-codes.index') }}';
|
|
|
|
// 상품 코드 수정 세팅
|
|
function editCode(cd) {
|
|
document.getElementById('codeTitle').innerText = '📦 상품 코드 수정 (#'+cd.id+')';
|
|
document.getElementById('codeForm').action = baseUrl + '/code/' + cd.id;
|
|
document.getElementById('codeMethod').value = 'PUT';
|
|
|
|
document.getElementById('codeProviderId').value = cd.provider_id;
|
|
document.getElementById('codeApi').value = cd.api_code;
|
|
document.getElementById('codeName').value = cd.name;
|
|
document.getElementById('codeActive').value = cd.is_active;
|
|
}
|
|
|
|
function resetCodeForm() {
|
|
document.getElementById('codeTitle').innerText = '📦 상품 코드 등록';
|
|
document.getElementById('codeForm').action = '{{ route('admin.sale-codes.code.store') }}';
|
|
document.getElementById('codeMethod').value = 'POST';
|
|
|
|
document.getElementById('codeProviderId').value = '';
|
|
document.getElementById('codeApi').value = '';
|
|
document.getElementById('codeName').value = '';
|
|
document.getElementById('codeActive').value = '1';
|
|
}
|
|
|
|
// 연동사 수정 세팅
|
|
function editProvider(pv) {
|
|
document.getElementById('pvTitle').innerText = '🏢 연동사 수정 (#'+pv.id+')';
|
|
document.getElementById('pvForm').action = baseUrl + '/provider/' + pv.id;
|
|
document.getElementById('pvMethod').value = 'PUT';
|
|
|
|
document.getElementById('pvCode').value = pv.code;
|
|
document.getElementById('pvCode').readOnly = true; // 코드는 수정 불가
|
|
document.getElementById('pvName').value = pv.name;
|
|
document.getElementById('pvActive').value = pv.is_active;
|
|
}
|
|
|
|
function resetPvForm() {
|
|
document.getElementById('pvTitle').innerText = '🏢 신규 연동사 등록';
|
|
document.getElementById('pvForm').action = '{{ route('admin.sale-codes.provider.store') }}';
|
|
document.getElementById('pvMethod').value = 'POST';
|
|
|
|
document.getElementById('pvCode').value = '';
|
|
document.getElementById('pvCode').readOnly = false;
|
|
document.getElementById('pvName').value = '';
|
|
document.getElementById('pvActive').value = '1';
|
|
}
|
|
|
|
// 드래그 앤 드롭 대신 화살표 버튼 정렬 (상품 코드 전용)
|
|
function moveRow(btn, direction) {
|
|
const item = btn.closest('.cat-item');
|
|
const container = item.parentNode;
|
|
|
|
if (direction === -1 && item.previousElementSibling) {
|
|
container.insertBefore(item, item.previousElementSibling);
|
|
saveSort(container);
|
|
} else if (direction === 1 && item.nextElementSibling) {
|
|
container.insertBefore(item.nextElementSibling, item);
|
|
saveSort(container);
|
|
}
|
|
}
|
|
|
|
function saveSort(container) {
|
|
const ids = Array.from(container.children).map(el => el.getAttribute('data-id'));
|
|
fetch('{{ route('admin.sale-codes.code.sort') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
'Accept': 'application/json'
|
|
},
|
|
body: JSON.stringify({ ids: ids })
|
|
});
|
|
}
|
|
</script>
|
|
@endpush
|