feat:영업파트너 고객관리 페이지 내부 새로고침 기능 추가
- 헤더에 새로고침 버튼 추가 - HTMX로 콘텐츠 영역만 새로고침 (페이지 전체 리로드 없음) - 컨트롤러에 refresh 메서드 및 getIndexData 공통 메서드 추가 - content.blade.php partial 분리 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,48 @@ public function index(Request $request): View|Response
|
||||
return response('', 200)->header('HX-Redirect', route('sales.admin-prospects.index'));
|
||||
}
|
||||
|
||||
$data = $this->getIndexData($request);
|
||||
|
||||
return view('sales.admin-prospects.index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 고객 상세 모달
|
||||
*/
|
||||
public function modalShow(int $id): View
|
||||
{
|
||||
$this->checkAdminAccess();
|
||||
|
||||
$prospect = TenantProspect::with(['registeredBy', 'tenant'])->findOrFail($id);
|
||||
|
||||
// 진행률
|
||||
$progress = SalesScenarioChecklist::getProspectProgress($prospect->id);
|
||||
$prospect->sales_progress = $progress['sales']['percentage'];
|
||||
$prospect->manager_progress = $progress['manager']['percentage'];
|
||||
|
||||
// management 정보
|
||||
$management = SalesTenantManagement::findOrCreateByProspect($prospect->id);
|
||||
|
||||
return view('sales.admin-prospects.partials.show-modal', compact('prospect', 'management', 'progress'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 콘텐츠 새로고침 (HTMX)
|
||||
*/
|
||||
public function refresh(Request $request): View
|
||||
{
|
||||
$this->checkAdminAccess();
|
||||
|
||||
$data = $this->getIndexData($request);
|
||||
|
||||
return view('sales.admin-prospects.partials.content', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* index 데이터 조회 (공통)
|
||||
*/
|
||||
private function getIndexData(Request $request): array
|
||||
{
|
||||
// 영업 역할을 가진 사용자 목록 (영업파트너)
|
||||
$salesPartners = User::whereHas('userRoles', function ($q) {
|
||||
$q->whereHas('role', function ($rq) {
|
||||
@@ -48,7 +90,7 @@ public function index(Request $request): View|Response
|
||||
$filters = [
|
||||
'search' => $request->get('search'),
|
||||
'status' => $request->get('status'),
|
||||
'registered_by' => $request->get('registered_by'), // 특정 영업파트너 필터
|
||||
'registered_by' => $request->get('registered_by'),
|
||||
];
|
||||
|
||||
// 쿼리 빌드
|
||||
@@ -86,7 +128,6 @@ public function index(Request $request): View|Response
|
||||
// 진행률 100% 시 상태 자동 전환 체크
|
||||
if ($progress['sales']['percentage'] === 100 && $progress['manager']['percentage'] === 100) {
|
||||
SalesScenarioChecklist::checkAndConvertProspectStatus($prospect->id);
|
||||
// 상태가 변경되었을 수 있으므로 다시 로드
|
||||
$prospect->refresh();
|
||||
}
|
||||
|
||||
@@ -117,27 +158,7 @@ public function index(Request $request): View|Response
|
||||
];
|
||||
});
|
||||
|
||||
return view('sales.admin-prospects.index', compact('prospects', 'stats', 'salesPartners', 'partnerStats', 'filters'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 고객 상세 모달
|
||||
*/
|
||||
public function modalShow(int $id): View
|
||||
{
|
||||
$this->checkAdminAccess();
|
||||
|
||||
$prospect = TenantProspect::with(['registeredBy', 'tenant'])->findOrFail($id);
|
||||
|
||||
// 진행률
|
||||
$progress = SalesScenarioChecklist::getProspectProgress($prospect->id);
|
||||
$prospect->sales_progress = $progress['sales']['percentage'];
|
||||
$prospect->manager_progress = $progress['manager']['percentage'];
|
||||
|
||||
// management 정보
|
||||
$management = SalesTenantManagement::findOrCreateByProspect($prospect->id);
|
||||
|
||||
return view('sales.admin-prospects.partials.show-modal', compact('prospect', 'management', 'progress'));
|
||||
return compact('prospects', 'stats', 'salesPartners', 'partnerStats', 'filters');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,25 @@
|
||||
|
||||
@section('title', '영업파트너 고객관리')
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
/* 새로고침 버튼 아이콘 상태 */
|
||||
.refresh-btn [data-refresh-spin] {
|
||||
display: none;
|
||||
}
|
||||
.refresh-btn [data-refresh-icon] {
|
||||
display: inline-block;
|
||||
}
|
||||
/* 로딩 중: 스피너 표시, 아이콘 숨김 */
|
||||
.refresh-btn.htmx-request [data-refresh-spin] {
|
||||
display: inline-block;
|
||||
}
|
||||
.refresh-btn.htmx-request [data-refresh-icon] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="flex flex-col h-full">
|
||||
<!-- 페이지 헤더 -->
|
||||
@@ -10,180 +29,26 @@
|
||||
<h1 class="text-2xl font-bold text-gray-800">영업파트너 고객관리</h1>
|
||||
<p class="text-sm text-gray-500 mt-1">전체 영업파트너의 고객 현황을 관리합니다 (관리자 전용)</p>
|
||||
</div>
|
||||
<!-- 새로고침 버튼 -->
|
||||
<button type="button"
|
||||
hx-get="{{ route('sales.admin-prospects.refresh', request()->query()) }}"
|
||||
hx-target="#admin-prospects-content"
|
||||
hx-swap="innerHTML"
|
||||
class="refresh-btn inline-flex items-center gap-1.5 px-4 py-2 text-sm text-gray-600 hover:text-blue-600 bg-white hover:bg-blue-50 border border-gray-300 rounded-lg transition-colors shadow-sm"
|
||||
title="새로고침">
|
||||
<svg data-refresh-spin class="w-4 h-4 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
<svg data-refresh-icon 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="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
<span>새로고침</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 통계 카드 -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4 flex-shrink-0">
|
||||
<div class="bg-white rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-gray-500">전체 고객</div>
|
||||
<div class="text-2xl font-bold text-gray-800">{{ number_format($stats['total']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-blue-600">영업 진행중</div>
|
||||
<div class="text-2xl font-bold text-blue-800">{{ number_format($stats['active']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-orange-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-orange-600">영업권 만료</div>
|
||||
<div class="text-2xl font-bold text-orange-800">{{ number_format($stats['expired']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-emerald-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-emerald-600">계약 완료</div>
|
||||
<div class="text-2xl font-bold text-emerald-800">{{ number_format($stats['converted']) }}건</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 필터 영역 -->
|
||||
<div class="flex-shrink-0 mb-4">
|
||||
<form method="GET" class="flex flex-wrap gap-2 sm:gap-3 items-center bg-white p-3 rounded-lg shadow-sm">
|
||||
<!-- 상태 필터 버튼 -->
|
||||
<div class="flex gap-1 flex-shrink-0">
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('status', 'page'), [])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ !request('status') ? 'bg-gray-800 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
전체
|
||||
</a>
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('page'), ['status' => 'active'])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ request('status') === 'active' ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
진행중
|
||||
</a>
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('page'), ['status' => 'converted'])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ request('status') === 'converted' ? 'bg-emerald-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
계약완료
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- 구분선 -->
|
||||
<div class="hidden sm:block w-px h-8 bg-gray-300"></div>
|
||||
|
||||
<!-- 현재 status 유지 -->
|
||||
@if(request('status'))
|
||||
<input type="hidden" name="status" value="{{ request('status') }}">
|
||||
@endif
|
||||
|
||||
<!-- 영업파트너 선택 -->
|
||||
<div class="w-40 flex-shrink-0">
|
||||
<select name="registered_by" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
<option value="">전체 파트너</option>
|
||||
@foreach($salesPartners as $partner)
|
||||
<option value="{{ $partner->id }}" {{ request('registered_by') == $partner->id ? 'selected' : '' }}>
|
||||
{{ $partner->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 검색 입력 -->
|
||||
<div class="flex-1 min-w-0">
|
||||
<input type="text"
|
||||
name="search"
|
||||
value="{{ request('search') }}"
|
||||
placeholder="업체명, 사업자번호, 대표자, 연락처 검색..."
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
</div>
|
||||
|
||||
<!-- 검색 버튼 -->
|
||||
<button type="submit" class="bg-gray-700 hover:bg-gray-800 text-white px-4 py-2 rounded-lg transition text-sm flex-shrink-0">
|
||||
검색
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 테이블 -->
|
||||
<div class="bg-white rounded-lg shadow-sm overflow-hidden flex-1 flex flex-col min-h-0">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">업체명</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">담당 파트너</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">담당 매니저</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">영업 진행률</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">매니저 진행률</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">개발 상태</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">상태</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">등록일</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">관리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@forelse($prospects as $prospect)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
<div class="font-medium text-gray-900">{{ $prospect->company_name }}</div>
|
||||
<div class="text-xs text-gray-500">{{ $prospect->business_number }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
@if($prospect->registeredBy)
|
||||
<span class="text-sm text-gray-900">{{ $prospect->registeredBy->name }}</span>
|
||||
@else
|
||||
<span class="text-sm text-gray-400">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
@if($prospect->manager_user)
|
||||
<span class="text-sm text-gray-900">{{ $prospect->manager_user->name }}</span>
|
||||
@else
|
||||
<span class="text-sm text-gray-400">미지정</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<div class="w-16 bg-gray-200 rounded-full h-2">
|
||||
<div class="bg-blue-500 h-2 rounded-full" style="width: {{ $prospect->sales_progress }}%"></div>
|
||||
</div>
|
||||
<span class="text-xs text-gray-600">{{ $prospect->sales_progress }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<div class="w-16 bg-gray-200 rounded-full h-2">
|
||||
<div class="bg-green-500 h-2 rounded-full" style="width: {{ $prospect->manager_progress }}%"></div>
|
||||
</div>
|
||||
<span class="text-xs text-gray-600">{{ $prospect->manager_progress }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<select
|
||||
onchange="updateHqStatus({{ $prospect->id }}, this.value)"
|
||||
class="text-xs font-medium rounded-lg px-2 py-1 border cursor-pointer
|
||||
@if($prospect->hq_status === 'handover') bg-emerald-100 text-emerald-700 border-emerald-300
|
||||
@elseif($prospect->hq_status === 'pending') bg-gray-100 text-gray-600 border-gray-300
|
||||
@else bg-purple-100 text-purple-700 border-purple-300 @endif">
|
||||
@foreach(\App\Models\Sales\SalesTenantManagement::$hqStatusLabels as $status => $label)
|
||||
<option value="{{ $status }}" {{ $prospect->hq_status === $status ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full {{ $prospect->status_color }}">
|
||||
{{ $prospect->status_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ $prospect->created_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-right text-sm font-medium">
|
||||
<button type="button" onclick="openDetailModal({{ $prospect->id }})" class="text-blue-600 hover:text-blue-900">상세</button>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-6 py-12 text-center text-gray-500">
|
||||
등록된 고객이 없습니다.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 페이지네이션 -->
|
||||
@if($prospects->hasPages())
|
||||
<div class="px-6 py-4 border-t border-gray-200">
|
||||
{{ $prospects->withQueryString()->links() }}
|
||||
</div>
|
||||
@endif
|
||||
<!-- 콘텐츠 영역 (HTMX로 새로고침) -->
|
||||
<div id="admin-prospects-content" class="flex-1 flex flex-col min-h-0">
|
||||
@include('sales.admin-prospects.partials.content')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
173
resources/views/sales/admin-prospects/partials/content.blade.php
Normal file
173
resources/views/sales/admin-prospects/partials/content.blade.php
Normal file
@@ -0,0 +1,173 @@
|
||||
{{-- 통계 카드 --}}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
|
||||
<div class="bg-white rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-gray-500">전체 고객</div>
|
||||
<div class="text-2xl font-bold text-gray-800">{{ number_format($stats['total']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-blue-600">영업 진행중</div>
|
||||
<div class="text-2xl font-bold text-blue-800">{{ number_format($stats['active']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-orange-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-orange-600">영업권 만료</div>
|
||||
<div class="text-2xl font-bold text-orange-800">{{ number_format($stats['expired']) }}건</div>
|
||||
</div>
|
||||
<div class="bg-emerald-50 rounded-lg shadow-sm p-4">
|
||||
<div class="text-sm text-emerald-600">계약 완료</div>
|
||||
<div class="text-2xl font-bold text-emerald-800">{{ number_format($stats['converted']) }}건</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 필터 영역 --}}
|
||||
<div class="mb-4">
|
||||
<form method="GET" class="flex flex-wrap gap-2 sm:gap-3 items-center bg-white p-3 rounded-lg shadow-sm">
|
||||
{{-- 상태 필터 버튼 --}}
|
||||
<div class="flex gap-1 flex-shrink-0">
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('status', 'page'), [])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ !request('status') ? 'bg-gray-800 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
전체
|
||||
</a>
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('page'), ['status' => 'active'])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ request('status') === 'active' ? 'bg-blue-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
진행중
|
||||
</a>
|
||||
<a href="{{ route('sales.admin-prospects.index', array_merge(request()->except('page'), ['status' => 'converted'])) }}"
|
||||
class="px-3 py-2 rounded-lg text-sm font-medium transition {{ request('status') === 'converted' ? 'bg-emerald-600 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
계약완료
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- 구분선 --}}
|
||||
<div class="hidden sm:block w-px h-8 bg-gray-300"></div>
|
||||
|
||||
{{-- 현재 status 유지 --}}
|
||||
@if(request('status'))
|
||||
<input type="hidden" name="status" value="{{ request('status') }}">
|
||||
@endif
|
||||
|
||||
{{-- 영업파트너 선택 --}}
|
||||
<div class="w-40 flex-shrink-0">
|
||||
<select name="registered_by" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
<option value="">전체 파트너</option>
|
||||
@foreach($salesPartners as $partner)
|
||||
<option value="{{ $partner->id }}" {{ request('registered_by') == $partner->id ? 'selected' : '' }}>
|
||||
{{ $partner->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{{-- 검색 입력 --}}
|
||||
<div class="flex-1 min-w-0">
|
||||
<input type="text"
|
||||
name="search"
|
||||
value="{{ request('search') }}"
|
||||
placeholder="업체명, 사업자번호, 대표자, 연락처 검색..."
|
||||
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm">
|
||||
</div>
|
||||
|
||||
{{-- 검색 버튼 --}}
|
||||
<button type="submit" class="bg-gray-700 hover:bg-gray-800 text-white px-4 py-2 rounded-lg transition text-sm flex-shrink-0">
|
||||
검색
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- 테이블 --}}
|
||||
<div class="bg-white rounded-lg shadow-sm overflow-hidden flex-1 flex flex-col min-h-0">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">업체명</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">담당 파트너</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">담당 매니저</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">영업 진행률</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">매니저 진행률</th>
|
||||
<th class="px-4 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider">개발 상태</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">상태</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">등록일</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">관리</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@forelse($prospects as $prospect)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
<div class="font-medium text-gray-900">{{ $prospect->company_name }}</div>
|
||||
<div class="text-xs text-gray-500">{{ $prospect->business_number }}</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
@if($prospect->registeredBy)
|
||||
<span class="text-sm text-gray-900">{{ $prospect->registeredBy->name }}</span>
|
||||
@else
|
||||
<span class="text-sm text-gray-400">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
@if($prospect->manager_user)
|
||||
<span class="text-sm text-gray-900">{{ $prospect->manager_user->name }}</span>
|
||||
@else
|
||||
<span class="text-sm text-gray-400">미지정</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<div class="w-16 bg-gray-200 rounded-full h-2">
|
||||
<div class="bg-blue-500 h-2 rounded-full" style="width: {{ $prospect->sales_progress }}%"></div>
|
||||
</div>
|
||||
<span class="text-xs text-gray-600">{{ $prospect->sales_progress }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<div class="w-16 bg-gray-200 rounded-full h-2">
|
||||
<div class="bg-green-500 h-2 rounded-full" style="width: {{ $prospect->manager_progress }}%"></div>
|
||||
</div>
|
||||
<span class="text-xs text-gray-600">{{ $prospect->manager_progress }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-center">
|
||||
<select
|
||||
onchange="updateHqStatus({{ $prospect->id }}, this.value)"
|
||||
class="text-xs font-medium rounded-lg px-2 py-1 border cursor-pointer
|
||||
@if($prospect->hq_status === 'handover') bg-emerald-100 text-emerald-700 border-emerald-300
|
||||
@elseif($prospect->hq_status === 'pending') bg-gray-100 text-gray-600 border-gray-300
|
||||
@else bg-purple-100 text-purple-700 border-purple-300 @endif">
|
||||
@foreach(\App\Models\Sales\SalesTenantManagement::$hqStatusLabels as $status => $label)
|
||||
<option value="{{ $status }}" {{ $prospect->hq_status === $status ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded-full {{ $prospect->status_color }}">
|
||||
{{ $prospect->status_label }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
{{ $prospect->created_at->format('Y-m-d') }}
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-right text-sm font-medium">
|
||||
<button type="button" onclick="openDetailModal({{ $prospect->id }})" class="text-blue-600 hover:text-blue-900">상세</button>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-6 py-12 text-center text-gray-500">
|
||||
등록된 고객이 없습니다.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- 페이지네이션 --}}
|
||||
@if($prospects->hasPages())
|
||||
<div class="px-6 py-4 border-t border-gray-200">
|
||||
{{ $prospects->withQueryString()->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@@ -930,6 +930,7 @@
|
||||
|
||||
// 관리자용 전체 고객 관리 (관리자/슈퍼관리자 전용)
|
||||
Route::get('admin-prospects', [\App\Http\Controllers\Sales\AdminProspectController::class, 'index'])->name('admin-prospects.index');
|
||||
Route::get('admin-prospects/refresh', [\App\Http\Controllers\Sales\AdminProspectController::class, 'refresh'])->name('admin-prospects.refresh');
|
||||
Route::get('admin-prospects/{id}/modal-show', [\App\Http\Controllers\Sales\AdminProspectController::class, 'modalShow'])->name('admin-prospects.modal-show');
|
||||
Route::post('admin-prospects/{id}/hq-status', [\App\Http\Controllers\Sales\AdminProspectController::class, 'updateHqStatus'])->name('admin-prospects.update-hq-status');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user