feat:영업관리 사이드바 메뉴 추가 및 담당자 자동등록 기능
- MngMenuSeeder에 영업관리 메뉴 그룹 추가 - 영업담당자 관리 (/sales/managers) - 가망고객 관리 (/sales/prospects) - 영업실적 관리 (/sales/records) - 담당자 등록 화면에 번개 아이콘 자동입력 기능 추가 - 랜덤 샘플 데이터 자동 채우기 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -639,6 +639,46 @@ protected function seedMainMenus(): void
|
||||
'options' => ['route_name' => 'credit.inquiry.index', 'section' => 'main'],
|
||||
]);
|
||||
|
||||
// ========================================
|
||||
// 영업관리 그룹
|
||||
// ========================================
|
||||
$salesGroup = $this->createMenu([
|
||||
'name' => '영업관리',
|
||||
'url' => '#',
|
||||
'icon' => 'briefcase',
|
||||
'sort_order' => $sortOrder++,
|
||||
'options' => [
|
||||
'section' => 'main',
|
||||
'meta' => ['group_id' => 'sales-group'],
|
||||
],
|
||||
]);
|
||||
|
||||
$salesSubOrder = 0;
|
||||
$this->createMenu([
|
||||
'parent_id' => $salesGroup->id,
|
||||
'name' => '영업담당자 관리',
|
||||
'url' => '/sales/managers',
|
||||
'icon' => 'users',
|
||||
'sort_order' => $salesSubOrder++,
|
||||
'options' => ['route_name' => 'sales.managers.index', 'section' => 'main'],
|
||||
]);
|
||||
$this->createMenu([
|
||||
'parent_id' => $salesGroup->id,
|
||||
'name' => '가망고객 관리',
|
||||
'url' => '/sales/prospects',
|
||||
'icon' => 'user-group',
|
||||
'sort_order' => $salesSubOrder++,
|
||||
'options' => ['route_name' => 'sales.prospects.index', 'section' => 'main'],
|
||||
]);
|
||||
$this->createMenu([
|
||||
'parent_id' => $salesGroup->id,
|
||||
'name' => '영업실적 관리',
|
||||
'url' => '/sales/records',
|
||||
'icon' => 'chart-bar',
|
||||
'sort_order' => $salesSubOrder++,
|
||||
'options' => ['route_name' => 'sales.records.index', 'section' => 'main'],
|
||||
]);
|
||||
|
||||
// ========================================
|
||||
// 시스템 그룹
|
||||
// ========================================
|
||||
|
||||
@@ -12,17 +12,29 @@
|
||||
</svg>
|
||||
목록으로
|
||||
</a>
|
||||
<h1 class="text-2xl font-bold text-gray-800">영업담당자 등록</h1>
|
||||
<div class="flex items-center gap-3">
|
||||
<h1 class="text-2xl font-bold text-gray-800">영업담당자 등록</h1>
|
||||
<button type="button" id="fillTestDataBtn"
|
||||
class="p-2 bg-amber-50 text-amber-600 rounded-lg hover:bg-amber-100 transition-all border border-amber-200 group relative"
|
||||
title="샘플 데이터 자동 입력">
|
||||
<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="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
<span class="absolute -top-10 left-1/2 -translate-x-1/2 bg-gray-800 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none z-50">
|
||||
랜덤 데이터 채우기
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 폼 -->
|
||||
<form action="{{ route('sales.managers.store') }}" method="POST" class="bg-white rounded-lg shadow-sm p-6 space-y-6">
|
||||
<form action="{{ route('sales.managers.store') }}" method="POST" id="managerForm" class="bg-white rounded-lg shadow-sm p-6 space-y-6">
|
||||
@csrf
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">로그인 ID <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="member_id" value="{{ old('member_id') }}" required
|
||||
<input type="text" name="member_id" id="member_id" value="{{ old('member_id') }}" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 @error('member_id') border-red-500 @enderror">
|
||||
@error('member_id')
|
||||
<p class="mt-1 text-sm text-red-500">{{ $message }}</p>
|
||||
@@ -31,7 +43,7 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">비밀번호 <span class="text-red-500">*</span></label>
|
||||
<input type="password" name="password" required
|
||||
<input type="text" name="password" id="password" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 @error('password') border-red-500 @enderror">
|
||||
@error('password')
|
||||
<p class="mt-1 text-sm text-red-500">{{ $message }}</p>
|
||||
@@ -42,7 +54,7 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">이름 <span class="text-red-500">*</span></label>
|
||||
<input type="text" name="name" value="{{ old('name') }}" required
|
||||
<input type="text" name="name" id="name" value="{{ old('name') }}" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 @error('name') border-red-500 @enderror">
|
||||
@error('name')
|
||||
<p class="mt-1 text-sm text-red-500">{{ $message }}</p>
|
||||
@@ -51,7 +63,7 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">역할 <span class="text-red-500">*</span></label>
|
||||
<select name="role" required
|
||||
<select name="role" id="role" required
|
||||
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 @error('role') border-red-500 @enderror">
|
||||
<option value="manager" {{ old('role') === 'manager' ? 'selected' : '' }}>매니저</option>
|
||||
<option value="sales_admin" {{ old('role') === 'sales_admin' ? 'selected' : '' }}>영업관리</option>
|
||||
@@ -66,13 +78,13 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">전화번호</label>
|
||||
<input type="text" name="phone" value="{{ old('phone') }}"
|
||||
<input type="text" name="phone" id="phone" value="{{ old('phone') }}"
|
||||
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>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">이메일</label>
|
||||
<input type="email" name="email" value="{{ old('email') }}"
|
||||
<input type="email" name="email" id="email" value="{{ old('email') }}"
|
||||
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>
|
||||
@@ -92,7 +104,7 @@ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none foc
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">비고</label>
|
||||
<textarea name="remarks" rows="3"
|
||||
<textarea name="remarks" id="remarks" 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">{{ old('remarks') }}</textarea>
|
||||
</div>
|
||||
|
||||
@@ -109,3 +121,33 @@ class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.getElementById('fillTestDataBtn').addEventListener('click', function() {
|
||||
const sampleNames = ['한효주', '공유', '이동욱', '김고은', '신세경', '박서준', '김수현', '수지', '남주혁', '성시경', '아이유', '조세호'];
|
||||
const sampleIds = ['sales_pro', 'mkt_king', 'deal_maker', 'win_win', 'growth_lab', 'biz_hero', 'ace_mgr', 'top_tier'];
|
||||
|
||||
const randomItem = (arr) => arr[Math.floor(Math.random() * arr.length)];
|
||||
const randomNum = (len) => Array.from({length: len}, () => Math.floor(Math.random() * 10)).join('');
|
||||
|
||||
const formatPhone = (val) => {
|
||||
const clean = val.replace(/[^0-9]/g, '');
|
||||
if (clean.length === 11) {
|
||||
return clean.slice(0, 3) + '-' + clean.slice(3, 7) + '-' + clean.slice(7);
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
||||
const name = randomItem(sampleNames);
|
||||
const idSuffix = randomNum(3);
|
||||
|
||||
document.getElementById('member_id').value = randomItem(sampleIds) + idSuffix;
|
||||
document.getElementById('password').value = 'password123';
|
||||
document.getElementById('name').value = name;
|
||||
document.getElementById('phone').value = formatPhone('010' + randomNum(8));
|
||||
document.getElementById('email').value = 'manager_' + randomNum(4) + '@example.com';
|
||||
document.getElementById('remarks').value = 'MNG 시스템 생성 샘플 데이터';
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
Reference in New Issue
Block a user