Files
sam-manage/resources/views/dev-tools/partials/auth-modal.blade.php
kent f70f75fb22 feat(dev-tools): 인증 모달에 회사 선택 및 토큰 표시 기능 추가
- 인증 모달에 회사(테넌트) 선택 드롭다운 추가
  - 헤더의 $globalTenants 재사용
  - tenant.switch 라우트와 동기화
  - 회사 변경 시 사용자 목록 자동 갱신

- Bearer 토큰 표시 및 복사 기능 추가
  - 토큰 발급 API 엔드포인트 추가 (POST /dev-tools/api-explorer/issue-token)
  - 현재 상태 영역에 토큰 표시
  - 클립보드 복사 버튼 (Clipboard API + fallback)
  - 적용 후 모달 유지하여 토큰 복사 가능

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 15:10:09 +09:00

121 lines
7.1 KiB
PHP

{{--
Dev Tools 공유 인증 모달
사용법: @include('dev-tools.partials.auth-modal')
--}}
<!-- 인증 모달 -->
<div id="devToolsAuthModal" class="fixed inset-0 z-50 hidden">
<div class="fixed inset-0 bg-black/50" onclick="DevToolsAuth.closeModal()"></div>
<div class="fixed inset-0 flex items-center justify-center p-4">
<div class="bg-white rounded-lg shadow-xl max-w-lg w-full p-6 relative">
<!-- 헤더 -->
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-900">인증 설정</h3>
<button onclick="DevToolsAuth.closeModal()" class="text-gray-400 hover:text-gray-600">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<!-- 인증 방식 선택 -->
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">인증 방식</label>
<div class="flex gap-4">
<label class="flex items-center">
<input type="radio" name="devToolsAuthType" value="token" checked onchange="DevToolsAuth.toggleType()" class="mr-2">
<span class="text-sm">토큰 직접 입력</span>
</label>
<label class="flex items-center">
<input type="radio" name="devToolsAuthType" value="user" onchange="DevToolsAuth.toggleType()" class="mr-2">
<span class="text-sm">사용자 선택</span>
</label>
</div>
</div>
<!-- 토큰 직접 입력 섹션 -->
<div id="devToolsAuthTokenSection" class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-1">Bearer 토큰</label>
<input type="text" id="devToolsAuthBearerToken" placeholder="Bearer 토큰을 입력하세요"
class="w-full border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
</div>
<!-- 사용자 선택 섹션 -->
<div id="devToolsAuthUserSection" class="mb-4 hidden">
<!-- 회사/사용자 선택 (가로 배치) -->
<div class="flex gap-3 mb-2">
<!-- 회사 선택 -->
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 mb-1">회사 선택</label>
<select id="devToolsAuthTenantSelect" onchange="DevToolsAuth.switchTenant(this.value)" class="w-full border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">회사를 선택하세요</option>
@if(isset($globalTenants) && $globalTenants->isNotEmpty())
@foreach($globalTenants as $tenant)
<option value="{{ $tenant->id }}" {{ session('selected_tenant_id') == $tenant->id ? 'selected' : '' }}>
{{ $tenant->company_name }}
</option>
@endforeach
@endif
</select>
</div>
<!-- 사용자 선택 -->
<div class="flex-1">
<label class="block text-sm font-medium text-gray-700 mb-1">사용자 선택</label>
<select id="devToolsAuthSelectedUser" class="w-full border rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">사용자를 선택하세요</option>
</select>
</div>
</div>
<div id="devToolsAuthUserSpinner" class="hidden mt-2 text-sm text-gray-500">
<svg class="animate-spin h-4 w-4 inline mr-1" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
</svg>
사용자 목록 로딩 ...
</div>
<p class="mt-1 text-xs text-gray-500">
회사를 선택하면 해당 회사의 사용자 목록이 표시됩니다.<br>
선택된 사용자로 Sanctum 토큰이 자동 발급됩니다.
</p>
</div>
<!-- 현재 인증 상태 -->
<div id="devToolsAuthCurrentStatus" class="mb-4 p-3 bg-gray-50 rounded-lg">
<div class="text-sm text-gray-600">
<span class="font-medium">현재 상태:</span>
<span id="devToolsAuthStatusDisplay" class="text-gray-500">인증 필요</span>
</div>
<div id="devToolsAuthUserInfo" class="mt-1 text-xs text-gray-500 hidden"></div>
<!-- 토큰 표시 영역 -->
<div id="devToolsAuthTokenDisplay" class="mt-2 hidden">
<div class="flex items-center gap-2">
<span class="text-xs font-medium text-gray-600">Bearer Token:</span>
<button onclick="DevToolsAuth.copyToken()" class="text-xs text-blue-600 hover:text-blue-800 flex items-center gap-1" title="토큰 복사">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
</svg>
복사
</button>
</div>
<div class="mt-1 p-2 bg-gray-100 rounded border text-xs font-mono text-gray-700 break-all max-h-20 overflow-y-auto" id="devToolsAuthTokenValue">
-
</div>
</div>
</div>
<!-- 버튼 -->
<div class="flex justify-end gap-3">
<button type="button" onclick="DevToolsAuth.clear()" class="px-4 py-2 text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition">
인증 초기화
</button>
<button type="button" onclick="DevToolsAuth.closeModal()" class="px-4 py-2 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition">
닫기
</button>
<button type="button" onclick="DevToolsAuth.save()" class="px-4 py-2 text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition">
적용
</button>
</div>
</div>
</div>
</div>