## 인증 모달 통합
- api-explorer, flow-tester, api-logs 3개 페이지의 인증 UI 통합
- 공유 컴포넌트 생성: auth-modal.blade.php, auth-scripts.blade.php
- sessionStorage 기반으로 페이지 간 인증 상태 공유
- DevToolsAuth 글로벌 JavaScript API 제공
## 테넌트 사용자 조회 개선
- 시스템 헤더에서 선택한 테넌트의 사용자 목록 표시
- 관리자가 모든 테넌트의 사용자 조회 가능 (소속 무관)
- session('selected_tenant_id')로 Tenant 모델 직접 조회
- 테넌트 미선택 시 안내 메시지 표시
## 버그 수정
- /users 페이지 HTMX swap 오류 수정 (JSON→HTML 직접 반환)
- 사용자 이름 JavaScript 이스케이프 처리 (@js() 사용)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
90 lines
4.5 KiB
PHP
90 lines
4.5 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<title>로그인 - {{ config('app.name') }}</title>
|
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
</head>
|
|
<body class="bg-gray-100">
|
|
<div class="min-h-screen flex items-center justify-center">
|
|
<div class="flex flex-col items-center">
|
|
<div class="text-center mb-6">
|
|
<h1 class="text-4xl font-bold text-gray-900">{{ config('app.name') }}</h1>
|
|
<p class="text-gray-600 mt-2">관리자 패널</p>
|
|
</div>
|
|
|
|
<div class="w-96 bg-white rounded-lg shadow-xl p-8">
|
|
<h2 class="text-2xl font-semibold text-center mb-6">로그인</h2>
|
|
|
|
@if (session('success'))
|
|
<div class="flex items-center gap-3 p-4 mb-4 bg-green-100 border border-green-200 text-green-800 rounded-lg">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<span>{{ session('success') }}</span>
|
|
</div>
|
|
@endif
|
|
|
|
@if ($errors->any())
|
|
<div class="flex items-center gap-3 p-4 mb-4 bg-red-100 border border-red-200 text-red-800 rounded-lg">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
<span>{{ $errors->first() }}</span>
|
|
</div>
|
|
@endif
|
|
|
|
<form method="POST" action="{{ route('login') }}">
|
|
@csrf
|
|
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
이메일
|
|
</label>
|
|
<input
|
|
type="email"
|
|
name="email"
|
|
value="{{ old('email') }}"
|
|
placeholder="email@example.com"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent @error('email') border-red-500 @enderror"
|
|
required
|
|
autofocus
|
|
/>
|
|
@error('email')
|
|
<p class="text-sm text-red-600 mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
비밀번호
|
|
</label>
|
|
<input
|
|
type="password"
|
|
name="password"
|
|
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-transparent @error('password') border-red-500 @enderror"
|
|
required
|
|
/>
|
|
@error('password')
|
|
<p class="text-sm text-red-600 mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="mb-6">
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input type="checkbox" name="remember" value="1" class="w-4 h-4 text-primary border-gray-300 rounded focus:ring-2 focus:ring-primary" />
|
|
<span class="text-sm text-gray-700">로그인 상태 유지</span>
|
|
</label>
|
|
</div>
|
|
|
|
<button type="submit" class="w-full bg-primary text-white font-semibold py-2.5 px-4 rounded-lg hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-opacity">
|
|
로그인
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |