{{-- ============================================================================ PAGE CONTENT — Kalendar Aktiviti (NRES) Site : nres · Page slug: calender · Page ID: 29 Sumber: modul content-calendar · content_calendar → tarikh, masa, kategori, status, jenis · content_calendar_translation → tajuk, lokasi, agenda (ikut bahasa) Konsep: https://www.kpwkm.gov.my/portal-main/calendar (grid bulan + senarai aktiviti bulan ini + navigasi bulan) Parameter URL: bulan YYYY-MM bulan yang dipaparkan (lalai: bulan semasa) tarikh YYYY-MM-DD hari terpilih → panel butiran hari itu kategori kod CALENDAR_CATEGORY (EVENT/MEETING/WORKSHOP/SEMINAR/OTHER) Nota: · SEMUA logik + markup + CSS ada dalam fail ini — tiada komponen, tiada partial. · Hanya acara calendar_status = ACTIVE dan calendar_type = PUBLIC dipaparkan. · Acara berbilang hari (calendar_date_end) ditanda pada SETIAP hari dalam julat. · Tajuk/lokasi/agenda ikut bahasa semasa ($lang) → fallback ke terjemahan "main". · Warna guna CSS variable tema (--teal/--green/--fade/--line/--ink) → dark mode. ============================================================================ --}} @php /* -------------------------------------------------------------------- | 1. Parameter URL + bulan yang dipaparkan -------------------------------------------------------------------- */ $calBase = url()->current(); // URL halaman (tanpa query) $calQuery = request()->query(); $calLang = ($lang ?? session('locale', 'ms')) === 'en' ? 'en' : 'ms'; $calBulan = (string) ($calQuery['bulan'] ?? ''); $calTarikh = (string) ($calQuery['tarikh'] ?? ''); $calKat = (string) ($calQuery['kategori'] ?? ''); if (! preg_match('/^\d{4}-\d{2}$/', $calBulan)) { $calBulan = now()->format('Y-m'); } try { $calStart = \Carbon\Carbon::createFromFormat('Y-m-d', $calBulan.'-01')->startOfMonth(); } catch (\Throwable $e) { $calBulan = now()->format('Y-m'); $calStart = now()->startOfMonth(); } $calEnd = $calStart->copy()->endOfMonth(); $calToday = now()->startOfDay(); /* -------------------------------------------------------------------- | 2. Nama bulan & hari (BM) — dipaparkan ikut bahasa halaman -------------------------------------------------------------------- */ $calMonthNames = [ 1 => 'Januari', 2 => 'Februari', 3 => 'Mac', 4 => 'April', 5 => 'Mei', 6 => 'Jun', 7 => 'Julai', 8 => 'Ogos', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Disember', ]; $calMonthNamesEn = [ 1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December', ]; $calDayNames = $calLang === 'en' ? ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] : ['Ahad', 'Isnin', 'Selasa', 'Rabu', 'Khamis', 'Jumaat', 'Sabtu']; $calAllLabel = $calLang === 'en' ? 'All' : 'Semua'; $calMonthLabel = ($calLang === 'en' ? $calMonthNamesEn : $calMonthNames)[(int) $calStart->month].' '.$calStart->year; /* -------------------------------------------------------------------- | 3. Rujukan kategori (warna + label ikut bahasa) -------------------------------------------------------------------- */ $calCatRefs = DB::table('ref')->where('cat', 'CALENDAR_CATEGORY')->orderBy('sort')->get(); $calCatLabel = []; foreach ($calCatRefs as $calRef) { $calCatLabel[(string) $calRef->code] = $calLang === 'en' ? ((string) ($calRef->descr_en ?: $calRef->descr)) : ((string) ($calRef->descr ?: $calRef->descr_en)); } $calCatColor = [ 'EVENT' => '#11808f', 'MEETING' => '#165c4a', 'WORKSHOP' => '#b45309', 'SEMINAR' => '#6d28d9', 'OTHER' => '#64748b', ]; if ($calKat !== '' && ! isset($calCatLabel[$calKat])) { $calKat = ''; } $calCatName = fn ($code) => $calCatLabel[(string) $code] ?? (string) $code; $calCatTint = fn ($code) => $calCatColor[(string) $code] ?? '#64748b'; // Masa: format seperti admin (h:i A) bila boleh di-parse; jika teks bebas, kekal asal $calTime = function ($value) { $value = trim((string) $value); if ($value === '') { return ''; } try { return \Carbon\Carbon::parse($value)->format('h:i A'); } catch (\Throwable $e) { return $value; } }; /* -------------------------------------------------------------------- | 4. Pembina URL (kekalkan bulan, buang parameter yang dikosongkan) -------------------------------------------------------------------- */ $calUrl = function (array $params = []) use ($calBase, $calBulan, $calKat, $calTarikh) { $query = array_filter([ 'bulan' => array_key_exists('bulan', $params) ? $params['bulan'] : $calBulan, 'kategori' => array_key_exists('kategori', $params) ? $params['kategori'] : $calKat, 'tarikh' => array_key_exists('tarikh', $params) ? $params['tarikh'] : $calTarikh, ], fn ($v) => $v !== null && $v !== ''); return $query ? $calBase.'?'.http_build_query($query) : $calBase; }; /* -------------------------------------------------------------------- | 5. Ambil acara yang bersinggungan dengan bulan ini | (status ACTIVE + jenis PUBLIC sahaja) -------------------------------------------------------------------- */ $calRows = DB::table('content_calendar as c') ->where('c.calendar_status', 'ACTIVE') ->where('c.calendar_type', 'PUBLIC') ->whereNotNull('c.calendar_date_start') ->whereDate('c.calendar_date_start', '<=', $calEnd->toDateString()) ->whereRaw('COALESCE(c.calendar_date_end, c.calendar_date_start) >= ?', [$calStart->toDateString()]) ->orderBy('c.calendar_date_start') ->orderBy('c.calendar_time_start') ->get(); $calRowIds = $calRows->pluck('calendar_id')->all(); $calTranslations = $calRowIds ? DB::table('content_calendar_translation') ->whereIn('calendar_translation_parent_id', $calRowIds) ->get() ->groupBy('calendar_translation_parent_id') : collect(); /* -------------------------------------------------------------------- | 6. Bina senarai acara (view model) -------------------------------------------------------------------- */ $calItems = []; foreach ($calRows as $calRow) { $calTr = $calTranslations[$calRow->calendar_id] ?? collect(); // Keutamaan: bahasa semasa → terjemahan "main" → terjemahan pertama $calTr = $calTr->firstWhere('calendar_translation_language', $calLang) ?? $calTr->firstWhere('calendar_translation_main', 1) ?? $calTr->first(); if (! $calTr || blank($calTr->calendar_translation_title)) { continue; // acara tanpa tajuk — langkau } $calFrom = \Carbon\Carbon::parse($calRow->calendar_date_start)->startOfDay(); $calTo = $calRow->calendar_date_end ? \Carbon\Carbon::parse($calRow->calendar_date_end)->startOfDay() : $calFrom->copy(); if ($calTo->lt($calFrom)) { $calTo = $calFrom->copy(); } $calItems[] = [ 'id' => (int) $calRow->calendar_id, 'title' => (string) $calTr->calendar_translation_title, 'location' => (string) ($calTr->calendar_translation_location ?? ''), 'agenda' => (string) ($calTr->calendar_translation_content ?? ''), 'from' => $calFrom, 'to' => $calTo, 'time_start' => (string) ($calRow->calendar_time_start ?? ''), 'time_end' => (string) ($calRow->calendar_time_end ?? ''), 'category' => (string) ($calRow->calendar_category ?? ''), 'participant' => $calRow->total_participant !== null ? (int) $calRow->total_participant : null, 'days' => $calFrom->diffInDays($calTo) + 1, ]; } // Tapisan kategori (pilihan) if ($calKat !== '') { $calItems = array_values(array_filter($calItems, fn ($calItem) => $calItem['category'] === $calKat)); } /* -------------------------------------------------------------------- | 7. Peta hari → acara (acara berbilang hari diulang pada setiap hari) -------------------------------------------------------------------- */ $calByDay = []; foreach ($calItems as $calItem) { $calCursor = $calItem['from']->copy(); while ($calCursor->lte($calItem['to'])) { $calByDay[$calCursor->format('Y-m-d')][] = $calItem; $calCursor->addDay(); } } /* -------------------------------------------------------------------- | 8. Grid bulan (Ahad → Sabtu, termasuk hari sebelum/selepas bulan) -------------------------------------------------------------------- */ $calGridStart = $calStart->copy()->startOfWeek(\Carbon\Carbon::SUNDAY); $calGridEnd = $calEnd->copy()->endOfWeek(\Carbon\Carbon::SATURDAY); $calWeeks = []; $calCursor = $calGridStart->copy(); while ($calCursor->lte($calGridEnd)) { $calWeek = []; for ($calDay = 0; $calDay < 7; $calDay++) { $calWeek[] = $calCursor->copy(); $calCursor->addDay(); } $calWeeks[] = $calWeek; } /* -------------------------------------------------------------------- | 9. Hari terpilih (panel butiran) + statistik -------------------------------------------------------------------- */ $calSelected = null; $calSelectedKey = ''; if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $calTarikh)) { try { $calTry = \Carbon\Carbon::createFromFormat('Y-m-d', $calTarikh)->startOfDay(); if ($calTry->format('Y-m') === $calBulan) { $calSelected = $calTry; $calSelectedKey = $calTry->format('Y-m-d'); } } catch (\Throwable $e) { $calSelected = null; } } $calTotal = count($calItems); $calDayCount = count($calByDay); @endphp
{{-- ---------- BREADCRUMB ---------- --}} {{-- ---------- TAJUK ---------- --}}
{{ t('Pusat Media') }}

{{ t('cal.title') }}

{{ t('cal.hero_desc') }}

{{-- ---------- BAR ALAT ---------- --}}

{{ $calMonthLabel }}

{{ t('cal.today') }}
{{ $calAllLabel }} @foreach ($calCatLabel as $calCode => $calLabel) {{ $calLabel }} @endforeach
{{-- ---------- RINGKASAN ---------- --}}

{{ $calTotal }} {{ t('cal.activities_this_month') }} @if ($calDayCount > 0) {{ $calDayCount }} hari ada aktiviti @endif @if ($calKat !== '') kategori: {{ $calCatName($calKat) }} @endif @if ($calSelected) tarikh: {{ $calSelected->format('d/m/Y') }} @endif

{{-- ---------- GRID BULAN ---------- --}}

{{ t('cal.table_hint') }}

@foreach ($calDayNames as $calDayName) @endforeach @foreach ($calWeeks as $calWeek) @foreach ($calWeek as $calDate) @php $calKey = $calDate->format('Y-m-d'); $calDayItems = $calByDay[$calKey] ?? []; $calInMonth = $calDate->format('Y-m') === $calBulan; $calIsToday = $calDate->isSameDay($calToday); $calIsSel = $calSelectedKey === $calKey; $calWeekend = in_array((int) $calDate->dayOfWeek, [0, 6], true); @endphp @endforeach @endforeach
{{ $calDayName }}
{{ $calDate->day }} @if (count($calDayItems)) @if (count($calDayItems) > 3) +{{ count($calDayItems) - 3 }} lagi @endif @endif
{{-- ---------- PANEL HARI TERPILIH ---------- --}} @if ($calSelected) @php $calSelItems = $calByDay[$calSelectedKey] ?? []; @endphp

{{ $calSelected->day }} {{ ($calLang === 'en' ? $calMonthNamesEn : $calMonthNames)[(int) $calSelected->month] }} {{ $calSelected->year }}

{{ $calDayNames[(int) $calSelected->dayOfWeek] }} {{ count($calSelItems) }} aktiviti Tutup
@if (count($calSelItems)) @foreach ($calSelItems as $calSelEv)
{{ $calCatName($calSelEv['category']) }} @if ($calSelEv['days'] > 1) {{ $calSelEv['days'] }} hari @endif

{{ $calSelEv['title'] }}

    @if ($calSelEv['time_start'] !== '')
  • {{ $calTime($calSelEv['time_start']) }}{{ $calSelEv['time_end'] !== '' ? ' – '.$calTime($calSelEv['time_end']) : '' }}
  • @endif @if ($calSelEv['days'] > 1)
  • {{ $calSelEv['from']->format('d/m/Y') }} – {{ $calSelEv['to']->format('d/m/Y') }}
  • @endif @if ($calSelEv['location'] !== '')
  • {{ $calSelEv['location'] }}
  • @endif @if ($calSelEv['participant'])
  • {{ $calSelEv['participant'] }} peserta
  • @endif
@if ($calSelEv['agenda'] !== '')

{!! nl2br(e($calSelEv['agenda'])) !!}

@endif
@endforeach @else

Tiada aktiviti pada tarikh ini.

@endif
@endif {{-- ---------- SENARAI AKTIVITI BULAN INI ---------- --}}

{{ t('cal.month_list') }}

{{ $calMonthLabel }} {{ $calTotal }} aktiviti
@if (count($calItems)) @foreach ($calItems as $calListEv)
{{ $calListEv['from']->day }} {{ mb_substr(($calLang === 'en' ? $calMonthNamesEn : $calMonthNames)[(int) $calListEv['from']->month], 0, 3) }}

{{ $calListEv['title'] }}

  • {{ $calCatName($calListEv['category']) }}
  • @if ($calListEv['time_start'] !== '')
  • {{ $calTime($calListEv['time_start']) }}{{ $calListEv['time_end'] !== '' ? ' – '.$calTime($calListEv['time_end']) : '' }}
  • @endif @if ($calListEv['days'] > 1)
  • {{ $calListEv['from']->format('d/m/Y') }} – {{ $calListEv['to']->format('d/m/Y') }}
  • @endif @if ($calListEv['location'] !== '')
  • {{ $calListEv['location'] }}
  • @endif
@endforeach @else
@if ($calKat !== '')

Tiada aktiviti bagi kategori ini

Tiada aktiviti berkategori {{ $calCatName($calKat) }} pada {{ $calMonthLabel }}. Tampilkan semua kategori.

@else

Tiada aktiviti pada bulan ini

Belum ada aktiviti didaftarkan bagi {{ $calMonthLabel }}. Lihat bulan semasa.

@endif
@endif
{{-- ---------- LEGENDA ---------- --}}
{{ t('cal.category') }} @foreach ($calCatLabel as $calCode => $calLabel) {{ $calLabel }} @endforeach
{{-- ---------- NOTA ---------- --}}