Commit 633ea705f911085da4ded96726a1f03a6caf7af9
1 parent
a67c9d7ef4
Exists in
master
Массовая рассылка сообщений
Showing 8 changed files with 169 additions and 79 deletions Side-by-side Diff
- app/Http/Controllers/Admin/MsgAnswersController.php
- app/Models/MessagesRequests.php
- public/assets/css/tailwind.output_new.css
- public/css/general.css
- public/css/style_may2024.css
- resources/views/admin/message/index.blade.php
- resources/views/layout/admin.blade.php
- resources/views/modals/admin/messages/rejecte_message.blade.php
app/Http/Controllers/Admin/MsgAnswersController.php
... | ... | @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin; |
4 | 4 | |
5 | 5 | use App\Http\Controllers\Controller; |
6 | 6 | use App\Models\Message; |
7 | +use App\Models\MessagesRequests; | |
7 | 8 | use App\Models\User; |
8 | 9 | use Illuminate\Database\Eloquent\Builder; |
9 | 10 | use Illuminate\Http\Request; |
... | ... | @@ -107,23 +108,16 @@ class MsgAnswersController extends Controller |
107 | 108 | $id_admin = Auth::user()->id; |
108 | 109 | $users = User::query()->OrderBy('name')->where('is_bd', '=', '0')->get(); |
109 | 110 | |
110 | - $Msgs = Message::with('user_from')->with('user_to') //->with('response') | |
111 | - ->where(function($query) use ($id_admin) { | |
112 | - $query->where('user_id', '=', $id_admin) | |
113 | - ->orWhere('to_user_id', '=', $id_admin); | |
114 | - }); | |
115 | - | |
116 | - $find_key = ''; | |
117 | - $find_cat = ''; | |
118 | - | |
119 | - $Msgs = $this->filter($Msgs, $request, $find_key, $find_cat); | |
120 | - | |
121 | - $Msgs = $Msgs->orderByDesc('created_at')->paginate(5); | |
111 | + $Msgs = MessagesRequests::query() | |
112 | + ->with('user') | |
113 | + ->orderByDesc('created_at') | |
114 | + ->paginate(10) | |
115 | + ; | |
122 | 116 | |
123 | 117 | if ($request->ajax()) |
124 | 118 | return view('admin.message.index_ajax', compact('Msgs', 'id_admin', 'users')); |
125 | 119 | else |
126 | - return view('admin.message.index', compact('Msgs', 'id_admin', 'users', 'find_key', 'find_cat')); | |
120 | + return view('admin.message.index', compact('Msgs', 'id_admin', 'users')); | |
127 | 121 | } |
128 | 122 | |
129 | 123 | public function messages_sql(Request $request) { |
app/Models/MessagesRequests.php
... | ... | @@ -16,4 +16,14 @@ class MessagesRequests extends Model |
16 | 16 | 'is_rejected', |
17 | 17 | 'is_sent' |
18 | 18 | ]; |
19 | + | |
20 | + public function getJobsAttribute() | |
21 | + { | |
22 | + $job_titles_ids = json_decode($this->attributes['job_titles'], true); | |
23 | + return Job_title::whereIn('id', $job_titles_ids)->get(); | |
24 | + } | |
25 | + | |
26 | + public function user() { | |
27 | + return $this->belongsTo(User::class, 'user_id'); | |
28 | + } | |
19 | 29 | } |
public/assets/css/tailwind.output_new.css
... | ... | @@ -521,6 +521,10 @@ img, video { |
521 | 521 | background-color: #047481; |
522 | 522 | background-color: rgba(4, 116, 129, var(--bg-opacity)) |
523 | 523 | } |
524 | +.bg-green-600 { | |
525 | + --bg-opacity: 1; | |
526 | + background-color: #44a32b; | |
527 | +} | |
524 | 528 | .bg-blue-100 { |
525 | 529 | --bg-opacity: 1; |
526 | 530 | background-color: #e1effe; |
public/css/general.css
... | ... | @@ -0,0 +1,51 @@ |
1 | +/* Диалог модал */ | |
2 | +.modal-dialog{ | |
3 | + border-radius: 10px; | |
4 | +} | |
5 | +.modal-dialog .modal-dialog-footer{ | |
6 | + display: flex; | |
7 | + justify-content: space-between; | |
8 | +} | |
9 | +.modal-dialog .modal-dialog-footer.center{ | |
10 | + display: flex; | |
11 | + justify-content: center; | |
12 | +} | |
13 | +.modal-dialog .modal-dialog-title h2{ | |
14 | + font-weight: bold; | |
15 | + font-size: 24px; | |
16 | + text-align: center; | |
17 | +} | |
18 | +.modal-dialog .modal-dialog-body{ | |
19 | + padding-top: 20px; | |
20 | + padding-bottom: 20px; | |
21 | +} | |
22 | +.modal-dialog .modal-dialog-footer .button-admin{ | |
23 | + padding: 5px 10px; | |
24 | + border: 1px #000 solid; | |
25 | + border-radius: 8px; | |
26 | +} | |
27 | +/* Конец Диалог модал */ | |
28 | + | |
29 | +.button-loader { | |
30 | + border: 2px solid #f3f3f3; | |
31 | + -webkit-animation: spin 1s linear infinite; | |
32 | + animation: spin 1s linear infinite; | |
33 | + border-top: 2px solid #555; | |
34 | + border-radius: 50%; | |
35 | + width: 20px; | |
36 | + height: 20px; | |
37 | + margin-right: 10px; | |
38 | +} | |
39 | +@keyframes spin { | |
40 | + 0% { transform: rotate(0deg); } | |
41 | + 100% { transform: rotate(360deg); } | |
42 | +} | |
43 | +.error-block{ | |
44 | + color:red; | |
45 | + padding: 0; | |
46 | + width: 100%; | |
47 | +} | |
48 | + | |
49 | +.review-image-modal{ | |
50 | + cursor: pointer; | |
51 | +} |
public/css/style_may2024.css
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | @import url(jquery.select2.css); |
11 | 11 | @import url(star-rating.min.css); |
12 | 12 | @import url(swiper.css); |
13 | +@import url(general.css); | |
13 | 14 | html { |
14 | 15 | line-height: 1.15; /* 1 */ |
15 | 16 | -webkit-text-size-adjust: 100%; /* 2 */ |
... | ... | @@ -9296,42 +9297,6 @@ body .cke_notifications_area{ |
9296 | 9297 | border-radius: 45px; |
9297 | 9298 | } |
9298 | 9299 | |
9299 | -/* Диалог модал */ | |
9300 | -.modal-dialog{ | |
9301 | - border-radius: 10px; | |
9302 | -} | |
9303 | -.modal-dialog .modal-dialog-footer{ | |
9304 | - display: flex; | |
9305 | - justify-content: space-between; | |
9306 | -} | |
9307 | -.modal-dialog .modal-dialog-footer.center{ | |
9308 | - display: flex; | |
9309 | - justify-content: center; | |
9310 | -} | |
9311 | - | |
9312 | -.button-loader { | |
9313 | - border: 2px solid #f3f3f3; | |
9314 | - -webkit-animation: spin 1s linear infinite; | |
9315 | - animation: spin 1s linear infinite; | |
9316 | - border-top: 2px solid #555; | |
9317 | - border-radius: 50%; | |
9318 | - width: 20px; | |
9319 | - height: 20px; | |
9320 | -} | |
9321 | -@keyframes spin { | |
9322 | - 0% { transform: rotate(0deg); } | |
9323 | - 100% { transform: rotate(360deg); } | |
9324 | -} | |
9325 | -.error-block{ | |
9326 | - color:red; | |
9327 | - padding: 0; | |
9328 | - width: 100%; | |
9329 | -} | |
9330 | - | |
9331 | -.review-image-modal{ | |
9332 | - cursor: pointer; | |
9333 | -} | |
9334 | - | |
9335 | 9300 | .flot-one-ship .flot-label{ |
9336 | 9301 | font-weight: bold; |
9337 | 9302 | display: flex; |
resources/views/admin/message/index.blade.php
... | ... | @@ -3,6 +3,16 @@ |
3 | 3 | @section('script') |
4 | 4 | <script> |
5 | 5 | $(document).ready(function() { |
6 | + $('.rejecte-button').click(function(){ | |
7 | + var this_btn = $(this); | |
8 | + var wrap = this_btn.closest('tr'); | |
9 | + var chat_id = wrap.data('message-id'); | |
10 | + var target = wrap.find('.user-name').text(); | |
11 | + | |
12 | + $('#rejecte_message').data('chat-id', chat_id); | |
13 | + $('#rejecte_message').find('.user-name').text(target.trim()); | |
14 | + }); | |
15 | + | |
6 | 16 | $(document).on('change', '.checkread', function () { |
7 | 17 | var this_ = $(this); |
8 | 18 | var value = this_.val(); |
... | ... | @@ -38,10 +48,6 @@ |
38 | 48 | </script> |
39 | 49 | @endsection |
40 | 50 | |
41 | -@section('search') | |
42 | - @include('admin.find_message') | |
43 | -@endsection | |
44 | - | |
45 | 51 | @section('content') |
46 | 52 | <div class="w-full overflow-hidden rounded-lg shadow-xs" id="ajax_block"> |
47 | 53 | <div class="w-full overflow-x-auto"> |
... | ... | @@ -52,7 +58,7 @@ |
52 | 58 | > |
53 | 59 | <th class="px-4 py-3">№</th> |
54 | 60 | <th class="px-4 py-3">От юзера</th> |
55 | - <th class="px-4 py-3">К юзеру</th> | |
61 | + <th class="px-4 py-3">Должности</th> | |
56 | 62 | <th class="px-4 py-3">Текст</th> |
57 | 63 | <th class="px-4 py-3">Дата</th> |
58 | 64 | <th class="px-4 py-3">Прочтено</th> |
... | ... | @@ -60,44 +66,54 @@ |
60 | 66 | </thead> |
61 | 67 | <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800"> |
62 | 68 | @foreach($Msgs as $msg) |
63 | - <tr class="text-gray-700 dark:text-gray-400" | |
64 | - @if (isset($msg->user_to->id)) | |
65 | - @if (($msg->user_to->id == $id_admin) && ($msg->flag_new == 1)) | |
66 | - style="background-color: #403998;" | |
67 | - @endif | |
68 | - @endif> | |
69 | + <tr class="text-gray-700 dark:text-gray-400" data-message-id="{{ $msg->id }}"> | |
69 | 70 | <td class="px-4 py-3"> |
70 | - {{$msg->id}} | |
71 | + {{ $msg->id }} | |
71 | 72 | </td> |
72 | 73 | <td class="px-4 py-3"> |
73 | - @if (isset($msg->user_from->name)) | |
74 | - {{$msg->user_from->name}} ({{$msg->user_from->id}}) | |
75 | - @else | |
76 | - Пользователь удален | |
77 | - @endif | |
74 | + <div class="user-name"> | |
75 | + @if (isset($msg->user->name)) | |
76 | + {{$msg->user->name}} ({{$msg->user->id}}) | |
77 | + @else | |
78 | + Пользователь удален | |
79 | + @endif | |
80 | + </div> | |
78 | 81 | </td> |
79 | 82 | <td class="px-4 py-3"> |
80 | - @if (isset($msg->user_to->name)) | |
81 | - {{$msg->user_to->name}} ({{$msg->user_to->id}}) | |
82 | - @else | |
83 | - Пользователь удален | |
84 | - @endif | |
83 | + @if($msg->job_titles) | |
84 | + @foreach($msg->jobs as $job) | |
85 | + {{ $job->name }} | |
86 | + @if(!$loop->last) | |
87 | + <br> | |
88 | + @endif | |
89 | + @endforeach | |
90 | + @endif | |
85 | 91 | </td> |
86 | 92 | <td class="px-4 py-3"> |
87 | - {{$msg->title}} | |
88 | - <div class="flex items-center text-sm"> | |
89 | - <textarea cols="7" style="width:250px;">{{ $msg->text }}</textarea> | |
93 | + <div> | |
94 | + {{ $msg->text }} | |
90 | 95 | </div> |
91 | 96 | </td> |
92 | 97 | <td class="px-4 py-3 text-sm"> |
93 | 98 | {{ date('d.m.Y h:i:s', strtotime($msg->created_at)) }} |
94 | 99 | </td> |
95 | - <td class="px-4 py-3 text-sm"> | |
96 | - @if (isset($msg->user_to->id)) | |
97 | - @if (($msg->user_to->id == $id_admin) && ($msg->flag_new == 1)) | |
98 | - <input type="checkbox" class="checkread" value="{{$msg->id}}" name="read_{{$msg->id}}"/> | |
100 | + <td class="px-4 py-3"> | |
101 | + @if($msg->is_rejected) | |
102 | + Отклонено | |
103 | + @elseif($msg->is_sent) | |
104 | + Отправлено | |
105 | + @else | |
106 | + <div class=""> | |
107 | + <button class="rejecte-button px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-red-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple" | |
108 | + data-fancybox data-src="#rejecte_message" | |
109 | + > | |
110 | + Отклонить | |
111 | + </button> | |
112 | + <button class="send-button px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-green-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> | |
113 | + Отправить | |
114 | + </button> | |
115 | + </div> | |
99 | 116 | @endif |
100 | - @endif | |
101 | 117 | </td> |
102 | 118 | </tr> |
103 | 119 | @endforeach |
... | ... | @@ -177,4 +193,6 @@ |
177 | 193 | </div> |
178 | 194 | </form> |
179 | 195 | </div> |
196 | + | |
197 | + @include('modals.admin.messages.rejecte_message') | |
180 | 198 | @endsection |
resources/views/layout/admin.blade.php
... | ... | @@ -21,6 +21,11 @@ |
21 | 21 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> |
22 | 22 | <script src="{{ asset('./assets/js/charts-lines.js') }}" defer></script> |
23 | 23 | <script src="{{ asset('./assets/js/charts-pie.js') }}" defer></script> |
24 | + <script src="{{ asset('js/jquery.fancybox.js') }}"></script> | |
25 | + <script src="{{ asset('./js/func.js') }}"></script> | |
26 | + <link rel="stylesheet" href="{{ asset('css/helpers.css') }}"> | |
27 | + <link rel="stylesheet" href="{{ asset('css/jquery.fancybox.css') }}"> | |
28 | + <link rel="stylesheet" href="{{ asset('css/general.css') }}"> | |
24 | 29 | </head> |
25 | 30 | <body> |
26 | 31 | <div class="flex h-screen bg-gray-50 dark:bg-gray-900" :class="{ 'overflow-hidden': isSideMenuOpen }"> |
resources/views/modals/admin/messages/rejecte_message.blade.php
... | ... | @@ -0,0 +1,43 @@ |
1 | +<div class="hide"> | |
2 | + <div id="rejecte_message" class="modal-dialog"> | |
3 | + <div class="modal-dialog-title"> | |
4 | + <h2>Отклонить сообщение</h2> | |
5 | + </div> | |
6 | + <div class="modal-dialog-body"> | |
7 | + <p>Вы действительно хотите отклонить сообщение №<span class="message-id"></span> от "<b><span class="user-name"></span></b>"?</p> | |
8 | + </div> | |
9 | + <div class="modal-dialog-footer"> | |
10 | + <button type="button" class="rejecte-message-button flex px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-red-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"> | |
11 | + Отклонить | |
12 | + </button> | |
13 | + <button type="button" class="px-3 py-1 text-sm font-medium leading-5 transition-colors duration-150 bg-white border border-transparent rounded-md border-gray-300" | |
14 | + onclick="$.fancybox.close();"> | |
15 | + Закрыть | |
16 | + </button> | |
17 | + </div> | |
18 | + </div> | |
19 | +</div> | |
20 | + | |
21 | +<script> | |
22 | + $(function(){ | |
23 | + $('.rejecte-message-button').click(function(){ | |
24 | + spinStart($(this)); | |
25 | + var wrap = $(this).closest('#rejecte_message'); | |
26 | + var chat_id = wrap.data('chat-id'); | |
27 | + | |
28 | + /*$.ajax({ | |
29 | + type: "POST", | |
30 | + url: "{{ route('employer.remove_chat') }}", | |
31 | + data: { | |
32 | + id: chat_id | |
33 | + }, | |
34 | + headers: { | |
35 | + 'X-CSRF-TOKEN': $('[name="_token"]').val() | |
36 | + }, | |
37 | + success: function(){ | |
38 | + location.reload(); | |
39 | + } | |
40 | + });*/ | |
41 | + }); | |
42 | + }); | |
43 | +</script> |