create.blade.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. {{-- Вьюха: Создание нового пользователя с назначением роли и прав.
  2. Контроллер: Admin\UserAdminController@create / store
  3. Переменные: $permissions (все права по группам), $roleLabels (метки ролей)
  4. --}}
  5. @extends('admin.layout')
  6. @section('title', 'Новый пользователь')
  7. @section('content_header')
  8. <div class="d-flex justify-content-between align-items-center">
  9. <h1 class="m-0">Новый пользователь</h1>
  10. <a href="{{ route('admin.users.index') }}" class="btn btn-default btn-sm">
  11. <i class="fas fa-arrow-left"></i> Назад
  12. </a>
  13. </div>
  14. @stop
  15. @section('breadcrumb')
  16. <li class="breadcrumb-item"><a href="{{ route('admin.dashboard') }}">Главная</a></li>
  17. <li class="breadcrumb-item"><a href="{{ route('admin.users.index') }}">Пользователи</a></li>
  18. <li class="breadcrumb-item active">Новый пользователь</li>
  19. @stop
  20. @section('content')
  21. @if($errors->any())
  22. <div class="alert alert-danger alert-dismissible">
  23. <button type="button" class="close" data-dismiss="alert">&times;</button>
  24. <ul class="mb-0 pl-3">
  25. @foreach($errors->all() as $error)
  26. <li>{{ $error }}</li>
  27. @endforeach
  28. </ul>
  29. </div>
  30. @endif
  31. <form action="{{ route('admin.users.store') }}" method="POST">
  32. @csrf
  33. <div class="row">
  34. {{-- Левая колонка: данные + роль --}}
  35. <div class="col-md-4">
  36. {{-- Данные пользователя --}}
  37. <div class="card card-primary card-outline">
  38. <div class="card-header"><h3 class="card-title">Учётные данные</h3></div>
  39. <div class="card-body">
  40. <div class="form-group">
  41. <label for="name">Имя <span class="text-danger">*</span></label>
  42. <input type="text" id="name" name="name" class="form-control @error('name') is-invalid @enderror"
  43. value="{{ old('name') }}" placeholder="Иван Иванов" required>
  44. @error('name')
  45. <div class="invalid-feedback">{{ $message }}</div>
  46. @enderror
  47. </div>
  48. <div class="form-group">
  49. <label for="email">Email <span class="text-danger">*</span></label>
  50. <input type="email" id="email" name="email" class="form-control @error('email') is-invalid @enderror"
  51. value="{{ old('email') }}" placeholder="user@example.com" required>
  52. @error('email')
  53. <div class="invalid-feedback">{{ $message }}</div>
  54. @enderror
  55. </div>
  56. <div class="form-group">
  57. <label for="password">Пароль <span class="text-danger">*</span></label>
  58. <input type="password" id="password" name="password"
  59. class="form-control @error('password') is-invalid @enderror"
  60. placeholder="Минимум 8 символов" required>
  61. @error('password')
  62. <div class="invalid-feedback">{{ $message }}</div>
  63. @enderror
  64. </div>
  65. <div class="form-group mb-0">
  66. <label for="password_confirmation">Подтверждение пароля <span class="text-danger">*</span></label>
  67. <input type="password" id="password_confirmation" name="password_confirmation"
  68. class="form-control" placeholder="Повторите пароль" required>
  69. </div>
  70. </div>
  71. </div>
  72. {{-- Роль --}}
  73. <div class="card card-primary card-outline">
  74. <div class="card-header"><h3 class="card-title">Роль</h3></div>
  75. <div class="card-body">
  76. <p class="text-muted" style="font-size:13px">
  77. Роль задаёт базовый набор прав. Индивидуальные overrides (справа) могут дополнить или ограничить их.
  78. </p>
  79. <div class="form-group mb-0">
  80. @foreach($roleLabels as $roleKey => $roleInfo)
  81. {{-- superadmin может назначить только суперадмин --}}
  82. @if($roleKey === 'superadmin' && auth()->user()->role !== 'superadmin')
  83. @continue
  84. @endif
  85. {{-- admin может назначить только суперадмин --}}
  86. @if($roleKey === 'admin' && auth()->user()->role !== 'superadmin')
  87. @continue
  88. @endif
  89. <div class="custom-control custom-radio mb-2">
  90. <input type="radio" class="custom-control-input" id="role_{{ $roleKey }}"
  91. name="role" value="{{ $roleKey }}" {{ old('role') === $roleKey ? 'checked' : '' }}>
  92. <label class="custom-control-label" for="role_{{ $roleKey }}">
  93. <span class="badge badge-{{ $roleInfo['color'] }}">{{ $roleInfo['label'] }}</span>
  94. <div style="font-size:11px;color:var(--muted,#666);margin-top:3px">
  95. @switch($roleKey)
  96. @case('superadmin') Все права, управляет всеми @break
  97. @case('admin') Всё кроме управления admins @break
  98. @case('editor') Автомобили + контент сайта @break
  99. @case('viewer') Только просмотр @break
  100. @endswitch
  101. </div>
  102. </label>
  103. </div>
  104. @endforeach
  105. <div class="custom-control custom-radio mt-2">
  106. <input type="radio" class="custom-control-input" id="role_none"
  107. name="role" value="" {{ ! old('role') ? 'checked' : '' }}>
  108. <label class="custom-control-label" for="role_none">
  109. <span class="badge badge-secondary">Без роли</span>
  110. <div style="font-size:11px;color:var(--muted,#666);margin-top:3px">Нет доступа в панель</div>
  111. </label>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="card-footer">
  116. <button type="submit" class="btn btn-success btn-block">
  117. <i class="fas fa-user-plus"></i> Создать пользователя
  118. </button>
  119. <a href="{{ route('admin.users.index') }}" class="btn btn-secondary btn-block mt-1">Отмена</a>
  120. </div>
  121. </div>
  122. </div>
  123. {{-- Правая колонка: индивидуальные overrides --}}
  124. <div class="col-md-8">
  125. <div class="card card-secondary card-outline">
  126. <div class="card-header">
  127. <h3 class="card-title">Индивидуальные overrides</h3>
  128. <div class="card-tools">
  129. <small class="text-muted">
  130. <span class="badge badge-success">Allow</span> — разрешить поверх роли &nbsp;
  131. <span class="badge badge-danger">Deny</span> — запретить поверх роли &nbsp;
  132. <span class="badge badge-secondary">Роль</span> — без override
  133. </small>
  134. </div>
  135. </div>
  136. <div class="card-body">
  137. @foreach($permissions as $groupName => $groupPerms)
  138. <h6 class="text-uppercase text-muted mb-2" style="font-size:11px;letter-spacing:.1em">{{ $groupName }}</h6>
  139. <table class="table table-sm table-bordered mb-3">
  140. <thead>
  141. <tr>
  142. <th>Право</th>
  143. <th style="width:260px" class="text-center">Override</th>
  144. </tr>
  145. </thead>
  146. <tbody>
  147. @foreach($groupPerms as $key => $label)
  148. <tr>
  149. <td>
  150. {{ $label }}
  151. <div><code style="font-size:10px">{{ $key }}</code></div>
  152. </td>
  153. <td class="text-center">
  154. <div class="d-flex justify-content-center" style="gap:6px">
  155. <label class="mb-0">
  156. <input type="radio" name="permissions[{{ $key }}]" value="allow"
  157. {{ old('permissions.'.$key) === 'allow' ? 'checked' : '' }}>
  158. <span class="badge badge-success ml-1">Allow</span>
  159. </label>
  160. <label class="mb-0">
  161. <input type="radio" name="permissions[{{ $key }}]" value="deny"
  162. {{ old('permissions.'.$key) === 'deny' ? 'checked' : '' }}>
  163. <span class="badge badge-danger ml-1">Deny</span>
  164. </label>
  165. <label class="mb-0">
  166. <input type="radio" name="permissions[{{ $key }}]" value=""
  167. {{ ! old('permissions.'.$key) ? 'checked' : '' }}>
  168. <span class="badge badge-secondary ml-1">Роль</span>
  169. </label>
  170. </div>
  171. </td>
  172. </tr>
  173. @endforeach
  174. </tbody>
  175. </table>
  176. @endforeach
  177. </div>
  178. </div>
  179. </div>
  180. </div>
  181. </form>
  182. @stop