Files
sam-manage/resources/views/quote-formulas/partials/basic-info-tab.blade.php
hskwon 403e0720d9 feat(quote-formulas): 범위(Range) 관리 UI 추가 (Phase 1)
- QuoteFormulaRangeService, RangeController 생성
- 범위 CRUD API 엔드포인트 추가 (6개)
- edit.blade.php 탭 구조로 개편 (기본정보/범위/매핑/품목)
- ranges-tab.blade.php 범위 관리 UI 구현
- Alpine.js 기반 인터랙티브 CRUD
2025-12-22 17:42:51 +09:00

169 lines
8.1 KiB
PHP

{{-- 기본 정보 --}}
<form @submit.prevent="saveFormula()" class="space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- 카테고리 -->
<div>
<label for="category_id" class="block text-sm font-medium text-gray-700 mb-1">
카테고리 <span class="text-red-500">*</span>
</label>
<select x-model="form.category_id" id="category_id"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required>
<option value="">카테고리 선택</option>
<template x-for="cat in categories" :key="cat.id">
<option :value="cat.id" x-text="cat.name"></option>
</template>
</select>
</div>
<!-- 수식 유형 -->
<div>
<label for="type" class="block text-sm font-medium text-gray-700 mb-1">
수식 유형 <span class="text-red-500">*</span>
</label>
<select x-model="form.type" id="type"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required>
<option value="">유형 선택</option>
<option value="input">입력값</option>
<option value="calculation">계산식</option>
<option value="range">범위별</option>
<option value="mapping">매핑</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- 수식명 -->
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">
수식명 <span class="text-red-500">*</span>
</label>
<input type="text" x-model="form.name" id="name"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required>
</div>
<!-- 변수명 -->
<div>
<label for="variable" class="block text-sm font-medium text-gray-700 mb-1">
변수명 <span class="text-red-500">*</span>
</label>
<input type="text" :value="form.variable" @input="onVariableInput($event)" id="variable"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono"
required>
<p class="text-xs text-gray-500 mt-1">대문자로 시작, 대문자/숫자/언더스코어만 사용</p>
</div>
</div>
<!-- 계산식 (type=calculation 표시) -->
<div x-show="form.type === 'calculation'" x-transition>
<label for="formula" class="block text-sm font-medium text-gray-700 mb-1">
계산식 <span class="text-red-500">*</span>
</label>
<textarea x-model="form.formula" id="formula" rows="3"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono"></textarea>
<div class="flex items-center gap-4 mt-2">
<button type="button" @click="validateFormula()"
class="text-sm text-blue-600 hover:text-blue-700">
수식 검증
</button>
<span id="validateResult" class="text-sm"></span>
</div>
<p class="text-xs text-gray-500 mt-1">지원 함수: SUM, ROUND, CEIL, FLOOR, ABS, MIN, MAX, IF</p>
</div>
<!-- 사용 가능한 변수 목록 (계산식일 때만 표시) -->
<div x-show="form.type === 'calculation'" x-transition>
<label class="block text-sm font-medium text-gray-700 mb-2">사용 가능한 변수</label>
<div class="flex flex-wrap gap-2 p-3 bg-gray-50 rounded-lg max-h-32 overflow-y-auto">
<template x-if="availableVariables.length === 0">
<span class="text-sm text-gray-500">사용 가능한 변수가 없습니다.</span>
</template>
<template x-for="v in availableVariables" :key="v.variable">
<button type="button" @click="insertVariable(v.variable)"
class="px-2 py-1 bg-blue-100 text-blue-700 rounded text-xs font-mono hover:bg-blue-200"
:title="v.name + ' (' + v.category + ')'"
x-text="v.variable">
</button>
</template>
</div>
</div>
<!-- 범위별 안내 -->
<div x-show="form.type === 'range'" x-transition class="bg-blue-50 border border-blue-200 rounded-lg p-4">
<div class="flex items-start gap-3">
<svg class="w-5 h-5 text-blue-500 mt-0.5" 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"></path>
</svg>
<div>
<p class="text-sm font-medium text-blue-800">범위별 수식</p>
<p class="text-sm text-blue-700 mt-1">
조건 변수의 값에 따라 다른 결과를 반환합니다.
<span class="font-semibold">"범위 설정"</span> 탭에서 범위별 조건을 설정하세요.
</p>
</div>
</div>
</div>
<!-- 매핑 안내 -->
<div x-show="form.type === 'mapping'" x-transition class="bg-purple-50 border border-purple-200 rounded-lg p-4">
<div class="flex items-start gap-3">
<svg class="w-5 h-5 text-purple-500 mt-0.5" 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"></path>
</svg>
<div>
<p class="text-sm font-medium text-purple-800">매핑 수식</p>
<p class="text-sm text-purple-700 mt-1">
입력값을 미리 정의된 값으로 변환합니다.
<span class="font-semibold">"매핑 설정"</span> 탭에서 매핑 규칙을 설정하세요.
</p>
</div>
</div>
</div>
<!-- 설명 -->
<div>
<label for="description" class="block text-sm font-medium text-gray-700 mb-1">
설명
</label>
<textarea x-model="form.description" id="description" rows="2"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- 정렬 순서 -->
<div>
<label for="sort_order" class="block text-sm font-medium text-gray-700 mb-1">
정렬 순서
</label>
<input type="number" x-model="form.sort_order" id="sort_order"
min="1"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<!-- 활성 상태 -->
<div class="flex items-center pt-6">
<input type="checkbox" x-model="form.is_active" id="is_active"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<label for="is_active" class="ml-2 block text-sm text-gray-700">
활성화
</label>
</div>
</div>
<!-- 에러 메시지 -->
<div id="errorMessage" class="hidden bg-red-50 border border-red-200 rounded-lg p-4 text-sm text-red-700"></div>
<!-- 버튼 -->
<div class="flex justify-end gap-3 pt-4 border-t">
<a href="{{ route('quote-formulas.index') }}"
class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition">
취소
</a>
<button type="submit"
class="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition">
저장
</button>
</div>
</form>