fix: [sales] 가격시뮬레이터 카테고리 상호 배타 선택으로 변경
- 업종 선택 카드 UI 추가 (제조업/공사업체 중 하나만 선택) - 카테고리 전환 시 기존 상품 선택 초기화 + 새 카테고리 필수상품만 자동 선택 - 다른 카테고리 상품이 동시에 체크되지 않도록 제한
This commit is contained in:
@@ -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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user