fix: [sales] 가격시뮬레이터 카테고리 상호 배타 선택으로 변경

- 업종 선택 카드 UI 추가 (제조업/공사업체 중 하나만 선택)
- 카테고리 전환 시 기존 상품 선택 초기화 + 새 카테고리 필수상품만 자동 선택
- 다른 카테고리 상품이 동시에 체크되지 않도록 제한
This commit is contained in:
김보곤
2026-03-13 20:09:33 +09:00
parent a42dbde1a5
commit a35376ced9

View File

@@ -615,13 +615,30 @@ class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
</label>
</div>
{{-- 카테고리 상품 목록 --}}
{{-- 업종 카테고리 선택 --}}
<div class="bg-white rounded-xl shadow-sm p-5 mb-4">
<h3 class="text-sm font-semibold text-gray-700 mb-3">업종 선택</h3>
<div class="flex gap-3">
@foreach($categories as $category)
<div class="flex-1 cursor-pointer p-4 border-2 rounded-xl text-center transition-all"
:class="selectedCategoryId === {{ $category->id }}
? 'border-blue-600 bg-blue-600 shadow-lg shadow-blue-200'
: 'border-gray-200 bg-white hover:border-gray-300'"
x-on:click="selectCategory({{ $category->id }})">
<div class="font-semibold" :class="selectedCategoryId === {{ $category->id }} ? 'text-white' : 'text-gray-900'">{{ $category->name }}</div>
<div class="text-xs mt-1" :class="selectedCategoryId === {{ $category->id }} ? 'text-blue-100' : 'text-gray-500'">{{ $category->products->count() }} 상품 / {{ $category->base_storage }}</div>
</div>
@endforeach
</div>
</div>
{{-- 선택된 카테고리의 상품 목록 --}}
@foreach($categories as $category)
<div class="bg-white rounded-xl shadow-sm mb-4 overflow-hidden">
<div x-show="selectedCategoryId === {{ $category->id }}" class="bg-white rounded-xl shadow-sm mb-4 overflow-hidden">
<div class="px-5 py-4 border-b border-gray-100 flex items-center justify-between">
<div>
<h3 class="font-semibold text-gray-900">{{ $category->name }}</h3>
<p class="text-xs text-gray-500">기본 제공: {{ $category->base_storage }}</p>
<h3 class="font-semibold text-gray-900">{{ $category->name }} 상품</h3>
<p class="text-xs text-gray-500">필요한 상품을 체크하세요</p>
</div>
<span class="text-xs px-2 py-1 rounded-full bg-gray-100 text-gray-500">
{{ $category->products->count() }} 상품
@@ -638,7 +655,7 @@ class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500">
:checked="isSelected({{ $product->id }})"
x-on:change="toggleProduct({{ $product->id }})"
class="w-4 h-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500"
@if($product->is_required) checked disabled @endif>
@if($product->is_required) :disabled="isSelected({{ $product->id }})" @endif>
</label>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2">
@@ -865,25 +882,36 @@ function priceSimulator() {
});
});
// 필수 상품 ID 수집
const requiredIds = Object.values(productMap)
.filter(p => p.is_required)
.map(p => p.id);
// 카테고리별 필수 상품 선택 세트 생성
function buildRequiredSelected(catId) {
const result = {};
Object.values(productMap)
.filter(p => p.categoryId === catId && p.is_required)
.forEach(p => {
result[p.id] = {
adjustedFee: Number(p.registration_fee) || Math.floor(Number(p.development_fee) * 0.25),
};
});
return result;
}
// 초기 선택 상태: 필수 상품은 기본 선택 + 기본 가입비 적용
const initialSelected = {};
requiredIds.forEach(id => {
const p = productMap[id];
initialSelected[id] = {
adjustedFee: Number(p.registration_fee) || Math.floor(Number(p.development_fee) * 0.25),
};
});
// 첫 번째 카테고리를 기본 선택
const firstCategoryId = categoriesData.length > 0 ? categoriesData[0].id : null;
return {
showHelp: false,
signupType: 'individual',
hasReferrer: false,
selected: { ...initialSelected },
selectedCategoryId: firstCategoryId,
selected: buildRequiredSelected(firstCategoryId),
// --- 카테고리 선택 (상호 배타) ---
selectCategory(catId) {
if (this.selectedCategoryId === catId) return;
this.selectedCategoryId = catId;
// 전체 초기화 후 새 카테고리의 필수 상품만 선택
this.selected = buildRequiredSelected(catId);
},
// --- 상품 선택/해제 ---
isSelected(id) {
@@ -893,7 +921,10 @@ function priceSimulator() {
toggleProduct(id) {
const p = productMap[id];
if (!p) return;
if (p.is_required) return; // 필수 상품은 해제 불가
// 현재 카테고리 상품만 토글 가능
if (p.categoryId !== this.selectedCategoryId) return;
// 필수 상품은 해제 불가
if (p.is_required && this.isSelected(id)) return;
if (this.isSelected(id)) {
const copy = { ...this.selected };
@@ -1029,7 +1060,8 @@ function priceSimulator() {
resetAll() {
this.signupType = 'individual';
this.hasReferrer = false;
this.selected = { ...initialSelected };
this.selectedCategoryId = firstCategoryId;
this.selected = buildRequiredSelected(firstCategoryId);
},
};
}