extractDateValue($event) : $this->normalizeDateValue($event['date'] ?? null); $event = $event instanceof CalendarEvent ? $event->toArray() : $event; $audience = $audience !== null ? strtolower(trim($audience)) : null; $p = (int) ($event['notify_parent'] ?? 0); $t = (int) ($event['notify_teacher'] ?? 0); $a = (int) ($event['notify_admin'] ?? 0); $ns = (int) ($event['no_school'] ?? 0); $backgroundColor = null; if (in_array($audience, ['teacher', 'parent'], true) && $ns === 1) { $backgroundColor = '#ffc107'; } if (in_array($audience, ['teacher', 'admin'], true) && $backgroundColor === null) { $isStaffOnly = ($p === 0 && ($t === 1 || $a === 1) && $ns === 0); if ($isStaffOnly) { $backgroundColor = '#28a745'; } } $title = (string) ($event['title'] ?? 'Untitled'); if ($ns === 1) { $title = preg_replace('/\bno\s*[- ]\s*school\b/i', 'No School', $title); } return [ 'id' => (int) ($event['id'] ?? 0), 'title' => $title, 'start' => $eventDate, 'description' => (string) ($event['description'] ?? ''), 'backgroundColor' => $backgroundColor, 'extendedProps' => [ 'semester' => (string) ($event['semester'] ?? ''), 'school_year' => (string) ($event['school_year'] ?? ''), 'event_type' => $event['event_type'] ?? null, 'notify_parent' => $p, 'notify_teacher' => $t, 'notify_admin' => $a, 'no_school' => $ns, 'backgroundColor' => $backgroundColor, ], ]; } private function extractDateValue(CalendarEvent $event): string { $raw = $event->getRawOriginal('date'); if (is_string($raw) && trim($raw) !== '') { return $this->normalizeDateValue($raw); } $value = $event->getAttribute('date'); if ($value instanceof CarbonInterface) { return $value->toDateString(); } return $this->normalizeDateValue($value); } private function normalizeDateValue(mixed $value): string { if ($value instanceof CarbonInterface) { return $value->toDateString(); } $value = trim((string) $value); if ($value === '') { return ''; } if (preg_match('/^\d{4}-\d{2}-\d{2}/', $value, $matches) === 1) { return $matches[0]; } try { return Carbon::parse($value)->toDateString(); } catch (\Throwable) { return $value; } } public function formatMeetingEvent(array $row, ?string $audience = null): array { $audience = $audience !== null ? strtolower(trim($audience)) : null; $parentName = (string) ($row['parent_name'] ?? 'Parent'); $studentName = (string) ($row['student_name'] ?? 'Student'); $time = trim((string) ($row['time'] ?? '')); $timeLabel = $time !== '' ? (' '.$time) : ''; $title = $audience === 'admin' ? 'Admin Meeting' : 'Parent Meeting'; $descParts = []; $descParts[] = 'Student: '.$studentName; $descParts[] = 'Parent: '.$parentName; if (! empty($row['class_section_name'])) { $descParts[] = 'Section: '.$row['class_section_name']; } $descParts[] = 'Date/Time: '.($row['date'] ?? '').$timeLabel; if (! empty($row['notes'])) { $descParts[] = 'Notes: '.$row['notes']; } $start = (string) ($row['date'] ?? ''); if ($start !== '' && $time !== '') { $start = $start.'T'.$time; } return [ 'id' => 'pm-'.(int) ($row['id'] ?? 0), 'title' => $title, 'start' => $start, 'description' => implode("\n", $descParts), 'backgroundColor' => '#6f42c1', 'extendedProps' => [ 'semester' => (string) ($row['semester'] ?? ''), 'school_year' => (string) ($row['school_year'] ?? ''), 'notify_parent' => 1, 'notify_admin' => 1, 'notify_teacher' => 0, 'no_school' => 0, 'backgroundColor' => '#6f42c1', ], ]; } }