Commit 6e22552141ffa77e3595cad46f3d68b060130c51

Authored by Андрей Ларионов
1 parent f8a3cafe55

Работа над сообщениями и диалогами

Showing 13 changed files with 343 additions and 49 deletions Side-by-side Diff

app/Http/Controllers/EmployerController.php
... ... @@ -4,6 +4,8 @@ namespace App\Http\Controllers;
4 4  
5 5 use App\Classes\RusDate;
6 6 use App\Classes\Tools;
  7 +use App\Http\Requests\BaseUser_min_Request;
  8 +use App\Http\Requests\BaseUserRequest;
7 9 use App\Http\Requests\FlotRequest;
8 10 use App\Http\Requests\MessagesRequiest;
9 11 use App\Http\Requests\VacancyRequestEdit;
... ... @@ -66,6 +68,22 @@ class EmployerController extends Controller
66 68 ->with('success', 'Вы вышли из личного кабинета');
67 69 }
68 70  
  71 + public function employer_info() {
  72 + // код юзера
  73 + $user_info = Auth()->user();
  74 + // вьюшка для вывода данных
  75 + return view('employers.info', compact('user_info'));
  76 + }
  77 +
  78 + public function employer_info_save(User_Model $user, BaseUser_min_Request $request) {
  79 + // Все данные через реквест
  80 + $all = $request->all();
  81 + unset($all['_token']);
  82 + // обновление
  83 + $user->update($all);
  84 + return redirect()->route('employer.employer_info');
  85 + }
  86 +
69 87 public function cabinet() {
70 88 $id = Auth()->user()->id;
71 89 $Employer = Employer::query()->with('users')->with('ads')->with('flots')->
... ... @@ -300,48 +318,49 @@ class EmployerController extends Controller
300 318 $count_output = $messages_output->count();
301 319  
302 320 if ($type_message == 'input') {
303   - $messages = $messages_input->paginate(15);
  321 + $messages = $messages_input->paginate(5);
304 322 }
305 323  
306 324 if ($type_message == 'output') {
307   - $messages = $messages_output->paginate(15);
  325 + $messages = $messages_output->paginate(5);
308 326 }
309 327  
  328 + //dd($user_id, $messages[2]->vacancies);
  329 + //jobs);
  330 +
310 331 return view('employers.messages', compact('messages', 'count_input', 'count_output', 'type_message', 'user_id'));
311 332 }
312 333  
313 334 // Диалог между пользователями
314   - public function dialog(User_Model $user1, User_Model $user2) {
  335 + public function dialog(Request $request, User_Model $user1, User_Model $user2) {
  336 + // Получение параметров.
  337 + if ($request->has('ad_employer')){
  338 + $ad_employer = $request->get('ad_employer');
  339 + } else {
  340 + $ad_employer = 0;
  341 + }
  342 +
315 343 if (isset($user2->id)) {
316 344 $companion = User_Model::query()->with('workers')->
317 345 with('employers')->
318 346 where('id', $user2->id)->first();
319 347 }
320 348  
321   - $Messages = Message::query()->with('response')->where(function($query) use ($user1, $user2) {
  349 + $Messages = Message::query()->
  350 + where('ad_employer_id', '=', $ad_employer)->
  351 + where(function($query) use ($user1, $user2) {
322 352 $query->where('user_id', $user1->id)->where('to_user_id', $user2->id);
323 353 })->orWhere(function($query) use ($user1, $user2) {
324 354 $query->where('user_id', $user2->id)->where('to_user_id', $user1->id);
325   - })->OrderBy('created_at')->get();
  355 + })->where('ad_employer_id', '=', $ad_employer)->OrderBy('created_at')->get();
326 356  
327 357 $id_vac = $Messages[$Messages->count() - 1]->ad_employer_id;
328   - /*foreach ($Messages as $it) {
329   - if (isset($it->response)) {
330   - foreach ($it->response as $r) {
331   - if (isset($r->ad_employer_id)) {
332   - $id_vac = $r->ad_employer_id;
333   - break;
334   - }
335   - }
336   - }
337   - if (!is_null($id_vac)) break;
338   - }
339   - */
340 358  
341   - $ad_employer = null;
342   - if (!is_null($id_vac)) $ad_employer = Ad_employer::query()->where('id', $id_vac)->first();
  359 + //$ad_employer = null;
  360 + //if (!is_null($id_vac)) $ad_employer = Ad_employer::query()->where('id', $id_vac)->first();
343 361 $sender = $user1;
344   - return view('employers.dialog', compact('companion', 'sender', 'Messages', 'ad_employer'));
  362 +
  363 + return view('employers.dialog', compact('companion', 'sender', 'ad_employer', 'Messages'));
345 364 }
346 365  
347 366 // Регистрация работодателя
app/Http/Controllers/MainController.php
... ... @@ -350,13 +350,13 @@ class MainController extends Controller
350 350 'file' => 'Файл «:attribute» должен быть не больше :max Кбайт'
351 351 ],
352 352 ];
353   -
354 353 $validator = Validator::make($request->all(), $rules, $messages);
355   -
356   -
357 354 if ($validator->fails()) {
358   - return json_encode(Array("ERROR" => "Email или пароль невалидный!"));
359   - //redirect()->route('index')->with('Error', "Email или пароль невалидный");
  355 + $user_id = $request->user()->id;
  356 + if ($user_id > 0)
  357 + return json_encode(Array("ERROR" => "Email или пароль невалидный!"));
  358 + else
  359 + return redirect()->route('index')->with('Error', "Email или пароль невалидный");
360 360 } else {
361 361 $credentials = $request->only('email', 'password');
362 362  
app/Http/Controllers/WorkerController.php
... ... @@ -373,12 +373,13 @@ class WorkerController extends Controller
373 373 $count_output = $messages_output->count();
374 374  
375 375 if ($type_message == 'input') {
376   - $messages = $messages_input->paginate(15);
  376 + $messages = $messages_input->paginate(5);
377 377 }
378 378  
379 379 if ($type_message == 'output') {
380   - $messages = $messages_output->paginate(15);
  380 + $messages = $messages_output->paginate(5);
381 381 }
  382 +
382 383 // Вернуть все 100%
383 384 return view('workers.messages', compact('messages', 'count_input', 'count_output', 'type_message', 'user_id'));
384 385 }
app/Http/Requests/BaseUser_min_Request.php
... ... @@ -0,0 +1,49 @@
  1 +<?php
  2 +
  3 +namespace App\Http\Requests;
  4 +
  5 +use Illuminate\Foundation\Http\FormRequest;
  6 +
  7 +class BaseUser_min_Request extends FormRequest
  8 +{
  9 + /**
  10 + * Determine if the user is authorized to make this request.
  11 + *
  12 + * @return bool
  13 + */
  14 + public function authorize()
  15 + {
  16 + return true;
  17 + }
  18 +
  19 + /**
  20 + * Get the validation rules that apply to the request.
  21 + *
  22 + * @return array<string, mixed>
  23 + */
  24 + public function rules()
  25 + {
  26 + return [
  27 + //'name' => 'required|min:3|max:255',
  28 + 'surname' => 'required|min:3|max:255',
  29 + 'name_man' => 'required|min:3|max:255',
  30 + ];
  31 + }
  32 +
  33 + public function messages() {
  34 + return [
  35 + 'required' => 'Поле :attribute обязательно для ввода',
  36 + 'min' => [
  37 + 'string' => 'Поле «:attribute» должно быть не меньше :min символов',
  38 + 'file' => 'Файл «:attribute» должен быть не меньше :min Кбайт'
  39 + ],
  40 + 'max' => [
  41 + 'string' => 'Поле «:attribute» должно быть не больше :max символов',
  42 + 'file' => 'Файл «:attribute» должен быть не больше :max Кбайт'
  43 + ],
  44 + 'email' => 'Введите корректный емайл',
  45 + 'unique' => 'Емайл должен быть уникальным',
  46 +
  47 + ];
  48 + }
  49 +}
app/Models/Message.php
... ... @@ -34,15 +34,8 @@ class Message extends Model
34 34 return $this->belongsTo(User::class, 'to_user_id');
35 35 }
36 36  
37   - /*
38   - * Связь модели Сообщения (Message) с моделью Отклик на Вакансию (Ad_response)
39   - */
40   - public function response() {
41   - return $this->hasMany(ad_response::class);
42   - }
43   -
44 37 // Связь модели Сообщения (Message) с моделью Вакансии (Ad_employer)
45 38 public function vacancies() {
46   - return $this->belongsToMany(Ad_employer::class, 'ad_responses');
  39 + return $this->belongsTo(Ad_employer::class, 'ad_employer_id', 'id');
47 40 }
48 41 }
database/migrations/2024_04_17_060549_alter_table_messages.php
... ... @@ -0,0 +1,32 @@
  1 +<?php
  2 +
  3 +use Illuminate\Database\Migrations\Migration;
  4 +use Illuminate\Database\Schema\Blueprint;
  5 +use Illuminate\Support\Facades\Schema;
  6 +
  7 +return new class extends Migration
  8 +{
  9 + /**
  10 + * Run the migrations.
  11 + *
  12 + * @return void
  13 + */
  14 + public function up()
  15 + {
  16 + Schema::table('messages', function (Blueprint $table) {
  17 + $table->integer('flag_new_from')->default(1);
  18 + });
  19 + }
  20 +
  21 + /**
  22 + * Reverse the migrations.
  23 + *
  24 + * @return void
  25 + */
  26 + public function down()
  27 + {
  28 + Schema::table('messages', function (Blueprint $table) {
  29 + $table->dropColumn('flag_new_from');
  30 + });
  31 + }
  32 +};
resources/views/employers/cabinet45.blade.php
... ... @@ -141,6 +141,43 @@
141 141 @enderror
142 142 </div>
143 143 </div>
  144 +
  145 + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group">
  146 + <label class="form-group__label">Ссылка на сайт</label>
  147 + <div class="form-group__item">
  148 + <input type="url" name="site" class="input" value="{{ old('site') ?? $Employer[0]->site ?? '' }}" placeholder="https://rekamore.su" required>
  149 + @error('site')
  150 + <span class="text-xs text-red-600">
  151 + {{ $message }}
  152 + </span>
  153 + @enderror
  154 + </div>
  155 + </div>
  156 +
  157 + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group">
  158 + <label class="form-group__label">Ссылка на сайт</label>
  159 + <div class="form-group__item">
  160 + <input type="url" name="site" class="input" value="{{ old('site') ?? $Employer[0]->site ?? '' }}" placeholder="https://rekamore.su" required>
  161 + @error('site')
  162 + <span class="text-xs text-red-600">
  163 + {{ $message }}
  164 + </span>
  165 + @enderror
  166 + </div>
  167 + </div>
  168 +
  169 + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group">
  170 + <label class="form-group__label">Ссылка на сайт</label>
  171 + <div class="form-group__item">
  172 + <input type="url" name="site" class="input" value="{{ old('site') ?? $Employer[0]->site ?? '' }}" placeholder="https://rekamore.su" required>
  173 + @error('site')
  174 + <span class="text-xs text-red-600">
  175 + {{ $message }}
  176 + </span>
  177 + @enderror
  178 + </div>
  179 + </div>
  180 +
144 181 <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group">
145 182 <label class="form-group__label">О компании</label>
146 183 <div class="form-group__item">
resources/views/employers/dialog.blade.php
... ... @@ -57,9 +57,9 @@
57 57 </ul>
58 58 <div class="cabinet__wrapper">
59 59 <div class="cabinet__side">
60   -
  60 + <div class="cabinet__side-toper">
61 61 @include('employers.emblema')
62   -
  62 + </div>
63 63 @include('employers.menu', ['item' => 5])
64 64 </div>
65 65 <div class="cabinet__body">
... ... @@ -87,7 +87,15 @@
87 87 </div>
88 88 <div class="messages__item-text">
89 89 <div>{{ $companion->surname." ".$companion->name_man." ".$companion->surname2." (".$companion->id.")" }} </div>
90   - <div><span>Вакансия:</span> @if (!is_null($ad_employer)) <a href="{{ route('vacancie', ['vacancy' => $ad_employer->id]) }}">{{ $ad_employer->name}}</a> @else Не указано @endif</div>
  90 + <div><span>Вакансия:</span>
  91 + @if ($ad_employer == 0)
  92 + @if (isset($_GET['ad_name'])){{ $_GET['ad_name'] }}@else Не указано @endif
  93 + @else
  94 + <a href="{{ route('vacancie', ['vacancy' => $ad_employer]) }}">
  95 + @if (isset($_GET['ad_name'])){{ $_GET['ad_name'] }} ({{ $ad_employer }}) @else Не указано @endif
  96 + </a>
  97 + @endif
  98 + </div>
91 99 </div>
92 100 </div>
93 101 @if (isset($companion->worker->id))
resources/views/employers/info.blade.php
... ... @@ -0,0 +1,98 @@
  1 +@extends('layout.frontend', ['title' => 'Кабинет работодателя - РекаМоре'])
  2 +
  3 +@section('scripts')
  4 + <script src="https://cdn.ckeditor.com/ckeditor5/23.0.0/classic/ckeditor.js"></script>
  5 + <script>
  6 + ClassicEditor
  7 + .create( document.querySelector( '#text' ) )
  8 + .catch( error => {
  9 + console.error( error );
  10 + } );
  11 + </script>
  12 +@endsection
  13 +@section('content')
  14 + <section class="cabinet">
  15 + <div class="container">
  16 + <ul class="breadcrumbs cabinet__breadcrumbs">
  17 + <li><a href="{{ route('index') }}">Главная</a></li>
  18 + <li><b>Личный кабинет</b></li>
  19 + </ul>
  20 + <div class="cabinet__wrapper">
  21 + <div class="cabinet__side">
  22 + <div class="cabinet__side-toper">
  23 + @include('employers.emblema')
  24 + </div>
  25 + @include('employers.menu', ['item' => 0])
  26 + </div>
  27 + <div class="cabinet__body">
  28 + @include('messages_error')
  29 +
  30 + <form action="{{ route('employer.employer_info_save', ['user' => $user_info->id]) }}" method="POST" enctype="multipart/form-data">
  31 + @csrf
  32 + <div class="cabinet__body-item">
  33 + <div class="cabinet__descr">
  34 + <h2 class="title cabinet__title">Личные данные</h2>
  35 + <p class="cabinet__text">Все поля обязательны для заполнения *</p>
  36 + </div>
  37 +
  38 + <div class="cabinet__inputs">
  39 + <div class="cabinet__inputs-item form-group">
  40 + <label class="form-group__label">Фамилия контактера</label>
  41 + <div class="form-group__item">
  42 + <input type="text" class="input" name="surname" id="surname" placeholder="Иванов" value="{{ old('surname') ?? $user_info->surname ?? '' }}" required>
  43 + @error('surname')
  44 + <span class="text-xs text-red-600">
  45 + {{ $message }}
  46 + </span>
  47 + @enderror
  48 + </div>
  49 + </div>
  50 + <div class="cabinet__inputs-item form-group">
  51 + <label class="form-group__label">Имя контактера</label>
  52 + <div class="form-group__item">
  53 + <input type="text" name="name_man" class="input" placeholder="Андрей" value="{{ old('name_man') ?? $user_info->name_man ?? '' }}" required>
  54 + @error('name_man')
  55 + <span class="text-xs text-red-600">
  56 + {{ $message }}
  57 + </span>
  58 + @enderror
  59 + </div>
  60 + </div>
  61 +
  62 + <div class="cabinet__inputs-item form-group">
  63 + <label class="form-group__label">Отчество контактера</label>
  64 + <div class="form-group__item">
  65 + <input type="text" name="surname2" class="input" placeholder="Васильевич" value="{{ old('surname2') ?? $user_info->surname2 ?? '' }}">
  66 + @error('surname2')
  67 + <span class="text-xs text-red-600">
  68 + {{ $message }}
  69 + </span>
  70 + @enderror
  71 + </div>
  72 + </div>
  73 +
  74 + <div class="cabinet__inputs-item form-group">
  75 + <label class="form-group__label">Номер телефона</label>
  76 + <div class="form-group__item">
  77 + <input type="tel" name="telephone" class="input" placeholder="+7 (___) ___-__-__" value="{{ old('telephone') ?? $user_info->telephone ?? '' }}" required>
  78 + @error('telephone')
  79 + <span class="text-xs text-red-600">
  80 + {{ $message }}
  81 + </span>
  82 + @enderror
  83 + </div>
  84 + </div>
  85 +
  86 + </div>
  87 + </div><br>
  88 + <button type="submit" class="button cabinet__submit">Сохранить изменения</button>
  89 + </form>
  90 +
  91 + </div>
  92 + </div>
  93 + </div>
  94 +
  95 + </section>
  96 +</div>
  97 + <!-- END TOP WRAPPER -->
  98 +@endsection
resources/views/employers/menu.blade.php
... ... @@ -17,6 +17,14 @@
17 17 </button>
18 18 <div class="cabinet__menu-body">
19 19 <div class="cabinet__menu-items">
  20 + <a href="{{ route('employer.employer_info') }}" class="cabinet__menu-item @if ($item==0) active @endif">
  21 + <i>
  22 + <svg>
  23 + <use xlink:href="{{ asset('images/sprite.svg#cabinet-1') }}"></use>
  24 + </svg>
  25 + </i>
  26 + <span>Личные данные</span>
  27 + </a>
20 28 <a href="{{ route('employer.cabinet') }}" class="cabinet__menu-item @if ($item==1) active @endif">
21 29 <i>
22 30 <svg>
resources/views/employers/messages.blade.php
... ... @@ -139,9 +139,9 @@
139 139 <div>
140 140 От: @if (isset($it->user_from))
141 141 @if ($it->user_from->id !== $user_id)
142   - <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_from->id]) }}" style="text-decoration: underline">
  142 + <!--<a href=" route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_from->id]) }}" style="text-decoration: underline">-->
143 143 {{ $it->user_from->surname." ".$it->user_from->name_man." ".$it->user_from->surname2." (".$it->user_from->id.")" }}
144   - </a>
  144 + <!--</a>-->
145 145 @else
146 146 {{ $it->user_from->surname." ".$it->user_from->name_man." ".$it->user_from->surname2." (".$it->user_from->id.")" }}
147 147 @endif
... ... @@ -151,9 +151,9 @@
151 151 <br>
152 152 К: @if (isset($it->user_to))
153 153 @if ($it->user_to->id !== $user_id)
154   - <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_to->id]) }}" style="text-decoration: underline">
  154 + <!--<a href=" route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_to->id]) }}" style="text-decoration: underline">-->
155 155 {{ $it->user_to->surname." ".$it->user_to->name_man." ".$it->user_to->surname2." (".$it->user_to->id.")" }}
156   - </a>
  156 + <!--</a>-->
157 157 @else
158 158 {{ $it->user_to->surname." ".$it->user_to->name_man." ".$it->user_to->surname2." (".$it->user_to->id.")" }}
159 159 @endif
... ... @@ -161,13 +161,58 @@
161 161 Удаленный пользователь
162 162 @endif
163 163 </div>
164   - <div><span>Вакансия: {{ $it->ad_employer_id }}</span>@if (isset($it->vacancies[0])) {{ $it->vacancies[0]->name." (".($it->vacancies[0]->id).")" }} @else Удалена @endif</div>
  164 + <div>
  165 + <span>Вакансия: </span>
  166 + @if (isset($it->user_from))
  167 + @if ($it->user_from->id !== $user_id)
  168 + @if (isset($it->vacancies))
  169 + <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_from->id, 'ad_employer' => $it->vacancies->id, 'ad_name' => $it->vacancies->name ]) }}" style="text-decoration: underline">
  170 + {{ $it->vacancies->name." (".($it->vacancies->id).")" }}
  171 + </a>
  172 + @else
  173 + <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_from->id, 'ad_employer' => 0, 'ad_name' => 'Не указана вакансия' ]) }}" style="text-decoration: underline">
  174 + Вакансия не указана
  175 + </a>
  176 + @endif
  177 + @else
  178 +
  179 + @endif
  180 + @endif
  181 +
  182 + @if (isset($it->user_to))
  183 + @if ($it->user_to->id !== $user_id)
  184 + @if (isset($it->vacancies))
  185 + <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_to->id, 'ad_employer' => $it->vacancies->id, 'ad_name' => $it->vacancies->name ]) }}" style="text-decoration: underline">
  186 + {{ $it->vacancies->name." (".($it->vacancies->id).")" }}
  187 + </a>
  188 + @else
  189 + <a href="{{ route('employer.dialog', ['user1' => $user_id, 'user2' => $it->user_to->id, 'ad_employer' => 0, 'ad_name' => 'Не указана вакансия' ]) }}" style="text-decoration: underline">
  190 + Вакансия не указана
  191 + </a>
  192 + @endif
  193 + @else
  194 +
  195 + @endif
  196 + @endif
  197 +
  198 + </div>
165 199 <div><span>Текст:</span>{{ $it->text }}</div>
166 200 </div>
167 201 </div>
  202 +
168 203 <div class="messages__item-date">{{ $it->created_at }}</div>
169 204 </div>
170 205 @endforeach
  206 + <div style="margin-top: 20px">
  207 + {{ $messages->onEachSide(0)->appends($_GET)->links('paginate') }}
  208 + </div><!-- конец -->
  209 + @else
  210 + <div class="notify">
  211 + <svg>
  212 + <use xlink:href="{{ asset('images/sprite.svg#i') }}"></use>
  213 + </svg>
  214 + <span>Сообщений не найдено</span>
  215 + </div>
171 216 @endif
172 217 </div>
173 218 </div>
resources/views/workers/messages.blade.php
... ... @@ -119,10 +119,15 @@
119 119 <div class="messages__item-date">{{ $it->created_at }}</div>
120 120 </div>
121 121 @endforeach
  122 +
  123 + <div style="margin-top: 20px">
  124 + {{ $messages->onEachSide(0)->appends($_GET)->links('paginate') }}
  125 + </div><!-- конец -->
  126 +
122 127 @else
123 128 <div class="notify">
124 129 <svg>
125   - <use xlink:href="images/sprite.svg#i"></use>
  130 + <use xlink:href="{{ asset('images/sprite.svg#i') }}"></use>
126 131 </svg>
127 132 <span>Сообщений не найдено</span>
128 133 </div>
... ... @@ -480,9 +480,6 @@ Route::get(&#39;cookies&#39;, function() {
480 480 return view('cookies');
481 481 })->name('cookies');
482 482  
483   -
484   -
485   -
486 483 // Личный кабинет работник
487 484 Route::group([
488 485 'as' => 'worker.', // имя маршрута, например auth.index
... ... @@ -549,6 +546,10 @@ Route::group([
549 546 'prefix' => 'employer', // префикс маршрута, например auth/index
550 547 'middleware' => ['auth'], !['is_worker'],
551 548 ], function() {
  549 + // 0 страница - Личные данные работодателя
  550 + Route::get('cabinet/employer_info', [EmployerController::class, 'employer_info'])->name('employer_info');
  551 + Route::post('cabinet/employer_info/{user}', [EmployerController::class, 'employer_info_save'])->name('employer_info_save');
  552 +
552 553 // 1 страница - Профиль
553 554 Route::get('cabinet', [EmployerController::class, 'cabinet'])->name('cabinet');
554 555 Route::post('cabinet/{Employer}', [EmployerController::class, 'cabinet_save'])->name('cabinet_save');
... ... @@ -560,10 +561,8 @@ Route::group([
560 561 Route::get('cabinet/vacancie', [EmployerController::class, 'cabinet_vacancie'])->name('cabinet_vacancie');
561 562 Route::post('vacancie', [EmployerController::class, 'cabinet_vacancy_save1'])->name('vac_save');
562 563  
563   -
564 564 Route::get('selected_people', [EmployerController::class, 'selected_people'])->name('selected_people');
565 565  
566   -
567 566 // 3 страница - Мои вакансии
568 567 Route::get('cabinet/vacancy_list', [EmployerController::class, 'vacancy_list'])->name('vacancy_list');
569 568 Route::get('cabinet/vacancy/{ad_employer}', [EmployerController::class, 'vacancy_edit'])->name('vacancy_edit');