add feature do not show again job for parent portal
This commit is contained in:
@@ -14,6 +14,7 @@ use App\Models\AttendanceRecordModel;
|
||||
use App\Models\AttendanceDayModel;
|
||||
use App\Models\CalendarModel;
|
||||
use App\Models\JobPositionModel;
|
||||
use App\Models\PreferencesModel;
|
||||
use \Config\Database;
|
||||
use DateTimeImmutable;
|
||||
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)
|
||||
|
||||
$students = $this->db->table('students')
|
||||
@@ -823,6 +791,8 @@ class LandingPageController extends BaseController
|
||||
}
|
||||
unset($student);
|
||||
|
||||
$notifications = $this->parentDashboardNotifications((int) $parentId, (int) session()->get('user_id'));
|
||||
|
||||
|
||||
// Fetch Attendance Records (filtered by most recent school year and semester)
|
||||
$attendanceData = $this->db->table('attendance_data')
|
||||
@@ -870,12 +840,14 @@ class LandingPageController extends BaseController
|
||||
$paymentBalance = (float) ($paymentRow['account_balance'] ?? 0);
|
||||
$openPositions = [];
|
||||
|
||||
try {
|
||||
if ($this->db->tableExists('job_positions')) {
|
||||
$openPositions = (new JobPositionModel())->openPositions();
|
||||
if (! $this->parentHidesJobOpeningsPopup($parentId)) {
|
||||
try {
|
||||
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
|
||||
@@ -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()
|
||||
{
|
||||
return view('/landing_page/guest_dashboard');
|
||||
|
||||
Reference in New Issue
Block a user