{{-- ============================================================================ 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 ---------- --}}
Pusat Media

Kalendar Aktiviti

Senarai aktiviti, majlis dan program Kementerian Sumber Asli dan Kelestarian Alam. Gunakan anak panah untuk menukar bulan, atau klik pada tarikh dalam kalendar untuk melihat butiran aktiviti hari itu.

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

{{ $calMonthLabel }}

Hari Ini
{{ $calAllLabel }} @foreach ($calCatLabel as $calCode => $calLabel) {{ $calLabel }} @endforeach
{{-- ---------- RINGKASAN ---------- --}}

{{ $calTotal }} aktiviti pada bulan ini @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 ---------- --}}

Leret jadual ke kiri atau kanan untuk melihat hari lain.

@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 ---------- --}}

Senarai Aktiviti Bulan Ini

{{ $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 ---------- --}}
Kategori: @foreach ($calCatLabel as $calCode => $calLabel) {{ $calLabel }} @endforeach
{{-- ---------- NOTA ---------- --}}