{{-- ============================================================================ 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: 'global' (semua portal) — tukar $vsScopeMode ke 'site' utk portal semasa sahaja. BM/EN ikut sesi. CSS sendiri (kelas .vs-*). ============================================================================ --}} @php $vsLang = ($lang ?? session('locale', 'ms')) === 'en' ? 'en' : 'ms'; // --- Skop: 'global' (semua portal) atau 'site' (portal ini sahaja) --- $vsScopeMode = 'global'; $vsSiteId = DB::table('frontend_sites')->where('slug', $siteSlug ?? 'nres')->value('id'); $vsSiteKey = ($vsScopeMode === 'site' && $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($vsScopeMode === 'site' && $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

{{ t('vs.title') }} {{ $vsYear }}

{{ t('vs.subtitle') }}

@foreach ([ ['lbl' => t('vs.total_visitors'), 'num' => $vsTotalVisits, 'note' => t('vs.daily_visits_this_year')], ['lbl' => t('vs.unique_visitors'), 'num' => $vsTotalUniq, 'note' => t('vs.distinct_visitors_this_year')], ['lbl' => t('vs.page_views'), 'num' => $vsTotalViews, 'note' => t('vs.total_page_views')], ['lbl' => t('vs.online_services'), 'num' => $vsTotalServices, 'note' => t('vs.pages_tracked')], ] as $vsCard)
{{ $vsCard['lbl'] }} {{ number_format($vsCard['num']) }} {{ $vsCard['note'] }}
@endforeach

{{ t('vs.monthly_title') }}

@foreach ($vsMonthShort as $vsLbl) @endforeach @foreach ([ ['lbl' => t('vs.number_of_visitors'), 'months' => $vsVisits->pluck('total', 'm'), 'total' => $vsTotalVisits], ['lbl' => t('vs.unique_visitors'), 'months' => $vsVisits->pluck('uniq', 'm'), 'total' => $vsTotalUniq], ['lbl' => t('vs.page_views'), '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
{{ t('vs.service') }}{{ $vsLbl }}{{ t('common.total') }}
{{ $vsRow['lbl'] }}@if ($vsV > 0){{ number_format($vsV) }}@else–@endif{{ number_format($vsRow['total']) }}

{{ t('vs.source_note') }}

{{ t('vs.pages_title') }}

@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
{{ t('vs.service_page') }}{{ $vsLbl }}{{ t('common.total') }}
{{ $vsName ? t($vsName) : ($vsSlug === '' ? t('Home') : $vsPath) }} @if ($vsSlug !== '') {{ $vsPath }} @endif @if ($vsV > 0){{ number_format($vsV) }}@else–@endif{{ number_format($vsRow['total']) }}
—

{{ t('vs.views_note') }}