Commit 5da8a8bd46493ff27777b197b70e161eb41ad61e
Exists in
master
Merge branch 'task-132985' into 'master'
task-132985 autoresponder & autolift added to worker cabinet
Showing 23 changed files Side-by-side Diff
- app/Console/Commands/DeleteExpiredAutoliftOptions.php
- app/Console/Commands/DispatchResumeLiftJobCommand.php
- app/Console/Commands/DispatchVacancyLiftJobCommand.php
- app/Console/Kernel.php
- app/Http/Controllers/EmployerController.php
- app/Http/Controllers/WorkerController.php
- app/Jobs/LiftResumeJob.php
- app/Models/Employer.php
- app/Models/User.php
- app/Models/Worker.php
- app/Models/WorkerAutoliftOption.php
- app/Observers/MessageObserver.php
- database/migrations/2024_10_25_120802_move_autoresponder_colomns.php
- database/migrations/2024_10_28_114521_create_worker_autolift_options_table.php
- public/js/script-vc.js
- resources/views/employers/autoresponder.blade.php
- resources/views/employers/menu.blade.php
- resources/views/employers/vacancy_autolift.blade.php
- resources/views/workers/autoresponder.blade.php
- resources/views/workers/dialog.blade.php
- resources/views/workers/menu.blade.php
- resources/views/workers/resume_autolift.blade.php
- routes/web.php
app/Console/Commands/DeleteExpiredAutoliftOptions.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | namespace App\Console\Commands; |
4 | 4 | |
5 | 5 | use App\Models\EmployerAutoliftOption; |
6 | +use App\Models\WorkerAutoliftOption; | |
6 | 7 | use Illuminate\Console\Command; |
7 | 8 | |
8 | 9 | class DeleteExpiredAutoliftOptions extends Command |
... | ... | @@ -18,6 +19,11 @@ class DeleteExpiredAutoliftOptions extends Command |
18 | 19 | ->update([ |
19 | 20 | 'is_enabled' => false |
20 | 21 | ]); |
22 | + WorkerAutoliftOption::query() | |
23 | + ->whereRaw('`updated_at` < DATE_SUB(NOW(), INTERVAL `days_repeat` DAY)') | |
24 | + ->update([ | |
25 | + 'is_enabled' => false | |
26 | + ]); | |
21 | 27 | return Command::SUCCESS; |
22 | 28 | } |
23 | 29 | } |
app/Console/Commands/DispatchResumeLiftJobCommand.php
... | ... | @@ -0,0 +1,41 @@ |
1 | +<?php | |
2 | + | |
3 | +namespace App\Console\Commands; | |
4 | + | |
5 | +use App\Jobs\LiftVacancyJob; | |
6 | +use App\Jobs\SendVacancyToTelegramJob; | |
7 | +use App\Models\EmployerAutoliftOption; | |
8 | +use App\Models\WorkerAutoliftOption; | |
9 | +use Illuminate\Console\Command; | |
10 | + | |
11 | +class DispatchResumeLiftJobCommand extends Command | |
12 | +{ | |
13 | + protected $signature ='resume:dispatch'; | |
14 | + | |
15 | + public function handle() | |
16 | + { | |
17 | + $now = now()->timezone('Europe/Moscow')->format('H:i'); | |
18 | + | |
19 | + $employers = WorkerAutoliftOption::query() | |
20 | + ->where(function ($query) use ($now) { | |
21 | + $query->where('times_per_day', 1) | |
22 | + ->where('time_send_first', $now); | |
23 | + }) | |
24 | + ->orWhere(function ($query) use ($now) { | |
25 | + $query->where('times_per_day', 2) | |
26 | + ->where('time_send_first', $now) | |
27 | + ->where('time_send_second', $now); | |
28 | + }) | |
29 | + ->orWhere(function ($query) use ($now) { | |
30 | + $query->where('times_per_day', 3) | |
31 | + ->where('time_send_first', $now) | |
32 | + ->where('time_send_second', $now) | |
33 | + ->where('time_send_third', $now); | |
34 | + }) | |
35 | + ->get(); | |
36 | + | |
37 | + LiftVacancyJob::dispatch($employers->pluck('employer_id')->toArray()); | |
38 | + | |
39 | + return Command::SUCCESS; | |
40 | + } | |
41 | +} |
app/Console/Commands/DispatchVacancyLiftJobCommand.php
... | ... | @@ -13,7 +13,7 @@ class DispatchVacancyLiftJobCommand extends Command |
13 | 13 | |
14 | 14 | public function handle() |
15 | 15 | { |
16 | - $now = now()->format('H:i'); | |
16 | + $now = now()->timezone('Europe/Moscow')->format('H:i'); | |
17 | 17 | |
18 | 18 | $employers = EmployerAutoliftOption::query() |
19 | 19 | ->where(function ($query) use ($now) { |
app/Console/Kernel.php
... | ... | @@ -11,6 +11,7 @@ class Kernel extends ConsoleKernel |
11 | 11 | { |
12 | 12 | $schedule->command('vacancy:delete_expired')->dailyAt('00:00'); |
13 | 13 | $schedule->command('vacancy:dispatch')->everyMinute(); |
14 | + $schedule->command('resume:dispatch')->everyMinute(); | |
14 | 15 | } |
15 | 16 | |
16 | 17 | protected function commands() |
app/Http/Controllers/EmployerController.php
... | ... | @@ -811,6 +811,7 @@ class EmployerController extends Controller |
811 | 811 | 'employer_id' => $employer->id, |
812 | 812 | ], |
813 | 813 | [ |
814 | + 'is_enabled' => $request->get('is_enabled'), | |
814 | 815 | 'times_per_day' => $request->get('times_per_day'), |
815 | 816 | 'days_repeat' => $request->get('days_repeat'), |
816 | 817 | 'time_send_first' => $request->get('time_send_first'), |
... | ... | @@ -834,17 +835,16 @@ class EmployerController extends Controller |
834 | 835 | |
835 | 836 | public function autoresponder() |
836 | 837 | { |
837 | - $employer = Auth::user()->employers[0]; | |
838 | - return view('employers.autoresponder', compact('employer')); | |
838 | + $user = Auth::user(); | |
839 | + return view('employers.autoresponder', compact('user')); | |
839 | 840 | } |
840 | 841 | |
841 | 842 | public function autoresponderSave(Request $request): RedirectResponse |
842 | 843 | { |
843 | - /** @var Employer $employer */ | |
844 | - $employer = Auth::user()->employers[0]; | |
845 | - $employer->autoresponder = $request->get('autoresponder', false) === 'on'; | |
846 | - $employer->autoresponder_message = $request->get('autoresponder_message'); | |
847 | - $employer->save(); | |
844 | + $user = Auth::user(); | |
845 | + $user->autoresponder = $request->get('autoresponder', false) === 'on'; | |
846 | + $user->autoresponder_message = $request->get('autoresponder_message'); | |
847 | + $user->save(); | |
848 | 848 | |
849 | 849 | return redirect(route('employer.autoresponder')); |
850 | 850 | } |
app/Http/Controllers/WorkerController.php
... | ... | @@ -11,6 +11,8 @@ use App\Models\Ad_employer; |
11 | 11 | use App\Models\ad_response; |
12 | 12 | use App\Models\Chat; |
13 | 13 | use App\Models\Dop_info; |
14 | +use App\Models\Employer; | |
15 | +use App\Models\EmployerAutoliftOption; | |
14 | 16 | use App\Models\infobloks; |
15 | 17 | use App\Models\Job_title; |
16 | 18 | use App\Models\Like_vacancy; |
... | ... | @@ -24,10 +26,12 @@ use App\Models\Title_worker; |
24 | 26 | use App\Models\User; |
25 | 27 | use App\Models\User as User_Model; |
26 | 28 | use App\Models\Worker; |
29 | +use App\Models\WorkerAutoliftOption; | |
27 | 30 | use Barryvdh\DomPDF\Facade\Pdf; |
28 | 31 | use Carbon\Carbon; |
29 | 32 | use Illuminate\Auth\Events\Registered; |
30 | 33 | use Illuminate\Database\Eloquent\Builder; |
34 | +use Illuminate\Http\RedirectResponse; | |
31 | 35 | use Illuminate\Http\Request; |
32 | 36 | use Illuminate\Pagination\LengthAwarePaginator; |
33 | 37 | use Illuminate\Support\Facades\Auth; |
... | ... | @@ -35,6 +39,8 @@ use Illuminate\Support\Facades\DB; |
35 | 39 | use Illuminate\Support\Facades\Hash; |
36 | 40 | use Illuminate\Support\Facades\Storage; |
37 | 41 | use Illuminate\Support\Facades\Validator; |
42 | +use Illuminate\View\View; | |
43 | +use JsonException; | |
38 | 44 | use PhpOffice\PhpSpreadsheet\Spreadsheet; |
39 | 45 | use PhpOffice\PhpSpreadsheet\Writer\Xlsx; |
40 | 46 | use Symfony\Component\HttpFoundation\StreamedResponse; |
... | ... | @@ -282,7 +288,8 @@ class WorkerController extends Controller |
282 | 288 | |
283 | 289 | $jobIds = $request->input('job_title_list', []); |
284 | 290 | |
285 | - $users = DB::select( | |
291 | + /* //query for mysql ver 8.0 or higher | |
292 | + $users = DB::select( | |
286 | 293 | "select `job_titles`.`name`, `users`.`surname`, `users`.`name_man`, `users`.`surname2`, `users`.`email`, `users`.`telephone` |
287 | 294 | from users |
288 | 295 | join workers on `users`.`id` = `workers`.`user_id` |
... | ... | @@ -295,6 +302,17 @@ class WorkerController extends Controller |
295 | 302 | '$[*]' COLUMNS (id INT PATH '$')) pw |
296 | 303 | where pw.id = job_titles.id) |
297 | 304 | )". ((!empty($jobIds)) ? 'and job_titles.id in ('. implode(',', $jobIds).')' : '') |
305 | + );*/ | |
306 | + | |
307 | + $users = DB::select( | |
308 | + "select `job_titles`.`name`, `users`.`surname`, `users`.`name_man`, `users`.`surname2`, `users`.`email`, `users`.`telephone` | |
309 | + from users | |
310 | + join workers on `users`.`id` = `workers`.`user_id` | |
311 | + join `job_titles` | |
312 | + where `users`.`is_bd` = 1 | |
313 | + and (`workers`.`position_work` = `job_titles`.`id` | |
314 | + or `workers`.`positions_work` | |
315 | + )". ((!empty($jobIds)) ? 'and job_titles.id in ('. implode(',', $jobIds).')' : '') | |
298 | 316 | ); |
299 | 317 | |
300 | 318 | $users = collect($users); |
... | ... | @@ -1053,5 +1071,59 @@ class WorkerController extends Controller |
1053 | 1071 | $doc->delete(); |
1054 | 1072 | return redirect()->route('worker.cabinet')->with('success', 'Вы успешно удалили запись!'); |
1055 | 1073 | } |
1074 | + | |
1075 | + public function autoresponder() | |
1076 | + { | |
1077 | + $user = Auth::user(); | |
1078 | + return view('workers.autoresponder', compact('user')); | |
1079 | + } | |
1080 | + | |
1081 | + public function autoresponderSave(Request $request): RedirectResponse | |
1082 | + { | |
1083 | + /** @var Employer $employer */ | |
1084 | + $employer = Auth::user(); | |
1085 | + $employer->autoresponder = $request->get('autoresponder', false) === 'on'; | |
1086 | + $employer->autoresponder_message = $request->get('autoresponder_message'); | |
1087 | + $employer->save(); | |
1088 | + | |
1089 | + return redirect(route('worker.autoresponder')); | |
1090 | + } | |
1091 | + /** | |
1092 | + * @throws JsonException | |
1093 | + */ | |
1094 | + public function resumeAutoLiftForm(): View | |
1095 | + { | |
1096 | + $worker = Auth::user()->workers[0]; | |
1097 | + | |
1098 | + $options = $worker->autoliftOptions ?? new WorkerAutoliftOption(); | |
1099 | + | |
1100 | + return view('workers.resume_autolift', compact('worker', 'options')); | |
1101 | + } | |
1102 | + | |
1103 | + /** | |
1104 | + * @throws JsonException | |
1105 | + */ | |
1106 | + public function resumeAutoLiftSave(Request $request) | |
1107 | + { | |
1108 | + $worker = Auth::user()->workers[0]; | |
1109 | + | |
1110 | + $worker->autoliftOptions()->updateOrCreate( | |
1111 | + [ | |
1112 | + 'worker_id' => $worker->id, | |
1113 | + ], | |
1114 | + [ | |
1115 | + 'is_enabled' => $request->get('is_enabled') === 'on', | |
1116 | + 'times_per_day' => $request->get('times_per_day'), | |
1117 | + 'days_repeat' => $request->get('days_repeat'), | |
1118 | + 'time_send_first' => $request->get('time_send_first'), | |
1119 | + 'time_send_second' => $request->get('time_send_second'), | |
1120 | + 'time_send_third' => $request->get('time_send_third'), | |
1121 | + 'time_send_tg' => $request->get('time_send_tg'), | |
1122 | + 'autolift_site' => $request->get('autolift_site') === 'on', | |
1123 | + ] | |
1124 | + ); | |
1125 | + | |
1126 | + return response()->json(['success' => true]); | |
1127 | + } | |
1056 | 1128 | } |
1057 | 1129 |
app/Jobs/LiftResumeJob.php
... | ... | @@ -0,0 +1,32 @@ |
1 | +<?php | |
2 | + | |
3 | +namespace App\Jobs; | |
4 | + | |
5 | +use App\Models\Ad_employer; | |
6 | +use App\Models\Worker; | |
7 | +use Illuminate\Bus\Queueable; | |
8 | +use Illuminate\Contracts\Queue\ShouldQueue; | |
9 | +use Illuminate\Foundation\Bus\Dispatchable; | |
10 | +use Illuminate\Queue\InteractsWithQueue; | |
11 | +use Illuminate\Queue\SerializesModels; | |
12 | + | |
13 | +class LiftResumeJob implements ShouldQueue | |
14 | +{ | |
15 | + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | |
16 | + | |
17 | + private array $workerIds; | |
18 | + | |
19 | + public function __construct(array $workerIds) | |
20 | + { | |
21 | + $this->workerIds = $workerIds; | |
22 | + } | |
23 | + | |
24 | + public function handle() | |
25 | + { | |
26 | + Worker::query() | |
27 | + ->whereIn('id', $this->workerIds) | |
28 | + ->update([ | |
29 | + 'updated_at' => now() | |
30 | + ]); | |
31 | + } | |
32 | +} |
app/Models/Employer.php
app/Models/User.php
... | ... | @@ -47,6 +47,8 @@ class User extends Authenticatable |
47 | 47 | 'is_manager', |
48 | 48 | 'subscribe_email', |
49 | 49 | 'subscribe', |
50 | + 'autoresponder', | |
51 | + 'autoresponder_message', | |
50 | 52 | ]; |
51 | 53 | |
52 | 54 | /** |
... | ... | @@ -173,7 +175,7 @@ class User extends Authenticatable |
173 | 175 | } |
174 | 176 | |
175 | 177 | if ($jobIds !== null && count($jobIds) > 0) { |
176 | - return Job_title::whereIn('id', $jobIds)->first()->name; | |
178 | + return Job_title::whereIn('id', $jobIds)->first()?->name; | |
177 | 179 | } |
178 | 180 | return null; |
179 | 181 | } |
app/Models/Worker.php
... | ... | @@ -136,4 +136,9 @@ class Worker extends Model |
136 | 136 | $job_titles_ids = json_decode($this->attributes['positions_work'], true); |
137 | 137 | return Job_title::whereIn('id', $job_titles_ids)->get(); |
138 | 138 | } |
139 | + | |
140 | + public function autoliftOptions() | |
141 | + { | |
142 | + return $this->hasOne(WorkerAutoliftOption::class); | |
143 | + } | |
139 | 144 | } |
app/Models/WorkerAutoliftOption.php
... | ... | @@ -0,0 +1,37 @@ |
1 | +<?php | |
2 | + | |
3 | +namespace App\Models; | |
4 | + | |
5 | +use Illuminate\Database\Eloquent\Casts\Attribute; | |
6 | +use Illuminate\Database\Eloquent\Model; | |
7 | +use Illuminate\Database\Eloquent\Relations\BelongsTo; | |
8 | + | |
9 | +/** | |
10 | + * @property int $employer_id | |
11 | + * @property bool $autolift_site | |
12 | + * @property int $times_per_day | |
13 | + * @property int $days_repeat | |
14 | + * @property string $time_send_first | |
15 | + * @property string $time_send_second | |
16 | + * @property string $time_send_third | |
17 | + * @property bool $is_enabled | |
18 | +*/ | |
19 | +class WorkerAutoliftOption extends Model | |
20 | +{ | |
21 | + protected $guarded = [ | |
22 | + 'created_at', | |
23 | + 'updated_at' | |
24 | + ]; | |
25 | + | |
26 | + public function isEnabled(): Attribute | |
27 | + { | |
28 | + return Attribute::make( | |
29 | + get: fn ($value) => $value === null ? 0 : 1 | |
30 | + ); | |
31 | + } | |
32 | + | |
33 | + public function worker(): BelongsTo | |
34 | + { | |
35 | + return $this->belongsTo(Worker::class); | |
36 | + } | |
37 | +} |
app/Observers/MessageObserver.php
... | ... | @@ -5,25 +5,24 @@ namespace App\Observers; |
5 | 5 | use App\Models\Chat; |
6 | 6 | use App\Models\Employer; |
7 | 7 | use App\Models\Message; |
8 | +use App\Models\User; | |
8 | 9 | use Illuminate\Http\Request; |
9 | 10 | |
10 | 11 | class MessageObserver |
11 | 12 | { |
12 | 13 | public function created(Message $message): void |
13 | 14 | { |
14 | - /** @var Employer $employer */ | |
15 | - $employer = Employer::query() | |
16 | - ->where('user_id', $message->to_user_id) | |
17 | - ->first(); | |
15 | + /** @var User $user */ | |
16 | + $user = User::find($message->to_user_id); | |
18 | 17 | |
19 | - if ($employer === null || !$employer->autoresponder) { | |
18 | + if ($user === null || !$user->autoresponder) { | |
20 | 19 | return; |
21 | 20 | } |
22 | 21 | |
23 | 22 | $recentAutoresponderMessage = Message::query() |
24 | 23 | ->where('user_id', $message->to_user_id) |
25 | 24 | ->where('to_user_id', $message->user_id) |
26 | - ->where('text', $employer->autoresponder_message) | |
25 | + ->where('text', $user->autoresponder_message) | |
27 | 26 | ->where('created_at', '>', now()->subDays(4)) |
28 | 27 | ->orderBy('id', 'desc') |
29 | 28 | ->first(); |
... | ... | @@ -37,7 +36,7 @@ class MessageObserver |
37 | 36 | user_id: $message->to_user_id, |
38 | 37 | to_user_id: $message->user_id, |
39 | 38 | message_params: [ |
40 | - 'text' => $employer->autoresponder_message, | |
39 | + 'text' => $user->autoresponder_message, | |
41 | 40 | 'flag_new' => 1 |
42 | 41 | ] |
43 | 42 | ); |
database/migrations/2024_10_25_120802_move_autoresponder_colomns.php
... | ... | @@ -0,0 +1,36 @@ |
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('employers', function (Blueprint $table) { | |
17 | + $table->dropColumn('autoresponder'); | |
18 | + $table->dropColumn('autoresponder_message'); | |
19 | + }); | |
20 | + | |
21 | + Schema::table('users', function (Blueprint $table) { | |
22 | + $table->boolean('autoresponder')->default(false); | |
23 | + $table->text('autoresponder_message')->nullable(); | |
24 | + }); | |
25 | + } | |
26 | + | |
27 | + /** | |
28 | + * Reverse the migrations. | |
29 | + * | |
30 | + * @return void | |
31 | + */ | |
32 | + public function down() | |
33 | + { | |
34 | + // | |
35 | + } | |
36 | +}; |
database/migrations/2024_10_28_114521_create_worker_autolift_options_table.php
... | ... | @@ -0,0 +1,40 @@ |
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::create('worker_autolift_options', function (Blueprint $table) { | |
17 | + $table->id(); | |
18 | + $table->unsignedBigInteger('worker_id'); | |
19 | + $table->foreign('worker_id')->references('id')->on('workers')->onDelete('cascade'); | |
20 | + $table->boolean('autolift_site')->default(true); | |
21 | + $table->integer('times_per_day')->index()->default(1); | |
22 | + $table->integer('days_repeat')->default(1); | |
23 | + $table->string('time_send_first')->index(); | |
24 | + $table->string('time_send_second')->index()->nullable(); | |
25 | + $table->string('time_send_third')->index()->nullable(); | |
26 | + $table->boolean('is_enabled')->default(true); | |
27 | + $table->timestamps(); | |
28 | + }); | |
29 | + } | |
30 | + | |
31 | + /** | |
32 | + * Reverse the migrations. | |
33 | + * | |
34 | + * @return void | |
35 | + */ | |
36 | + public function down() | |
37 | + { | |
38 | + Schema::dropIfExists('worker_autolift_options'); | |
39 | + } | |
40 | +}; |
public/js/script-vc.js
resources/views/employers/autoresponder.blade.php
... | ... | @@ -21,14 +21,16 @@ |
21 | 21 | <div class="cabinet__inputs"> |
22 | 22 | <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> |
23 | 23 | <label class="toggle"> |
24 | - <input name="autoresponder" type="checkbox" class="toggle__input" @if($employer->autoresponder) checked @endif> | |
24 | + <input name="autoresponder" type="checkbox" class="toggle__input" | |
25 | + @if($user->autoresponder) checked @endif> | |
25 | 26 | <span class="toggle__icon"></span> |
26 | 27 | <span class="toggle__text">Деактивировано</span> |
27 | 28 | <span class="toggle__text">Активировано</span> |
28 | 29 | </label> |
29 | 30 | </div> |
30 | 31 | <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> |
31 | - <p>В этом разделе вы сможете задать автоматический ответ на письма, поступающие в почтовый ящик.</p> | |
32 | + <p>В этом разделе вы сможете задать автоматический ответ на письма, поступающие в | |
33 | + почтовый ящик.</p> | |
32 | 34 | </div> |
33 | 35 | <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group"> |
34 | 36 | <label class="form-group__label">Введите текст</label> |
... | ... | @@ -38,7 +40,7 @@ |
38 | 40 | class="textarea" |
39 | 41 | placeholder="Ваше сообщение" |
40 | 42 | required |
41 | - >{{$employer->autoresponder_message}}</textarea> | |
43 | + >{{$user->autoresponder_message}}</textarea> | |
42 | 44 | </div> |
43 | 45 | </div> |
44 | 46 | <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> |
resources/views/employers/menu.blade.php
... | ... | @@ -69,7 +69,7 @@ |
69 | 69 | </i> |
70 | 70 | <span>Избранные кандидаты</span> |
71 | 71 | </a> |
72 | - <a href="{{ route('employer.autolift') }}" class="cabinet__menu-item @if ($item==15 ) active @endif"> | |
72 | + <a href="{{ route('employer.autolift') }}" class="cabinet__menu-item @if ($item==15) active @endif"> | |
73 | 73 | <i> |
74 | 74 | <svg> |
75 | 75 | <use xlink:href="{{ asset('images/sprite.svg#refresh') }}"></use> |
resources/views/employers/vacancy_autolift.blade.php
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | <script> |
4 | 4 | $(document).on('click', '#submit', function () { |
5 | 5 | let data = {}; |
6 | + data.is_enabled = $('[name="is_enabled"]').checked; | |
6 | 7 | data.times_per_day = $('[name="times_per_day"]').chosen().val(); |
7 | 8 | data.days_repeat = $('[name="days_repeat"]').chosen().val(); |
8 | 9 | data.time_send_first = $('[name="time_send_first"]').val(); |
... | ... | @@ -58,11 +59,11 @@ |
58 | 59 | <div class="cabinet__inputs"> |
59 | 60 | <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> |
60 | 61 | <?php |
61 | - $createdAtClone = clone($options->created_at); | |
62 | + $createdAtClone = isset($options->created_at) ? clone($options->created_at) : now(); | |
62 | 63 | $diff = $createdAtClone->addDays($options->days_repeat)->diffInDays($options->created_at); |
63 | 64 | ?> |
64 | 65 | <label class="toggle"> |
65 | - <input type="checkbox" @if($options->is_enabled) checked @endif class="toggle__input js_autoraise_toggle"> | |
66 | + <input type="checkbox" @if($options->is_enabled) checked disabled @endif class="toggle__input js_autoraise_toggle"> | |
66 | 67 | <span class="toggle__icon"></span> |
67 | 68 | <span class="toggle__text">Деактивировано</span> |
68 | 69 | <span class="toggle__text">Активировано</span> |
resources/views/workers/autoresponder.blade.php
... | ... | @@ -0,0 +1,56 @@ |
1 | +@extends('layout.frontend', ['title' => 'Автоответчик']) | |
2 | + | |
3 | +@section('content') | |
4 | + <section class="cabinet"> | |
5 | + <div class="container"> | |
6 | + <ul class="breadcrumbs cabinet__breadcrumbs"> | |
7 | + <li><a href="{{ route('index') }}">Главная</a></li> | |
8 | + <li><b>Личный кабинет</b></li> | |
9 | + </ul> | |
10 | + <div class="cabinet__wrapper"> | |
11 | + <div class="cabinet__side"> | |
12 | + <div class="cabinet__side-toper"> | |
13 | + @include('workers.emblema') | |
14 | + </div> | |
15 | + @include('workers.menu', ['item' => 16]) | |
16 | + </div> | |
17 | + | |
18 | + <form class="cabinet__body" action="{{ route('worker.autoresponder_save') }}"> | |
19 | + <div class="cabinet__body-item"> | |
20 | + <h2 class="title cabinet__title">Автоответчик</h2> | |
21 | + <div class="cabinet__inputs"> | |
22 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> | |
23 | + <label class="toggle"> | |
24 | + <input name="autoresponder" type="checkbox" class="toggle__input" | |
25 | + @if($user->autoresponder) checked @endif> | |
26 | + <span class="toggle__icon"></span> | |
27 | + <span class="toggle__text">Деактивировано</span> | |
28 | + <span class="toggle__text">Активировано</span> | |
29 | + </label> | |
30 | + </div> | |
31 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> | |
32 | + <p>В этом разделе вы сможете задать автоматический ответ на письма, поступающие в | |
33 | + почтовый ящик.</p> | |
34 | + </div> | |
35 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group"> | |
36 | + <label class="form-group__label">Введите текст</label> | |
37 | + <div class="form-group__item"> | |
38 | + <textarea | |
39 | + name="autoresponder_message" | |
40 | + class="textarea" | |
41 | + placeholder="Ваше сообщение" | |
42 | + required | |
43 | + >{{$user->autoresponder_message}}</textarea> | |
44 | + </div> | |
45 | + </div> | |
46 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> | |
47 | + <button type="submit" class="button">Сохранить</button> | |
48 | + </div> | |
49 | + </div> | |
50 | + </div> | |
51 | + </form> | |
52 | + </div> | |
53 | + </div> | |
54 | + </section> | |
55 | + </div> | |
56 | +@endsection |
resources/views/workers/dialog.blade.php
... | ... | @@ -256,7 +256,7 @@ |
256 | 256 | </button> |
257 | 257 | @endif |
258 | 258 | |
259 | - @if($it->ad_employer_id > 0) | |
259 | + @if(\App\Models\Ad_employer::where('id', $it->ad_employer_id)->exists())) | |
260 | 260 | <b>Отклик на вакансию</b> "{{ \App\Models\Ad_employer::find($it->ad_employer_id)->name }}"<br> |
261 | 261 | @if($it->text) |
262 | 262 | <b>Комментарий:</b> {{ $it->text }} |
resources/views/workers/menu.blade.php
... | ... | @@ -26,6 +26,22 @@ |
26 | 26 | </i> |
27 | 27 | <span>Сообщения</span> |
28 | 28 | </a> |
29 | + <a href="{{ route('worker.autolift') }}" class="cabinet__menu-item @if ($item==7) active @endif"> | |
30 | + <i> | |
31 | + <svg> | |
32 | + <use xlink:href="{{ asset('images/sprite.svg#refresh') }}"></use> | |
33 | + </svg> | |
34 | + </i> | |
35 | + <span>Автоподнятие резюме</span> | |
36 | + </a> | |
37 | + <a href="{{ route('worker.autoresponder') }}" class="cabinet__menu-item @if ($item==6) active @endif"> | |
38 | + <i> | |
39 | + <svg> | |
40 | + <use xlink:href="{{ asset('images/sprite.svg#answering') }}"></use> | |
41 | + </svg> | |
42 | + </i> | |
43 | + <span>Автоответчик</span> | |
44 | + </a> | |
29 | 45 | <a href="{{ route('worker.colorado') }}" class="cabinet__menu-item @if ($item==3) active @endif"> |
30 | 46 | <i> |
31 | 47 | <svg> |
resources/views/workers/resume_autolift.blade.php
... | ... | @@ -0,0 +1,204 @@ |
1 | +@extends('layout.frontend', ['title' => 'Автоподнятие вакансий']) | |
2 | +@section('scripts') | |
3 | + <script> | |
4 | + $(document).on('click', '#submit', function () { | |
5 | + let data = {}; | |
6 | + console.log($('[name="is_enabled"]').val()); | |
7 | + data.is_enabled = $('[name="is_enabled"]').val(); | |
8 | + data.times_per_day = $('[name="times_per_day"]').chosen().val(); | |
9 | + data.days_repeat = $('[name="days_repeat"]').chosen().val(); | |
10 | + data.time_send_first = $('[name="time_send_first"]').val(); | |
11 | + data.time_send_second = $('[name="time_send_second"]').val(); | |
12 | + data.time_send_third = $('[name="time_send_third"]').val(); | |
13 | + data.autolift_site = $('[name="autolift_site"]').val(); | |
14 | + | |
15 | + $.ajax({ | |
16 | + url: '{{ route('worker.autolift_save') }}', | |
17 | + type: 'POST', | |
18 | + data: data, | |
19 | + headers: { | |
20 | + 'X-CSRF-TOKEN': '{{ csrf_token() }}' | |
21 | + }, | |
22 | + success: function (result) { | |
23 | + location.reload(); | |
24 | + }, | |
25 | + error: function (result) { | |
26 | + //todo пульнуть какуюнить модалку | |
27 | + }, | |
28 | + }); | |
29 | + }) | |
30 | + </script> | |
31 | +@endsection | |
32 | +@section('content') | |
33 | + <section class="cabinet"> | |
34 | + <div class="container"> | |
35 | + <ul class="breadcrumbs cabinet__breadcrumbs"> | |
36 | + <li><a href="{{ route('index') }}">Главная</a></li> | |
37 | + <li><b>Личный кабинет</b></li> | |
38 | + </ul> | |
39 | + <div class="cabinet__wrapper"> | |
40 | + <div class="cabinet__side"> | |
41 | + <div class="cabinet__side-toper"> | |
42 | + @include('workers.emblema') | |
43 | + </div> | |
44 | + @include('workers.menu', ['item' => 15]) | |
45 | + </div> | |
46 | + <form class="cabinet__body"> | |
47 | + @csrf | |
48 | + <div class="cabinet__body-item"> | |
49 | + <h2 class="title cabinet__title">Автоподнятие вакансий</h2> | |
50 | + <div class="cabinet__inputs"> | |
51 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> | |
52 | + <?php | |
53 | + $createdAtClone = isset($options->created_at) ? clone($options->created_at) : now(); | |
54 | + $diff = $createdAtClone->addDays($options->days_repeat)->diffInDays($options->created_at); | |
55 | + ?> | |
56 | + <label class="toggle"> | |
57 | + <input name="is_enabled" type="checkbox" @if($options->is_enabled) checked disabled @endif class="toggle__input js_autoraise_toggle"> | |
58 | + <span class="toggle__icon"></span> | |
59 | + <span class="toggle__text">Деактивировано</span> | |
60 | + <span class="toggle__text">Активировано</span> | |
61 | + </label> | |
62 | + <p class="mod js_autoraise_prompt @if($options->is_enabled === 1) hidden @endif">Срок действия автоподнятия резюме истек. Желаете его возобновить?</p> | |
63 | + <p class="mod js_autoraise_prompt @if($options->is_enabled === 0) hidden @endif">Автоподнятие резюме продолжит действовать в течение следующих дней: <span>{{$diff}}</span></p> | |
64 | + </div> | |
65 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth form-group"> | |
66 | + <label class="form-group__label">Сколько раз в день необходимо обновлять | |
67 | + вакансии?</label> | |
68 | + <div class="form-group__item"> | |
69 | + <div class="select"> | |
70 | + <select name="times_per_day" class="js-select2 js_autoraise_select"> | |
71 | + <option @if($options['times_per_day'] === null) selected @endif disabled>Выберите вариант из списка</option> | |
72 | + <option @if($options['times_per_day'] === 1) selected @endif value="1">1 раз</option> | |
73 | + <option @if($options['times_per_day'] === 2) selected @endif value="2">2 раза</option> | |
74 | + <option @if($options['times_per_day'] === 3) selected @endif value="3">3 раза</option> | |
75 | + </select> | |
76 | + </div> | |
77 | + </div> | |
78 | + </div> | |
79 | + <label class="cabinet__inputs-item form-group"> | |
80 | + <div class="form-group__label">Выберите первое время обновления (по | |
81 | + МСК)</div> | |
82 | + <div class="form-group__item"> | |
83 | + <span class="form-group__item-icon"> | |
84 | + <svg> | |
85 | + <use xlink:href="images/sprite.svg#date"></use> | |
86 | + </svg> | |
87 | + </span> | |
88 | + <input | |
89 | + name="time_send_first" | |
90 | + type="text" | |
91 | + class="input js-picker input-picker" | |
92 | + placeholder="Время" | |
93 | + value="{{ $options['time_send_first'] }}" | |
94 | + > | |
95 | + </div> | |
96 | + </label> | |
97 | + <label class="cabinet__inputs-item form-group"> | |
98 | + <div class="form-group__label">Выберите второе время обновления (по | |
99 | + МСК)</div> | |
100 | + <div class="form-group__item"> | |
101 | + <span class="form-group__item-icon"> | |
102 | + <svg> | |
103 | + <use xlink:href="images/sprite.svg#date"></use> | |
104 | + </svg> | |
105 | + </span> | |
106 | + <input | |
107 | + name="time_send_second" | |
108 | + type="text" | |
109 | + class="input js-picker input-picker" | |
110 | + placeholder="Время" | |
111 | + value="{{ $options['time_send_second'] }}" | |
112 | + @if($options['times_per_day'] < 2) disabled @endif | |
113 | + > | |
114 | + </div> | |
115 | + </label> | |
116 | + <label class="cabinet__inputs-item form-group"> | |
117 | + <div class="form-group__label">Выберите третье время обновления (по МСК)</div> | |
118 | + <div class="form-group__item"> | |
119 | + <span class="form-group__item-icon"> | |
120 | + <svg> | |
121 | + <use xlink:href="images/sprite.svg#date"></use> | |
122 | + </svg> | |
123 | + </span> | |
124 | + <input | |
125 | + name="time_send_third" | |
126 | + type="text" | |
127 | + class="input js-picker input-picker" | |
128 | + placeholder="Время" | |
129 | + value="{{ $options['time_send_third'] }}" | |
130 | + @if($options['times_per_day'] < 3) disabled @endif | |
131 | + > | |
132 | + </div> | |
133 | + </label> | |
134 | + <div class="cabinet__inputs-item form-group"> | |
135 | + <label class="form-group__label">Выполнять это действие на протяжении</label> | |
136 | + <div class="form-group__item"> | |
137 | + <div class="select"> | |
138 | + <select name="days_repeat" class="js-select2"> | |
139 | + <option @if($options['days_repeat'] === null) selected @endif disabled>Выполнять это действие на протяжении</option> | |
140 | + <option @if($options['days_repeat'] === 1) selected @endif value="1">1 день</option> | |
141 | + <option @if($options['days_repeat'] === 3) selected @endif value="3">3 дня</option> | |
142 | + <option @if($options['days_repeat'] === 5) selected @endif value="5">5 дней</option> | |
143 | + <option @if($options['days_repeat'] === 7) selected @endif value="7">7 дней</option> | |
144 | + <option @if($options['days_repeat'] === 10) selected @endif value="10">10 дней</option> | |
145 | + <option @if($options['days_repeat'] === 15) selected @endif value="15">15 дней</option> | |
146 | + <option @if($options['days_repeat'] === 30) selected @endif value="30">30 дней</option> | |
147 | + </select> | |
148 | + </div> | |
149 | + </div> | |
150 | + </div> | |
151 | + </div> | |
152 | + <div class="table table_spoiler"> | |
153 | + <div class="table__scroll"> | |
154 | + <div class="table__body table__body_min-width"> | |
155 | + <table> | |
156 | + <thead> | |
157 | + <tr> | |
158 | + <th>Название</th> | |
159 | + <th>Обновлять на сайте</th> | |
160 | + </tr> | |
161 | + </thead> | |
162 | + <tbody> | |
163 | + <tr name="resume_table_row" data-id="{{ $worker->id }}"> | |
164 | + <td>Резюме</td> | |
165 | + <td > | |
166 | + <span class="checkbox-empty"> | |
167 | + <label class="checkbox"> | |
168 | + <input | |
169 | + type="checkbox" | |
170 | + class="checkbox__input" | |
171 | + @if($options->autolift_site) checked @endif | |
172 | + name="autolift_site" | |
173 | + > | |
174 | + <span class="checkbox__icon"> | |
175 | + <svg> | |
176 | + <use xlink:href="{{ asset('images/sprite.svg#v') }}"></use> | |
177 | + </svg> | |
178 | + </span> | |
179 | + </label> | |
180 | + </span> | |
181 | + </td> | |
182 | + </tr> | |
183 | + </tbody> | |
184 | + </table> | |
185 | + </div> | |
186 | + </div> | |
187 | + <div class="mrg-wrapper" style="display: flex; justify-content: center; clear: both;"> | |
188 | + <ins class="mrg-tag" data-ad-client="ad-595528" data-ad-slot="595528" style="display: flex; align-items: center; justify-content: center; width: 300px; z-index: 1;"> | |
189 | + | |
190 | + </ins> | |
191 | + </div> | |
192 | + </div> | |
193 | + <div class="cabinet__inputs"> | |
194 | + <div class="cabinet__inputs-item cabinet__inputs-item_fullwidth"> | |
195 | + <button id="submit" type="button" class="button">Сохранить</button> | |
196 | + </div> | |
197 | + </div> | |
198 | + </div> | |
199 | + </form> | |
200 | + </div> | |
201 | + </div> | |
202 | + </section> | |
203 | + </div> | |
204 | +@endsection |
routes/web.php
... | ... | @@ -529,6 +529,12 @@ Route::group([ |
529 | 529 | Route::post('сообщение/', [WorkerController::class, 'new_message']) |
530 | 530 | ->withoutMiddleware('is_worker') |
531 | 531 | ->name('new_message'); |
532 | + | |
533 | + Route::get('cabinet/autoresponder', [WorkerController::class, 'autoresponder'])->name('autoresponder'); | |
534 | + Route::get('cabinet/autoresponder_save', [WorkerController::class, 'autoresponderSave'])->name('autoresponder_save'); | |
535 | + | |
536 | + Route::get('cabinet/autolift', [WorkerController::class, 'resumeAutoLiftForm'])->name('autolift'); | |
537 | + Route::post('cabinet/autolift/save', [WorkerController::class, 'resumeAutoLiftSave'])->name('autolift_save'); | |
532 | 538 | }); |
533 | 539 | |
534 | 540 | // Личный кабинет работодателя |