{{-- ============================================================================ PAGE CONTENT — Statistik Perkhidmatan Dalam Talian Site : nres · Page slug: visitor-statistics · Page ID: 40 URL : /nres/visitor-statistics Konsep: halaman portal asal https://www.nres.gov.my/ms-my/Pages/StatistikPerkhidmatanDalamTalian2026.aspx → jadual bulanan (Jan…Dis) + Jumlah untuk: 1. Bilangan Pelawat Portal Rasmi Kementerian 2. Perkhidmatan Dalam Talian (halaman paling dilawati) Sumber data: modul VISITOR (tiada modul/jadual baharu) · visitor_daily_counters → visited_on · visitor_hash · site_key · visitor_page_views → page_path · visitor_hash · viewed_at · site_key · frontend_pages → nama mesra bagi setiap page_path Metrik: · Bilangan Pelawat = COUNT(*) harian terkumpul sebulan (visitor_daily_counters) · Pelawat Unik = COUNT(DISTINCT visitor_hash) sebulan · Paparan Halaman = COUNT(*) visitor_page_views sebulan · Perkhidmatan = paparan halaman dikumpulkan ikut page_path Skop: site_key = site:{id} bagi $siteSlug semasa (bukan global). BM/EN ikut sesi. CSS sendiri (kelas .vs-*). ============================================================================ --}} @php $vsLang = ($lang ?? session('locale', 'ms')) === 'en' ? 'en' : 'ms'; // --- Skop site --- $vsSiteId = DB::table('frontend_sites')->where('slug', $siteSlug ?? 'nres')->value('id'); $vsSiteKey = $vsSiteId ? 'site:'.$vsSiteId : null; $vsScope = fn ($q) => $vsSiteKey ? $q->where('site_key', $vsSiteKey) : $q; // --- Tahun: tahun data terakhir (fallback tahun semasa) --- $vsYear = (int) ($vsScope(DB::table('visitor_page_views'))->selectRaw('MAX(YEAR(viewed_at)) as y')->first()->y ?? 0); $vsYear = $vsYear ?: (int) now()->year; $vsYearStart = $vsYear.'-01-01'; $vsYearEnd = $vsYear.'-12-31'; // --- Nama bulan --- $vsMonthShort = $vsLang === 'en' ? [1 => 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] : [1 => 'Jan', 'Feb', 'Mac', 'Apr', 'Mei', 'Jun', 'Julai', 'Ogos', 'Sept', 'Okt', 'Nov', 'Dis']; // --- 1. Pelawat (harian terkumpul) + unik, ikut bulan --- $vsVisits = $vsScope(DB::table('visitor_daily_counters')) ->whereBetween('visited_on', [$vsYearStart, $vsYearEnd]) ->selectRaw('MONTH(visited_on) as m, COUNT(*) as total, COUNT(DISTINCT visitor_hash) as uniq') ->groupBy('m') ->get() ->keyBy('m'); // --- 2. Paparan halaman ikut bulan --- $vsViews = $vsScope(DB::table('visitor_page_views')) ->whereYear('viewed_at', $vsYear) ->selectRaw('MONTH(viewed_at) as m, COUNT(*) as total') ->groupBy('m') ->get() ->keyBy('m'); // --- 3. Perkhidmatan (page_path) ikut bulan --- $vsPageRows = []; foreach ($vsScope(DB::table('visitor_page_views')) ->whereYear('viewed_at', $vsYear) ->selectRaw('page_path, MONTH(viewed_at) as m, COUNT(*) as total') ->groupBy('page_path', 'm') ->get() as $r) { $vsPageRows[$r->page_path]['m'][(int) $r->m] = (int) $r->total; $vsPageRows[$r->page_path]['total'] = ($vsPageRows[$r->page_path]['total'] ?? 0) + (int) $r->total; } uasort($vsPageRows, fn ($a, $b) => $b['total'] <=> $a['total']); // Nama mesra dari frontend_pages (page_path → slug → name) $vsPageNames = DB::table('frontend_pages') ->when($vsSiteId, fn ($q) => $q->where('site_fk', $vsSiteId)) ->pluck('name', 'slug'); // --- Jumlah tahun --- $vsTotalVisits = (int) $vsVisits->sum('total'); $vsTotalUniq = (int) ($vsScope(DB::table('visitor_daily_counters')) ->whereBetween('visited_on', [$vsYearStart, $vsYearEnd]) ->distinct() ->count('visitor_hash')); $vsTotalViews = (int) $vsViews->sum('total'); $vsTotalServices = count($vsPageRows); @endphp

{{ $vsLang === 'en' ? 'Online Service Statistics' : 'Statistik Perkhidmatan Dalam Talian' }} {{ $vsYear }}

{{ $vsLang === 'en' ? 'Visitor and online service usage statistics for the official portal.' : 'Statistik pelawat dan penggunaan perkhidmatan dalam talian portal rasmi.' }}

@foreach ([ ['lbl' => $vsLang === 'en' ? 'Total Visitors' : 'Jumlah Pelawat', 'num' => $vsTotalVisits, 'note' => $vsLang === 'en' ? 'daily visits this year' : 'kunjungan harian tahun ini'], ['lbl' => $vsLang === 'en' ? 'Unique Visitors' : 'Pelawat Unik', 'num' => $vsTotalUniq, 'note' => $vsLang === 'en' ? 'distinct visitors this year' : 'pelawat berbeza tahun ini'], ['lbl' => $vsLang === 'en' ? 'Page Views' : 'Paparan Halaman', 'num' => $vsTotalViews, 'note' => $vsLang === 'en' ? 'total page views' : 'jumlah paparan halaman'], ['lbl' => $vsLang === 'en' ? 'Online Services' : 'Perkhidmatan Dalam Talian', 'num' => $vsTotalServices, 'note' => $vsLang === 'en' ? 'pages tracked' : 'halaman dipantau'], ] as $vsCard)
{{ $vsCard['lbl'] }} {{ number_format($vsCard['num']) }} {{ $vsCard['note'] }}
@endforeach

{{ $vsLang === 'en' ? 'Number of Visitors to the Ministry Official Portal' : 'Bilangan Pelawat Portal Rasmi Kementerian' }}

@foreach ($vsMonthShort as $vsLbl) @endforeach @foreach ([ ['lbl' => $vsLang === 'en' ? 'Number of Visitors' : 'Bilangan Pelawat', 'months' => $vsVisits->pluck('total', 'm'), 'total' => $vsTotalVisits], ['lbl' => $vsLang === 'en' ? 'Unique Visitors' : 'Pelawat Unik', 'months' => $vsVisits->pluck('uniq', 'm'), 'total' => $vsTotalUniq], ['lbl' => $vsLang === 'en' ? 'Page Views' : 'Paparan Halaman', 'months' => $vsViews->pluck('total', 'm'), 'total' => $vsTotalViews], ] as $vsRow) @foreach (array_keys($vsMonthShort) as $vsM) @php $vsV = (int) ($vsRow['months'][$vsM] ?? 0); @endphp @endforeach @endforeach
{{ $vsLang === 'en' ? 'Service' : 'Perkhidmatan' }}{{ $vsLbl }}{{ $vsLang === 'en' ? 'Total' : 'Jumlah' }}
{{ $vsRow['lbl'] }}@if ($vsV > 0){{ number_format($vsV) }}@else–@endif{{ number_format($vsRow['total']) }}

{{ $vsLang === 'en' ? 'Source: Visitor module (visitor_daily_counters & visitor_page_views), scoped to this portal. Updated on every visit.' : 'Sumber: modul Pelawat (visitor_daily_counters & visitor_page_views), skop portal ini sahaja. Dikemas kini pada setiap lawatan.' }}

{{ $vsLang === 'en' ? 'Online Services (Most Visited Pages)' : 'Perkhidmatan Dalam Talian (Halaman Paling Dilawati)' }}

@foreach ($vsMonthShort as $vsLbl) @endforeach @forelse ($vsPageRows as $vsPath => $vsRow) @php $vsSlug = ltrim((string) $vsPath, '/'); $vsName = $vsPageNames[$vsSlug] ?? null; @endphp @foreach (array_keys($vsMonthShort) as $vsM) @php $vsV = (int) ($vsRow['m'][$vsM] ?? 0); @endphp @endforeach @empty @endforelse
{{ $vsLang === 'en' ? 'Service / Page' : 'Perkhidmatan / Halaman' }}{{ $vsLbl }}{{ $vsLang === 'en' ? 'Total' : 'Jumlah' }}
{{ $vsName ?: ($vsSlug === '' ? ($vsLang === 'en' ? 'Home' : 'Utama') : $vsPath) }} @if ($vsSlug !== '') {{ $vsPath }} @endif @if ($vsV > 0){{ number_format($vsV) }}@else–@endif{{ number_format($vsRow['total']) }}
—

{{ $vsLang === 'en' ? 'Page views are grouped by URL path. Only recorded paths are listed. Counts are scoped to this portal.' : 'Paparan halaman dikumpulkan ikut laluan URL. Hanya laluan yang direkodkan dipaparkan. Kiraan adalah untuk portal ini sahaja.' }}