Commit e688e0d8a7d49fac8e7ccc049f8fbf65b395dc67
1 parent
90302d3663
Exists in
master
and in
1 other branch
Статистика работников и вакансий, сообщения от администратора
Showing 16 changed files with 750 additions and 8 deletions Side-by-side Diff
- app/Http/Controllers/Admin/EmployersController.php
- app/Http/Controllers/Admin/MsgAnswersController.php
- app/Http/Controllers/Admin/WorkersController.php
- app/Models/Message.php
- app/Models/Static_ad.php
- app/Models/Static_worker.php
- database/migrations/2023_09_15_070116_alter_static_workers_table.php
- database/migrations/2023_09_15_070215_alter_static_ads_table.php
- database/migrations/2023_09_15_071013_alter_messages_table.php
- resources/views/admin/message/index.blade.php
- resources/views/admin/static/index_ads.blade.php
- resources/views/admin/static/index_ads_ajax.blade.php
- resources/views/admin/static/index_workers.blade.php
- resources/views/admin/static/index_workers_ajax.blade.php
- resources/views/layout/admin.blade.php
- routes/web.php
app/Http/Controllers/Admin/EmployersController.php
... | ... | @@ -3,8 +3,10 @@ |
3 | 3 | namespace App\Http\Controllers\Admin; |
4 | 4 | |
5 | 5 | use App\Http\Controllers\Controller; |
6 | +use App\Models\Ad_employer; | |
6 | 7 | use App\Models\Answer; |
7 | 8 | use App\Models\Employer; |
9 | +use App\Models\Static_ad; | |
8 | 10 | use App\Models\User; |
9 | 11 | use Illuminate\Http\Request; |
10 | 12 | use Illuminate\Support\Facades\Storage; |
... | ... | @@ -107,8 +109,28 @@ class EmployersController extends Controller |
107 | 109 | } |
108 | 110 | |
109 | 111 | // кабинет - статистика вакансий работодателя |
110 | - public function static_ads() { | |
111 | - return; | |
112 | + public function static_ads(Request $request) { | |
113 | + $stat = Static_ad::with('ads'); | |
114 | + $ads = Ad_employer::query()->active()->OrderBy('id')->get(); | |
115 | + $periods = Static_ad::query()->distinct('year_month')->select('year_month')->get(); | |
116 | + if ($request->ajax()) { | |
117 | + if (isset($request->ad_employer_id)) | |
118 | + if (!$request->ad_employer_id == "0") | |
119 | + $stat = $stat->Where('ad_employer_id', '=', $request->ad_employer_id); | |
120 | + if (isset($request->year_month)) { | |
121 | + if (!$request->year_month == "0") | |
122 | + $stat = $stat->Where('year_month', '=', $request->year_month); | |
123 | + } | |
124 | + } | |
125 | + | |
126 | + $stat = $stat->OrderByDesc('year_month'); | |
127 | + $stat = $stat->paginate(15); | |
128 | + | |
129 | + if ($request->ajax()) | |
130 | + return view('admin.static.index_ads_ajax', compact('stat')); | |
131 | + else | |
132 | + return view('admin.static.index_ads', compact('stat', 'ads', 'periods')); | |
133 | + | |
112 | 134 | } |
113 | 135 | |
114 | 136 |
app/Http/Controllers/Admin/MsgAnswersController.php
... | ... | @@ -4,7 +4,10 @@ namespace App\Http\Controllers\Admin; |
4 | 4 | |
5 | 5 | use App\Http\Controllers\Controller; |
6 | 6 | use App\Models\Message; |
7 | +use App\Models\User; | |
7 | 8 | use Illuminate\Http\Request; |
9 | +use Illuminate\Support\Facades\Auth; | |
10 | +use Illuminate\Support\Facades\Validator; | |
8 | 11 | |
9 | 12 | class MsgAnswersController extends Controller |
10 | 13 | { |
... | ... | @@ -13,4 +16,40 @@ class MsgAnswersController extends Controller |
13 | 16 | |
14 | 17 | return view('admin.messages', compact('Msgs')); |
15 | 18 | } |
19 | + | |
20 | + public function admin_messages(Request $request) { | |
21 | + $id_admin = Auth::user()->id; | |
22 | + $users = User::query()->OrderBy('name')->get(); | |
23 | + | |
24 | + $Msgs = Message::query()->where('user_id', '=', $id_admin) | |
25 | + ->orWhere('to_user_id', '=', $id_admin) | |
26 | + ->orderByDesc('created_at')->paginate(5); | |
27 | + | |
28 | + return view('admin.message.index', compact('Msgs', 'id_admin', 'users')); | |
29 | + } | |
30 | + | |
31 | + public function admin_messages_post(Request $request) { | |
32 | + $rules = [ | |
33 | + 'title' => 'required|min:3|max:255', | |
34 | + 'text' => 'required|min:1' | |
35 | + ]; | |
36 | + | |
37 | + $messages = [ | |
38 | + 'required' => 'Поле не может быть пустым!', | |
39 | + ]; | |
40 | + | |
41 | + $validator = Validator::make($request->all(), $rules, $messages); | |
42 | + | |
43 | + if ($validator->fails()) { | |
44 | + return redirect()->route('admin.admin-messages')->withErrors($validator); | |
45 | + } else { | |
46 | + $params = $request->all(); | |
47 | + $id_admin = Auth::user()->id; | |
48 | + if ($request->has('file')) { | |
49 | + $params['file'] = $request->file('file')->store("upload/".$id_admin, 'public'); | |
50 | + } | |
51 | + Message::create($params); | |
52 | + return redirect()->route('admin.admin-messages'); | |
53 | + } | |
54 | + } | |
16 | 55 | } |
app/Http/Controllers/Admin/WorkersController.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | namespace App\Http\Controllers\Admin; |
4 | 4 | |
5 | 5 | use App\Http\Controllers\Controller; |
6 | +use App\Models\Static_worker; | |
6 | 7 | use App\Models\User; |
7 | 8 | use App\Models\Worker; |
8 | 9 | use Illuminate\Http\Request; |
... | ... | @@ -30,8 +31,35 @@ class WorkersController extends Controller |
30 | 31 | } |
31 | 32 | |
32 | 33 | // кабинет - статистика работников |
33 | - public function static_workers() { | |
34 | - return; | |
34 | + public function static_workers(Request $request) { | |
35 | + $stat = Static_worker::with('users'); | |
36 | + //->join('users', 'users.id', '=', 'static_workers.user_id'); | |
37 | + $users = User::query()->active()->OrderBy('id')->get(); | |
38 | + $periods = Static_worker::query()->distinct('year_month')->select('year_month')->get(); | |
39 | + if ($request->ajax()) { | |
40 | + if (isset($request->user_id)) | |
41 | + if (!$request->user_id == "0") | |
42 | + $stat = $stat->Where('user_id', '=', $request->user_id); | |
43 | + if (isset($request->year_month)) { | |
44 | + if (!$request->year_month == "0") | |
45 | + $stat = $stat->Where('year_month', '=', $request->year_month); | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + $stat = $stat->OrderByDesc('year_month'); | |
50 | + //->OrderBy('users.name'); | |
51 | + //OrderBy('users.name')-> | |
52 | + /*$stat->implode() loadMissing(['users' => function (Builder $query) { | |
53 | + $query->orderBy('name', 'asc'); | |
54 | + }]);*/ | |
55 | + | |
56 | + $stat = $stat->paginate(15); | |
57 | + | |
58 | + if ($request->ajax()) | |
59 | + return view('admin.static.index_workers_ajax', compact('stat')); | |
60 | + else | |
61 | + return view('admin.static.index_workers', compact('stat', 'users', 'periods')); | |
62 | + | |
35 | 63 | } |
36 | 64 | |
37 | 65 | } |
app/Models/Message.php
app/Models/Static_ad.php
... | ... | @@ -8,4 +8,21 @@ use Illuminate\Database\Eloquent\Model; |
8 | 8 | class Static_ad extends Model |
9 | 9 | { |
10 | 10 | use HasFactory; |
11 | + | |
12 | + protected $fillable = [ | |
13 | + 'ad_employer_id', | |
14 | + 'lookin', | |
15 | + 'year_month', | |
16 | + 'message', | |
17 | + 'old_lookin', | |
18 | + 'old_message' | |
19 | + ]; | |
20 | + | |
21 | + /* | |
22 | + * Связь таблицы ad_employers с таблицей static_ads | |
23 | + многие-к-одному | |
24 | + */ | |
25 | + public function ads() { | |
26 | + return $this->belongsTo(Ad_employer::class, 'ad_employer_id'); | |
27 | + } | |
11 | 28 | } |
app/Models/Static_worker.php
... | ... | @@ -8,4 +8,22 @@ use Illuminate\Database\Eloquent\Model; |
8 | 8 | class Static_worker extends Model |
9 | 9 | { |
10 | 10 | use HasFactory; |
11 | + | |
12 | + protected $fillable = [ | |
13 | + 'user_id', | |
14 | + 'lookin', | |
15 | + 'year_month', | |
16 | + 'message', | |
17 | + 'old_lookin', | |
18 | + 'old_message' | |
19 | + ]; | |
20 | + | |
21 | + /* | |
22 | + * Связь таблицы users с таблицей static_workers | |
23 | + многие-к-одному | |
24 | + */ | |
25 | + public function users() { | |
26 | + return $this->belongsTo(User::class, 'user_id'); | |
27 | + } | |
28 | + | |
11 | 29 | } |
database/migrations/2023_09_15_070116_alter_static_workers_table.php
... | ... | @@ -0,0 +1,34 @@ |
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('static_workers', function (Blueprint $table) { | |
17 | + $table->integer('old_lookin')->default(0); | |
18 | + $table->integer('old_message')->default(0); | |
19 | + }); | |
20 | + } | |
21 | + | |
22 | + /** | |
23 | + * Reverse the migrations. | |
24 | + * | |
25 | + * @return void | |
26 | + */ | |
27 | + public function down() | |
28 | + { | |
29 | + Schema::table('static_workers', function (Blueprint $table) { | |
30 | + $table->dropColumn('old_lookin'); | |
31 | + $table->dropColumn('old_message'); | |
32 | + }); | |
33 | + } | |
34 | +}; |
database/migrations/2023_09_15_070215_alter_static_ads_table.php
... | ... | @@ -0,0 +1,34 @@ |
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('static_ads', function (Blueprint $table) { | |
17 | + $table->integer('old_lookin')->default(0); | |
18 | + $table->integer('old_message')->default(0); | |
19 | + }); | |
20 | + } | |
21 | + | |
22 | + /** | |
23 | + * Reverse the migrations. | |
24 | + * | |
25 | + * @return void | |
26 | + */ | |
27 | + public function down() | |
28 | + { | |
29 | + Schema::table('static_ads', function (Blueprint $table) { | |
30 | + $table->dropColumn('old_lookin'); | |
31 | + $table->dropColumn('old_message'); | |
32 | + }); | |
33 | + } | |
34 | +}; |
database/migrations/2023_09_15_071013_alter_messages_table.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->boolean('flag_new')->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'); | |
30 | + }); | |
31 | + } | |
32 | +}; |
resources/views/admin/message/index.blade.php
... | ... | @@ -0,0 +1,149 @@ |
1 | +@extends('layout.admin', ['title' => 'Админка - Сообщения адмистратора']) | |
2 | + | |
3 | +@section('script') | |
4 | +@endsection | |
5 | + | |
6 | +@section('search') | |
7 | + <!--<div class="absolute inset-y-0 flex items-center pl-2"> | |
8 | + <svg | |
9 | + class="w-4 h-4" | |
10 | + aria-hidden="true" | |
11 | + fill="currentColor" | |
12 | + viewBox="0 0 20 20" | |
13 | + > | |
14 | + <path | |
15 | + fill-rule="evenodd" | |
16 | + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" | |
17 | + clip-rule="evenodd" | |
18 | + ></path> | |
19 | + </svg> | |
20 | + </div> | |
21 | + <form action="" method="POST"> | |
22 | + <div style="float:left;"><input | |
23 | + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" | |
24 | + style="width: 400px" | |
25 | + type="text" | |
26 | + placeholder="Искать компанию или вакансию" | |
27 | + aria-label="Search" | |
28 | + /></div> | |
29 | + <div style="float: left"> | |
30 | + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Поиск</button> | |
31 | + </div> | |
32 | + </form>--> | |
33 | +@endsection | |
34 | + | |
35 | +@section('content') | |
36 | + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> | |
37 | + <div class="w-full overflow-x-auto"> | |
38 | + <table class="w-full whitespace-no-wrap"> | |
39 | + <thead> | |
40 | + <tr | |
41 | + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" | |
42 | + > | |
43 | + <th class="px-4 py-3">№</th> | |
44 | + <th class="px-4 py-3">От юзера</th> | |
45 | + <th class="px-4 py-3">К юзеру</th> | |
46 | + <th class="px-4 py-3">Текст</th> | |
47 | + <th class="px-4 py-3">Дата</th> | |
48 | + </tr> | |
49 | + </thead> | |
50 | + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> | |
51 | + @foreach($Msgs as $msg) | |
52 | + <tr class="text-gray-700 dark:text-gray-400"> | |
53 | + <td class="px-4 py-3"> | |
54 | + {{$msg->id}} | |
55 | + </td> | |
56 | + <td class="px-4 py-3"> | |
57 | + {{$msg->user_from->name}} ({{$msg->user_from->id}}) | |
58 | + </td> | |
59 | + <td class="px-4 py-3"> | |
60 | + {{$msg->user_to->name}} ({{$msg->user_to->id}}) | |
61 | + </td> | |
62 | + <td class="px-4 py-3"> | |
63 | + {{$msg->title}} | |
64 | + <div class="flex items-center text-sm"> | |
65 | + <textarea cols="7" style="width:250px;">{{ $msg->text }}</textarea> | |
66 | + </div> | |
67 | + </td> | |
68 | + <td class="px-4 py-3 text-sm"> | |
69 | + {{ $msg->created_at }} | |
70 | + </td> | |
71 | + </tr> | |
72 | + @endforeach | |
73 | + </tbody> | |
74 | + </table> | |
75 | + </div> | |
76 | + | |
77 | + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> | |
78 | + <?=$Msgs->appends($_GET)->links('admin.pagginate'); ?> | |
79 | + </div> | |
80 | + </div><br> | |
81 | + | |
82 | + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block2"> | |
83 | + | |
84 | + <form method="POST" action="{{ route('admin.admin-messages-post') }}" enctype="multipart/form-data"> | |
85 | + @csrf | |
86 | + <div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800"> | |
87 | + <h3 class="text-gray-700 dark:text-gray-400">Отправка сообщения</h3> | |
88 | + <hr> | |
89 | + <label for="ad_employer_id" class="block text-sm"> | |
90 | + <input type="hidden" name="user_id" id="user_id" value="{{ $id_admin }}"/> | |
91 | + | |
92 | + <span class="text-gray-700 dark:text-gray-400">Кому:</span> | |
93 | + | |
94 | + <select name="to_user_id" id="to_user_id" class="block change_js mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"> | |
95 | + @foreach($users as $user) | |
96 | + <option value="{{ $user->id }}">{{ $user->name }} ({{ $user->id }})</option> | |
97 | + @endforeach | |
98 | + </select> | |
99 | + </label><br> | |
100 | + | |
101 | + <label class="block text-sm"> | |
102 | + <span class="text-gray-700 dark:text-gray-400">Заголовок</span> | |
103 | + <input name="title" id="title" | |
104 | + class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input" | |
105 | + placeholder="Заголовок" value="{{ old('title') ?? '' }}" | |
106 | + /> | |
107 | + @error('title') | |
108 | + <span class="text-xs text-red-600 dark:text-red-400"> | |
109 | + {{ $message }} | |
110 | + </span> | |
111 | + @enderror | |
112 | + </label><br> | |
113 | + | |
114 | + <label class="block text-sm"> | |
115 | + <span class="text-gray-700 dark:text-gray-400">Текст</span> | |
116 | + <textarea class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-textarea focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray" name="text" placeholder="Текст" required | |
117 | + rows="4">{{ old('text') ?? '' }}</textarea> | |
118 | + @error('text') | |
119 | + <span class="text-xs text-red-600 dark:text-red-400"> | |
120 | + {{ $message }} | |
121 | + </span> | |
122 | + @enderror | |
123 | + </label><br> | |
124 | + | |
125 | + | |
126 | + <label class="block text-sm"> | |
127 | + <span class="text-gray-700 dark:text-gray-400">Файл</span> | |
128 | + <input type="file" class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 | |
129 | + focus:border-purple-400 focus:outline-none focus:shadow-outline-purple | |
130 | + dark:text-gray-300 dark:focus:shadow-outline-gray form-input" | |
131 | + id="file" name="file"> | |
132 | + @error('file') | |
133 | + <span class="text-xs text-red-600 dark:text-red-400"> | |
134 | + {{ $message }} | |
135 | + </span> | |
136 | + @enderror | |
137 | + </label><br> | |
138 | + | |
139 | + <div class="flex flex-col flex-wrap mb-4 space-y-4 md:flex-row md:items-end md:space-x-4"> | |
140 | + <div> | |
141 | + <button type="submit" class="px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> | |
142 | + Отправить | |
143 | + </button> | |
144 | + </div> | |
145 | + </div> | |
146 | + </div> | |
147 | + </form> | |
148 | + </div> | |
149 | +@endsection |
resources/views/admin/static/index_ads.blade.php
... | ... | @@ -0,0 +1,131 @@ |
1 | +@extends('layout.admin', ['title' => 'Админка - Вакансии статистика']) | |
2 | + | |
3 | +@section('script') | |
4 | + <script> | |
5 | + $(document).ready(function() { | |
6 | + $(document).on('change', '.change_js', function () { | |
7 | + var ad_employer_id = $('#ad_employer_id'); | |
8 | + var ad_employer_id_value = ad_employer_id.val(); | |
9 | + var year_month = $('#year_month'); | |
10 | + var year_month_value = year_month.val(); | |
11 | + var ajax_block = $('#ajax_block'); | |
12 | + | |
13 | + $.ajax({ | |
14 | + type: "GET", | |
15 | + url: "{{ url()->full()}}", | |
16 | + data: "ad_employer_id=" + ad_employer_id_value + "&year_month=" + year_month_value, | |
17 | + success: function (data) { | |
18 | + console.log('Обновление таблицы резюме '); | |
19 | + //data = JSON.parse(data); | |
20 | + console.log(data); | |
21 | + ajax_block.html(data); | |
22 | + }, | |
23 | + headers: { | |
24 | + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') | |
25 | + }, | |
26 | + error: function (data) { | |
27 | + console.log('Error: ' + data); | |
28 | + } | |
29 | + }); | |
30 | + }); | |
31 | + }); | |
32 | + </script> | |
33 | +@endsection | |
34 | + | |
35 | +@section('search') | |
36 | + <!-- <div class="absolute inset-y-0 flex items-center pl-2"> | |
37 | + <svg | |
38 | + class="w-4 h-4" | |
39 | + aria-hidden="true" | |
40 | + fill="currentColor" | |
41 | + viewBox="0 0 20 20" | |
42 | + > | |
43 | + <path | |
44 | + fill-rule="evenodd" | |
45 | + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" | |
46 | + clip-rule="evenodd" | |
47 | + ></path> | |
48 | + </svg> | |
49 | + </div> | |
50 | + <form action="" method="POST"> | |
51 | + <div style="float:left;"><input | |
52 | + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" | |
53 | + style="width: 400px" | |
54 | + type="text" | |
55 | + placeholder="Искать..." | |
56 | + aria-label="Search" | |
57 | + /></div> | |
58 | + <div style="float: left"> | |
59 | + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Искать</button> | |
60 | + </div> | |
61 | + </form>--> | |
62 | +@endsection | |
63 | + | |
64 | +@section('content') | |
65 | + <div> | |
66 | + <label for="ad_employer_id" class="block text-sm"> | |
67 | + <span class="text-gray-700 dark:text-gray-400">Пользователи</span> | |
68 | + </label> | |
69 | + <select name="ad_employer_id" id="ad_employer_id" class="block change_js mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"> | |
70 | + <option value="0">Все</option> | |
71 | + @foreach($ads as $ad) | |
72 | + <option value="{{ $ad->id }}">{{ $ad->name }} ({{ $ad->id }})</option> | |
73 | + @endforeach | |
74 | + </select> | |
75 | + <label for="year_month" class="block text-sm"> | |
76 | + <span class="text-gray-700 dark:text-gray-400">Периоды</span> | |
77 | + </label> | |
78 | + <select name="year_month" id="year_month" class="block change_js mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"> | |
79 | + <option value="0">Все</option> | |
80 | + @foreach($periods as $period) | |
81 | + <option value="{{ $period->year_month }}">{{ $period->year_month }}</option> | |
82 | + @endforeach | |
83 | + </select><br> | |
84 | + </div> | |
85 | + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> | |
86 | + <div class="w-full overflow-x-auto"> | |
87 | + <table class="w-full whitespace-no-wrap"> | |
88 | + <thead> | |
89 | + <tr | |
90 | + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" | |
91 | + > | |
92 | + <th class="px-4 py-3">№</th> | |
93 | + <th class="px-4 py-3">Вакансия (название/код)</th> | |
94 | + <th class="px-4 py-3">Интервал времени</th> | |
95 | + <th class="px-4 py-3">Просмотры</th> | |
96 | + <th class="px-4 py-3">Сообщения</th> | |
97 | + </tr> | |
98 | + </thead> | |
99 | + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> | |
100 | + | |
101 | + @foreach($stat as $ad) | |
102 | + <tr class="text-gray-700 dark:text-gray-400"> | |
103 | + <td class="px-4 py-3"> | |
104 | + {{$ad->id}} | |
105 | + </td> | |
106 | + <td class="px-4 py-3"> | |
107 | + {{ $ad->ads->name }} ({{ $ad->ad_employer_id }}) | |
108 | + </td> | |
109 | + <td class="px-4 py-3"> | |
110 | + {{ $ad->year_month }} | |
111 | + </td> | |
112 | + <td class="px-4 py-3"> | |
113 | + {{ $ad->lookin }} | |
114 | + </td> | |
115 | + <td class="px-4 py-3"> | |
116 | + {{ $ad->message }} | |
117 | + </td> | |
118 | + </tr> | |
119 | + @endforeach | |
120 | + | |
121 | + </tbody> | |
122 | + </table> | |
123 | + </div> | |
124 | + | |
125 | + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> | |
126 | + <?=$stat->appends($_GET)->links('admin.pagginate'); ?> | |
127 | + </div> | |
128 | + </div> | |
129 | + | |
130 | + | |
131 | +@endsection |
resources/views/admin/static/index_ads_ajax.blade.php
... | ... | @@ -0,0 +1,42 @@ |
1 | +<div class="w-full overflow-x-auto"> | |
2 | + <table class="w-full whitespace-no-wrap"> | |
3 | + <thead> | |
4 | + <tr | |
5 | + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" | |
6 | + > | |
7 | + <th class="px-4 py-3">№</th> | |
8 | + <th class="px-4 py-3">Вакансия (название/код)</th> | |
9 | + <th class="px-4 py-3">Интервал времени</th> | |
10 | + <th class="px-4 py-3">Просмотры</th> | |
11 | + <th class="px-4 py-3">Сообщения</th> | |
12 | + </tr> | |
13 | + </thead> | |
14 | + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> | |
15 | + | |
16 | + @foreach($stat as $ad) | |
17 | + <tr class="text-gray-700 dark:text-gray-400"> | |
18 | + <td class="px-4 py-3"> | |
19 | + {{$ad->id}} | |
20 | + </td> | |
21 | + <td class="px-4 py-3"> | |
22 | + {{ $ad->ads->name }} ({{ $ad->ad_employer_id }}) | |
23 | + </td> | |
24 | + <td class="px-4 py-3"> | |
25 | + {{ $ad->year_month }} | |
26 | + </td> | |
27 | + <td class="px-4 py-3"> | |
28 | + {{ $ad->lookin }} | |
29 | + </td> | |
30 | + <td class="px-4 py-3"> | |
31 | + {{ $ad->message }} | |
32 | + </td> | |
33 | + </tr> | |
34 | + @endforeach | |
35 | + | |
36 | + </tbody> | |
37 | + </table> | |
38 | +</div> | |
39 | + | |
40 | +<div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> | |
41 | + <?=$stat->appends($_GET)->links('admin.pagginate'); ?> | |
42 | +</div> |
resources/views/admin/static/index_workers.blade.php
... | ... | @@ -0,0 +1,131 @@ |
1 | +@extends('layout.admin', ['title' => 'Админка - Работники статистика']) | |
2 | + | |
3 | +@section('script') | |
4 | + <script> | |
5 | + $(document).ready(function() { | |
6 | + $(document).on('change', '.change_js', function () { | |
7 | + var user_id = $('#user_id'); | |
8 | + var user_id_value = user_id.val(); | |
9 | + var year_month = $('#year_month'); | |
10 | + var year_month_value = year_month.val(); | |
11 | + var ajax_block = $('#ajax_block'); | |
12 | + | |
13 | + $.ajax({ | |
14 | + type: "GET", | |
15 | + url: "{{ url()->full()}}", | |
16 | + data: "user_id=" + user_id_value + "&year_month=" + year_month_value, | |
17 | + success: function (data) { | |
18 | + console.log('Обновление таблицы работников '); | |
19 | + //data = JSON.parse(data); | |
20 | + console.log(data); | |
21 | + ajax_block.html(data); | |
22 | + }, | |
23 | + headers: { | |
24 | + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') | |
25 | + }, | |
26 | + error: function (data) { | |
27 | + console.log('Error: ' + data); | |
28 | + } | |
29 | + }); | |
30 | + }); | |
31 | + }); | |
32 | + </script> | |
33 | +@endsection | |
34 | + | |
35 | +@section('search') | |
36 | + <!-- <div class="absolute inset-y-0 flex items-center pl-2"> | |
37 | + <svg | |
38 | + class="w-4 h-4" | |
39 | + aria-hidden="true" | |
40 | + fill="currentColor" | |
41 | + viewBox="0 0 20 20" | |
42 | + > | |
43 | + <path | |
44 | + fill-rule="evenodd" | |
45 | + d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" | |
46 | + clip-rule="evenodd" | |
47 | + ></path> | |
48 | + </svg> | |
49 | + </div> | |
50 | + <form action="" method="POST"> | |
51 | + <div style="float:left;"><input | |
52 | + class="w-full pl-8 pr-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input" | |
53 | + style="width: 400px" | |
54 | + type="text" | |
55 | + placeholder="Искать..." | |
56 | + aria-label="Search" | |
57 | + /></div> | |
58 | + <div style="float: left"> | |
59 | + <button type="submit" class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">Искать</button> | |
60 | + </div> | |
61 | + </form>--> | |
62 | +@endsection | |
63 | + | |
64 | +@section('content') | |
65 | + <div> | |
66 | + <label for="user_id" class="block text-sm"> | |
67 | + <span class="text-gray-700 dark:text-gray-400">Пользователи</span> | |
68 | + </label> | |
69 | + <select name="user_id" id="user_id" class="block change_js mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"> | |
70 | + <option value="0">Все</option> | |
71 | + @foreach($users as $user) | |
72 | + <option value="{{ $user->id }}">{{ !empty($user->name) ? $user->name : $user->name_man }} ({{ $user->id }})</option> | |
73 | + @endforeach | |
74 | + </select> | |
75 | + <label for="year_month" class="block text-sm"> | |
76 | + <span class="text-gray-700 dark:text-gray-400">Периоды</span> | |
77 | + </label> | |
78 | + <select name="year_month" id="year_month" class="block change_js mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"> | |
79 | + <option value="0">Все</option> | |
80 | + @foreach($periods as $period) | |
81 | + <option value="{{ $period->year_month }}">{{ $period->year_month }}</option> | |
82 | + @endforeach | |
83 | + </select><br> | |
84 | + </div> | |
85 | + <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> | |
86 | + <div class="w-full overflow-x-auto"> | |
87 | + <table class="w-full whitespace-no-wrap"> | |
88 | + <thead> | |
89 | + <tr | |
90 | + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" | |
91 | + > | |
92 | + <th class="px-4 py-3">№</th> | |
93 | + <th class="px-4 py-3">Юзер (имя/код)</th> | |
94 | + <th class="px-4 py-3">Интервал времени</th> | |
95 | + <th class="px-4 py-3">Просмотры</th> | |
96 | + <th class="px-4 py-3">Сообщения</th> | |
97 | + </tr> | |
98 | + </thead> | |
99 | + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> | |
100 | + | |
101 | + @foreach($stat as $user) | |
102 | + <tr class="text-gray-700 dark:text-gray-400"> | |
103 | + <td class="px-4 py-3"> | |
104 | + {{$user->id}} | |
105 | + </td> | |
106 | + <td class="px-4 py-3"> | |
107 | + {{ !empty($user->users->name) ? $user->users->name : $user->users->name_man }} ({{ $user->user_id }}) | |
108 | + </td> | |
109 | + <td class="px-4 py-3"> | |
110 | + {{ $user->year_month }} | |
111 | + </td> | |
112 | + <td class="px-4 py-3"> | |
113 | + {{ $user->lookin }} | |
114 | + </td> | |
115 | + <td class="px-4 py-3"> | |
116 | + {{ $user->message }} | |
117 | + </td> | |
118 | + </tr> | |
119 | + @endforeach | |
120 | + | |
121 | + </tbody> | |
122 | + </table> | |
123 | + </div> | |
124 | + | |
125 | + <div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> | |
126 | + <?=$stat->appends($_GET)->links('admin.pagginate'); ?> | |
127 | + </div> | |
128 | +</div> | |
129 | + | |
130 | + | |
131 | +@endsection |
resources/views/admin/static/index_workers_ajax.blade.php
... | ... | @@ -0,0 +1,40 @@ |
1 | +<div class="w-full overflow-x-auto"> | |
2 | + <table class="w-full whitespace-no-wrap"> | |
3 | + <thead> | |
4 | + <tr | |
5 | + class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800" | |
6 | + > | |
7 | + <th class="px-4 py-3">№</th> | |
8 | + <th class="px-4 py-3">Юзер (имя/код)</th> | |
9 | + <th class="px-4 py-3">Интервал времени</th> | |
10 | + <th class="px-4 py-3">Просмотры</th> | |
11 | + <th class="px-4 py-3">Сообщения</th> | |
12 | + </tr> | |
13 | + </thead> | |
14 | + <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> | |
15 | + @foreach($stat as $user) | |
16 | + <tr class="text-gray-700 dark:text-gray-400"> | |
17 | + <td class="px-4 py-3"> | |
18 | + {{$user->id}} | |
19 | + </td> | |
20 | + <td class="px-4 py-3"> | |
21 | + {{ !empty($user->users->name) ? $user->users->name : $user->users->name_man }} ({{ $user->user_id }}) | |
22 | + </td> | |
23 | + <td class="px-4 py-3"> | |
24 | + {{ $user->year_month }} | |
25 | + </td> | |
26 | + <td class="px-4 py-3"> | |
27 | + {{ $user->lookin }} | |
28 | + </td> | |
29 | + <td class="px-4 py-3"> | |
30 | + {{ $user->message }} | |
31 | + </td> | |
32 | + </tr> | |
33 | + @endforeach | |
34 | + </tbody> | |
35 | + </table> | |
36 | +</div> | |
37 | + | |
38 | +<div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"> | |
39 | + <?=$stat->appends($_GET)->links('admin.pagginate'); ?> | |
40 | +</div> |
resources/views/layout/admin.blade.php
... | ... | @@ -897,7 +897,7 @@ |
897 | 897 | <li class="flex"> |
898 | 898 | <a |
899 | 899 | class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200" |
900 | - href="#" | |
900 | + href="{{ route('admin.admin-messages') }}" | |
901 | 901 | > |
902 | 902 | <span>Сообщения</span> |
903 | 903 | <span |
... | ... | @@ -907,14 +907,14 @@ |
907 | 907 | </span> |
908 | 908 | </a> |
909 | 909 | </li> |
910 | - <li class="flex"> | |
910 | + <!--<li class="flex"> | |
911 | 911 | <a |
912 | 912 | class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200" |
913 | 913 | href="#" |
914 | 914 | > |
915 | 915 | <span>Логи</span> |
916 | 916 | </a> |
917 | - </li> | |
917 | + </li>--> | |
918 | 918 | </ul> |
919 | 919 | </template> |
920 | 920 | </li> |
routes/web.php
... | ... | @@ -19,6 +19,7 @@ use App\Http\Controllers\Admin\Ad_EmployersController; |
19 | 19 | use App\Http\Controllers\Admin\MsgAnswersController; |
20 | 20 | use App\Http\Controllers\Admin\GroupsController; |
21 | 21 | use App\Http\Controllers\PagesController; |
22 | +use Illuminate\Support\Facades\Storage; | |
22 | 23 | |
23 | 24 | |
24 | 25 | /* |
... | ... | @@ -90,6 +91,10 @@ Route::group([ |
90 | 91 | // кабинет профиль админа - сохранение формы |
91 | 92 | Route::post('profile', [AdminController::class, 'store_profile'])->name('store_profile'); |
92 | 93 | |
94 | + //кабинет сообщения админа | |
95 | + //Route::get('messages', [AdminController::class, 'profile'])->name('profile'); | |
96 | + | |
97 | + | |
93 | 98 | // кабинет профиль - форма пароли |
94 | 99 | Route::get('password', [AdminController::class, 'profile_password'])->name('password'); |
95 | 100 | // кабинет профиль - сохранение формы пароля |
... | ... | @@ -144,8 +149,12 @@ Route::group([ |
144 | 149 | */ |
145 | 150 | Route::resource('job-titles', JobTitlesController::class, ['except' => ['show']]); |
146 | 151 | |
147 | - // кабинет - сообщения | |
152 | + // кабинет - сообщения (чтение чужих) | |
148 | 153 | Route::get('messages', [MsgAnswersController::class, 'messages'])->name('messages'); |
154 | + // кабинет - сообщения (админские) | |
155 | + Route::get('admin-messages', [MsgAnswersController::class, 'admin_messages'])->name('admin-messages'); | |
156 | + // кабинет - сообщения (админские) | |
157 | + Route::post('admin-messages', [MsgAnswersController::class, 'admin_messages_post'])->name('admin-messages-post'); | |
149 | 158 | |
150 | 159 | /* |
151 | 160 | * Расписанный подход в описании каждой директорий групп пользователей. |
... | ... | @@ -163,9 +172,11 @@ Route::group([ |
163 | 172 | // кабинет - удаление группы пользователей |
164 | 173 | Route::delete('groups/delete/{group}', [GroupsController::class, 'destroy'])->name('delete-group'); |
165 | 174 | |
175 | + | |
166 | 176 | // кабинет - список админов |
167 | 177 | Route::get('group-admin', [AdminController::class, 'index'])->name('group-admin'); |
168 | 178 | |
179 | + | |
169 | 180 | /////редактор////// кабинет - редактор сайта//////////////////////// |
170 | 181 | Route::get('editor-site', function() { |
171 | 182 | return view('admin.editor.index'); |
... | ... | @@ -247,6 +258,11 @@ Route::group([ |
247 | 258 | // кабинет - роли пользователя |
248 | 259 | Route::get('roles', [UsersController::class, 'roles'])->name('roles'); |
249 | 260 | |
261 | + Route::get('logs', function() { | |
262 | + $files = Storage::files('logs/laravel.log'); | |
263 | + print_r($files); | |
264 | + })->name('logs'); | |
265 | + | |
250 | 266 | }); |
251 | 267 | |
252 | 268 | Route::post('ckeditor/upload', [CKEditorController::class, 'upload'])->name('ckeditor.image-upload'); |