add feature do not show again job for parent portal
This commit is contained in:
@@ -1290,6 +1290,7 @@ $routes->get('/landing_page/admin_dashboard', 'View\LandingPageController::admin
|
|||||||
$routes->get('/teacher_dashboard', 'View\LandingPageController::teacher', ['filter' => 'auth:teacher_dashboard,read']);
|
$routes->get('/teacher_dashboard', 'View\LandingPageController::teacher', ['filter' => 'auth:teacher_dashboard,read']);
|
||||||
$routes->get('/landing_page/student_dashboard', 'View\LandingPageController::student', ['filter' => 'auth:student_dashboard,read']);
|
$routes->get('/landing_page/student_dashboard', 'View\LandingPageController::student', ['filter' => 'auth:student_dashboard,read']);
|
||||||
$routes->get('/parent_dashboard', 'View\LandingPageController::parentDashboard', ['filter' => 'auth:parent_dashboard,read']);
|
$routes->get('/parent_dashboard', 'View\LandingPageController::parentDashboard', ['filter' => 'auth:parent_dashboard,read']);
|
||||||
|
$routes->post('/parent_dashboard/job-openings-popup', 'View\LandingPageController::hideJobOpeningsPopup', ['filter' => 'auth:parent_dashboard,read']);
|
||||||
$routes->get('/landing_page/guest_dashboard', 'View\LandingPageController::guest', ['filter' => 'auth:guest_dashboard,read']);
|
$routes->get('/landing_page/guest_dashboard', 'View\LandingPageController::guest', ['filter' => 'auth:guest_dashboard,read']);
|
||||||
$routes->get('/dashboard', 'View\LandingPageController::index');
|
$routes->get('/dashboard', 'View\LandingPageController::index');
|
||||||
$routes->get('/access_denied', 'ErrorController::accessDenied');
|
$routes->get('/access_denied', 'ErrorController::accessDenied');
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use App\Models\AttendanceRecordModel;
|
|||||||
use App\Models\AttendanceDayModel;
|
use App\Models\AttendanceDayModel;
|
||||||
use App\Models\CalendarModel;
|
use App\Models\CalendarModel;
|
||||||
use App\Models\JobPositionModel;
|
use App\Models\JobPositionModel;
|
||||||
|
use App\Models\PreferencesModel;
|
||||||
use \Config\Database;
|
use \Config\Database;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
@@ -775,39 +776,6 @@ class LandingPageController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fetch Notifications (only active, non-expired, non-deleted)
|
|
||||||
$notifications = $this->db->table('notifications')
|
|
||||||
->select([
|
|
||||||
'notifications.id',
|
|
||||||
'notifications.title',
|
|
||||||
'notifications.message',
|
|
||||||
'notifications.target_group',
|
|
||||||
'notifications.created_at',
|
|
||||||
'notifications.expires_at',
|
|
||||||
'user_notifications.user_id',
|
|
||||||
"CASE
|
|
||||||
WHEN user_notifications.user_id IS NOT NULL THEN 'personal'
|
|
||||||
ELSE 'broadcast'
|
|
||||||
END as notification_type"
|
|
||||||
])
|
|
||||||
->join(
|
|
||||||
'user_notifications',
|
|
||||||
'user_notifications.notification_id = notifications.id AND user_notifications.user_id = ' . (int) $parentId,
|
|
||||||
'left'
|
|
||||||
)
|
|
||||||
->groupStart()
|
|
||||||
->where('notifications.target_group', 'parent')
|
|
||||||
->orWhere('user_notifications.user_id', $parentId)
|
|
||||||
->groupEnd()
|
|
||||||
->where('notifications.deleted_at IS NULL') // Exclude soft-deleted notifications
|
|
||||||
->groupStart()
|
|
||||||
->where('notifications.expires_at IS NULL')
|
|
||||||
->orWhere('notifications.expires_at > NOW()') // Exclude expired
|
|
||||||
->groupEnd()
|
|
||||||
->orderBy('notifications.created_at', 'DESC')
|
|
||||||
->get()
|
|
||||||
->getResultArray();
|
|
||||||
|
|
||||||
// Fetch Student Information (no filtering needed by school year or semester)
|
// Fetch Student Information (no filtering needed by school year or semester)
|
||||||
|
|
||||||
$students = $this->db->table('students')
|
$students = $this->db->table('students')
|
||||||
@@ -823,6 +791,8 @@ class LandingPageController extends BaseController
|
|||||||
}
|
}
|
||||||
unset($student);
|
unset($student);
|
||||||
|
|
||||||
|
$notifications = $this->parentDashboardNotifications((int) $parentId, (int) session()->get('user_id'));
|
||||||
|
|
||||||
|
|
||||||
// Fetch Attendance Records (filtered by most recent school year and semester)
|
// Fetch Attendance Records (filtered by most recent school year and semester)
|
||||||
$attendanceData = $this->db->table('attendance_data')
|
$attendanceData = $this->db->table('attendance_data')
|
||||||
@@ -870,12 +840,14 @@ class LandingPageController extends BaseController
|
|||||||
$paymentBalance = (float) ($paymentRow['account_balance'] ?? 0);
|
$paymentBalance = (float) ($paymentRow['account_balance'] ?? 0);
|
||||||
$openPositions = [];
|
$openPositions = [];
|
||||||
|
|
||||||
try {
|
if (! $this->parentHidesJobOpeningsPopup($parentId)) {
|
||||||
if ($this->db->tableExists('job_positions')) {
|
try {
|
||||||
$openPositions = (new JobPositionModel())->openPositions();
|
if ($this->db->tableExists('job_positions')) {
|
||||||
|
$openPositions = (new JobPositionModel())->openPositions();
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
log_message('error', 'Unable to load parent dashboard job positions: ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
|
||||||
log_message('error', 'Unable to load parent dashboard job positions: ' . $e->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass data to the view, including the deadlines
|
// Pass data to the view, including the deadlines
|
||||||
@@ -892,6 +864,255 @@ class LandingPageController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hideJobOpeningsPopup()
|
||||||
|
{
|
||||||
|
$userId = (int) (session()->get('user_id') ?? 0);
|
||||||
|
if ($userId <= 0) {
|
||||||
|
return $this->response->setStatusCode(401)->setJSON([
|
||||||
|
'ok' => false,
|
||||||
|
'error' => 'Please log in to update this setting.',
|
||||||
|
'csrf_token' => csrf_token(),
|
||||||
|
'csrf_hash' => csrf_hash(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
! $this->db->tableExists('user_preferences')
|
||||||
|
|| ! $this->db->fieldExists('hide_job_openings_popup', 'user_preferences')
|
||||||
|
) {
|
||||||
|
return $this->response->setStatusCode(500)->setJSON([
|
||||||
|
'ok' => false,
|
||||||
|
'error' => 'Preference storage is not ready.',
|
||||||
|
'csrf_token' => csrf_token(),
|
||||||
|
'csrf_hash' => csrf_hash(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hide = (string) $this->request->getPost('hide_job_openings_popup') === '1' ? 1 : 0;
|
||||||
|
$preferencesModel = new PreferencesModel();
|
||||||
|
$existing = $preferencesModel->where('user_id', $userId)->first();
|
||||||
|
|
||||||
|
if ($existing) {
|
||||||
|
$preferencesModel->update((int) $existing['id'], [
|
||||||
|
'hide_job_openings_popup' => $hide,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$preferencesModel->insert([
|
||||||
|
'user_id' => $userId,
|
||||||
|
'hide_job_openings_popup' => $hide,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'ok' => true,
|
||||||
|
'hide_job_openings_popup' => $hide,
|
||||||
|
'csrf_token' => csrf_token(),
|
||||||
|
'csrf_hash' => csrf_hash(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parentHidesJobOpeningsPopup(int $parentId): bool
|
||||||
|
{
|
||||||
|
if ($parentId <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
! $this->db->tableExists('user_preferences')
|
||||||
|
|| ! $this->db->fieldExists('hide_job_openings_popup', 'user_preferences')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$preferences = (new PreferencesModel())->where('user_id', $parentId)->first();
|
||||||
|
|
||||||
|
return ! empty($preferences['hide_job_openings_popup']);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
log_message('error', 'Unable to load parent job openings popup preference: ' . $e->getMessage());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parentDashboardNotifications(int $parentId, int $userId): array
|
||||||
|
{
|
||||||
|
$notifications = array_merge(
|
||||||
|
$this->parentAttendanceNotifications($parentId),
|
||||||
|
$this->activeParentBroadcastNotifications($parentId, $userId)
|
||||||
|
);
|
||||||
|
|
||||||
|
usort($notifications, static function (array $a, array $b): int {
|
||||||
|
return strtotime((string) ($b['created_at'] ?? '')) <=> strtotime((string) ($a['created_at'] ?? ''));
|
||||||
|
});
|
||||||
|
|
||||||
|
return array_slice($notifications, 0, 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parentAttendanceNotifications(int $parentId): array
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
$parentId <= 0
|
||||||
|
|| ! $this->db->tableExists('parent_notifications')
|
||||||
|
|| ! $this->db->tableExists('students')
|
||||||
|
) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = $this->db->table('parent_notifications pn')
|
||||||
|
->select([
|
||||||
|
'pn.id',
|
||||||
|
'pn.student_id',
|
||||||
|
'pn.code',
|
||||||
|
'pn.incident_date',
|
||||||
|
'pn.channel',
|
||||||
|
'pn.subject',
|
||||||
|
'pn.status',
|
||||||
|
'pn.response',
|
||||||
|
'pn.semester',
|
||||||
|
'pn.school_year',
|
||||||
|
'pn.created_at',
|
||||||
|
'pn.updated_at',
|
||||||
|
'students.firstname',
|
||||||
|
'students.lastname',
|
||||||
|
])
|
||||||
|
->join('students', 'students.id = pn.student_id')
|
||||||
|
->where('students.parent_id', $parentId)
|
||||||
|
->where('pn.school_year', (string) $this->schoolYear)
|
||||||
|
->where('pn.semester', (string) $this->semester)
|
||||||
|
->orderBy('COALESCE(pn.updated_at, pn.created_at)', 'DESC', false)
|
||||||
|
->orderBy('pn.id', 'DESC')
|
||||||
|
->limit(100)
|
||||||
|
->get()
|
||||||
|
->getResultArray();
|
||||||
|
|
||||||
|
$notifications = [];
|
||||||
|
$seen = [];
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$key = implode('|', [
|
||||||
|
(string) ($row['student_id'] ?? ''),
|
||||||
|
(string) ($row['code'] ?? ''),
|
||||||
|
(string) ($row['incident_date'] ?? ''),
|
||||||
|
(string) ($row['subject'] ?? ''),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (isset($seen[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$seen[$key] = true;
|
||||||
|
$studentName = trim((string) ($row['firstname'] ?? '') . ' ' . (string) ($row['lastname'] ?? ''));
|
||||||
|
$code = strtoupper((string) ($row['code'] ?? ''));
|
||||||
|
$incidentDate = (string) ($row['incident_date'] ?? '');
|
||||||
|
$subject = trim((string) ($row['subject'] ?? ''));
|
||||||
|
|
||||||
|
$title = $subject !== '' ? $subject : $this->parentNotificationCodeLabel($code);
|
||||||
|
if ($studentName !== '') {
|
||||||
|
$title .= ' - ' . $studentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
$messageParts = [];
|
||||||
|
if ($incidentDate !== '') {
|
||||||
|
$messageParts[] = 'Incident date: ' . $incidentDate;
|
||||||
|
}
|
||||||
|
if (!empty($row['status'])) {
|
||||||
|
$messageParts[] = 'Status: ' . ucfirst((string) $row['status']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$notifications[] = [
|
||||||
|
'id' => $row['id'] ?? null,
|
||||||
|
'title' => $title,
|
||||||
|
'message' => implode(' | ', $messageParts),
|
||||||
|
'created_at' => $row['updated_at'] ?: ($row['created_at'] ?? null),
|
||||||
|
'notification_type' => $this->parentNotificationCodeLabel($code),
|
||||||
|
'status' => $row['status'] ?? null,
|
||||||
|
'code' => $code,
|
||||||
|
'incident_date' => $incidentDate,
|
||||||
|
'student_name' => $studentName,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (count($notifications) >= 25) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function activeParentBroadcastNotifications(int $parentId, int $userId): array
|
||||||
|
{
|
||||||
|
if ($parentId <= 0 || ! $this->db->tableExists('notifications')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder = $this->db->table('notifications')
|
||||||
|
->select([
|
||||||
|
'notifications.id',
|
||||||
|
'notifications.title',
|
||||||
|
'notifications.message',
|
||||||
|
'notifications.target_group',
|
||||||
|
'notifications.created_at',
|
||||||
|
'notifications.expires_at',
|
||||||
|
"CASE
|
||||||
|
WHEN user_notifications.user_id IS NOT NULL THEN 'personal'
|
||||||
|
ELSE 'broadcast'
|
||||||
|
END as notification_type",
|
||||||
|
])
|
||||||
|
->join(
|
||||||
|
'user_notifications',
|
||||||
|
'user_notifications.notification_id = notifications.id AND user_notifications.user_id IN (' . implode(',', array_unique([$parentId, $userId])) . ')',
|
||||||
|
'left'
|
||||||
|
)
|
||||||
|
->groupStart()
|
||||||
|
->whereIn('notifications.target_group', ['parent', 'everyone'])
|
||||||
|
->orWhere('user_notifications.user_id IS NOT NULL')
|
||||||
|
->groupEnd()
|
||||||
|
->where('notifications.deleted_at IS NULL')
|
||||||
|
->groupStart()
|
||||||
|
->where('notifications.scheduled_at IS NULL')
|
||||||
|
->orWhere('notifications.scheduled_at <=', utc_now())
|
||||||
|
->groupEnd()
|
||||||
|
->groupStart()
|
||||||
|
->where('notifications.expires_at IS NULL')
|
||||||
|
->orWhere('notifications.expires_at >', utc_now())
|
||||||
|
->groupEnd();
|
||||||
|
|
||||||
|
if ($this->db->fieldExists('school_year', 'notifications')) {
|
||||||
|
$builder->where('notifications.school_year', (string) $this->schoolYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->db->fieldExists('semester', 'notifications')) {
|
||||||
|
$builder->groupStart()
|
||||||
|
->where('notifications.semester', null)
|
||||||
|
->orWhere('notifications.semester', '')
|
||||||
|
->orWhere('notifications.semester', (string) $this->semester)
|
||||||
|
->groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $builder
|
||||||
|
->groupBy('notifications.id')
|
||||||
|
->orderBy('notifications.created_at', 'DESC')
|
||||||
|
->limit(25)
|
||||||
|
->get()
|
||||||
|
->getResultArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parentNotificationCodeLabel(string $code): string
|
||||||
|
{
|
||||||
|
return match ($code) {
|
||||||
|
'ABS_1' => 'Unreported absence',
|
||||||
|
'ABS_2' => 'Repeated absences',
|
||||||
|
'ABS_3' => 'Attendance warning',
|
||||||
|
'ABS_4' => 'Attendance review',
|
||||||
|
'LATE_2' => 'Repeated lateness',
|
||||||
|
'LATE_3' => 'Lateness warning',
|
||||||
|
'LATE_4' => 'Lateness review',
|
||||||
|
'MIX_L2A1' => 'Attendance warning',
|
||||||
|
default => 'Parent notice',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public function guest()
|
public function guest()
|
||||||
{
|
{
|
||||||
return view('/landing_page/guest_dashboard');
|
return view('/landing_page/guest_dashboard');
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Database\Migrations;
|
||||||
|
|
||||||
|
use CodeIgniter\Database\Migration;
|
||||||
|
|
||||||
|
class AddHideJobOpeningsPopupToPreferences extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (! $this->db->tableExists('user_preferences')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->db->fieldExists('hide_job_openings_popup', 'user_preferences')) {
|
||||||
|
$definition = [
|
||||||
|
'type' => 'TINYINT',
|
||||||
|
'constraint' => 1,
|
||||||
|
'default' => 0,
|
||||||
|
'null' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->db->fieldExists('menu_custom_mode', 'user_preferences')) {
|
||||||
|
$definition['after'] = 'menu_custom_mode';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->forge->addColumn('user_preferences', [
|
||||||
|
'hide_job_openings_popup' => $definition,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
$this->db->tableExists('user_preferences')
|
||||||
|
&& $this->db->fieldExists('hide_job_openings_popup', 'user_preferences')
|
||||||
|
) {
|
||||||
|
$this->forge->dropColumn('user_preferences', 'hide_job_openings_popup');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ final class SchoolYearWritableFilter implements FilterInterface
|
|||||||
'api/register',
|
'api/register',
|
||||||
'user/select_role',
|
'user/select_role',
|
||||||
'set-role',
|
'set-role',
|
||||||
|
'parent_dashboard/job-openings-popup',
|
||||||
'processForgotPassword',
|
'processForgotPassword',
|
||||||
'user/forgot_password',
|
'user/forgot_password',
|
||||||
'user/processResetPassword',
|
'user/processResetPassword',
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class PreferencesModel extends Model
|
|||||||
'menu_custom_bg', // Custom menu background color
|
'menu_custom_bg', // Custom menu background color
|
||||||
'menu_custom_text', // Custom menu text color
|
'menu_custom_text', // Custom menu text color
|
||||||
'menu_custom_mode', // Custom menu mode: light|dark
|
'menu_custom_mode', // Custom menu mode: light|dark
|
||||||
|
'hide_job_openings_popup', // Parent dismissed volunteer openings popup
|
||||||
'created_at', // Timestamp of when the record was created
|
'created_at', // Timestamp of when the record was created
|
||||||
'updated_at' // Timestamp of when the record was last updated
|
'updated_at' // Timestamp of when the record was last updated
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -71,14 +71,18 @@
|
|||||||
<ul class="mb-0 ps-3">
|
<ul class="mb-0 ps-3">
|
||||||
<?php foreach ($notifications as $n): ?>
|
<?php foreach ($notifications as $n): ?>
|
||||||
<li class="mb-2">
|
<li class="mb-2">
|
||||||
<strong><?= esc($n['title']) ?></strong><br>
|
<strong><?= esc($n['title'] ?? 'Notification') ?></strong><br>
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
<?= isset($n['created_at']) && strtotime($n['created_at'])
|
<?= isset($n['created_at']) && strtotime($n['created_at'])
|
||||||
? esc(local_datetime($n['created_at'], 'm-d-Y H:i'))
|
? esc(local_datetime($n['created_at'], 'm-d-Y H:i'))
|
||||||
: 'No date' ?>
|
: 'No date' ?>
|
||||||
</small>
|
</small>
|
||||||
|
<?php if (!empty($n['message'] ?? '')): ?>
|
||||||
|
<br>
|
||||||
|
<span><?= esc($n['message']) ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
<br>
|
<br>
|
||||||
<span class="badge bg-light text-dark"><?= ucfirst($n['notification_type'] ?? 'broadcast') ?></span>
|
<span class="badge bg-light text-dark"><?= esc(ucfirst((string) ($n['notification_type'] ?? 'notice'))) ?></span>
|
||||||
</li>
|
</li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -256,6 +260,20 @@
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
<div class="form-check me-auto text-start">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
type="checkbox"
|
||||||
|
value="1"
|
||||||
|
id="hideJobOpeningsPopup"
|
||||||
|
data-save-url="<?= esc(site_url('parent_dashboard/job-openings-popup')) ?>"
|
||||||
|
data-csrf-name="<?= esc(csrf_token()) ?>"
|
||||||
|
data-csrf-value="<?= esc(csrf_hash()) ?>">
|
||||||
|
<label class="form-check-label" for="hideJobOpeningsPopup">
|
||||||
|
Do not show again
|
||||||
|
</label>
|
||||||
|
<div class="small text-muted d-none" id="hideJobOpeningsPopupStatus"></div>
|
||||||
|
</div>
|
||||||
<a class="btn btn-outline-secondary" href="<?= site_url('careers') ?>">View all openings</a>
|
<a class="btn btn-outline-secondary" href="<?= site_url('careers') ?>">View all openings</a>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -276,6 +294,68 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
bootstrap.Modal.getOrCreateInstance(modalEl).show();
|
bootstrap.Modal.getOrCreateInstance(modalEl).show();
|
||||||
|
|
||||||
|
const checkbox = document.getElementById('hideJobOpeningsPopup');
|
||||||
|
const statusEl = document.getElementById('hideJobOpeningsPopupStatus');
|
||||||
|
if (!checkbox) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox.addEventListener('change', async function () {
|
||||||
|
if (!checkbox.checked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox.disabled = true;
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.classList.remove('d-none', 'text-danger');
|
||||||
|
statusEl.classList.add('text-muted');
|
||||||
|
statusEl.textContent = 'Saving preference...';
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = new FormData();
|
||||||
|
let csrfName = checkbox.dataset.csrfName || '';
|
||||||
|
let csrfValue = checkbox.dataset.csrfValue || '';
|
||||||
|
body.append('hide_job_openings_popup', '1');
|
||||||
|
if (csrfName && csrfValue) {
|
||||||
|
body.append(csrfName, csrfValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(checkbox.dataset.saveUrl || '', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
...(csrfValue ? { 'X-CSRF-TOKEN': csrfValue } : {})
|
||||||
|
},
|
||||||
|
body
|
||||||
|
});
|
||||||
|
const data = await response.json().catch(function () {
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.csrf_token && data.csrf_hash) {
|
||||||
|
checkbox.dataset.csrfName = data.csrf_token;
|
||||||
|
checkbox.dataset.csrfValue = data.csrf_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.ok || !data.ok) {
|
||||||
|
throw new Error(data.error || 'Unable to save preference.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.textContent = 'Saved.';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
checkbox.checked = false;
|
||||||
|
checkbox.disabled = false;
|
||||||
|
if (statusEl) {
|
||||||
|
statusEl.classList.remove('d-none', 'text-muted');
|
||||||
|
statusEl.classList.add('text-danger');
|
||||||
|
statusEl.textContent = error.message || 'Unable to save preference.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<?= $this->endSection() ?>
|
<?= $this->endSection() ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user