{"id":7,"date":"2026-09-11T10:55:18","date_gmt":"2026-09-11T02:55:18","guid":{"rendered":"https:\/\/www.ukm.my\/bakatukm\/?page_id=7"},"modified":"2026-09-22T17:14:29","modified_gmt":"2026-09-22T09:14:29","slug":"laman-utama","status":"publish","type":"page","link":"https:\/\/www.ukm.my\/bakatukm\/","title":{"rendered":"Laman Utama"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"7\" class=\"elementor elementor-7\">\n\t\t\t\t<div class=\"elementor-element elementor-element-df606ed e-grid e-con-full e-con e-parent\" data-id=\"df606ed\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6705d0b elementor-pagination-position-inside elementor-widget elementor-widget-image-carousel\" data-id=\"6705d0b\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;slides_to_show&quot;:&quot;1&quot;,&quot;navigation&quot;:&quot;dots&quot;,&quot;autoplay&quot;:&quot;yes&quot;,&quot;pause_on_hover&quot;:&quot;yes&quot;,&quot;pause_on_interaction&quot;:&quot;yes&quot;,&quot;autoplay_speed&quot;:5000,&quot;infinite&quot;:&quot;yes&quot;,&quot;effect&quot;:&quot;slide&quot;,&quot;speed&quot;:500}\" data-widget_type=\"image-carousel.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-carousel-wrapper swiper\" role=\"region\" aria-roledescription=\"carousel\" aria-label=\"Image Carousel\" dir=\"ltr\">\n\t\t\t<div class=\"elementor-image-carousel swiper-wrapper\" aria-live=\"off\">\n\t\t\t\t\t\t\t\t<div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 1\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/www.ukm.my\/bakatukm\/wp-content\/uploads\/2026\/09\/banner_canselori_jp-rhaw34nuj823qa6m046kgeo9tvnrynr6xrqvlcbr6g.png\" alt=\"banner_canselori_jp-rhaw34nuj823qa6m046kgeo9tvnrynr6xrqvlcbr6g\" \/><\/figure><\/div>\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b5046e7 e-grid e-con-boxed e-con e-parent\" data-id=\"b5046e7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-dff09b5 e-grid e-con-boxed e-con e-parent\" data-id=\"dff09b5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-21335ac elementor-widget elementor-widget-heading\" data-id=\"21335ac\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Kalendar Latihan<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-046f663 elementor-widget elementor-widget-html\" data-id=\"046f663\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- Fonts & CSS -->\n<link href=\"https:\/\/cdn.jsdelivr.net\/npm\/fullcalendar@6.1.11\/index.global.min.css\" rel=\"stylesheet\" \/>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&display=swap\" rel=\"stylesheet\">\n\n<style>\n    :root {\n        \/* Corporate palette \u2014 navy as primary, warm gold as the single deliberate accent *\/\n        --navy-900: #0a1f3d;\n        --navy-800: #0f2a4d;\n        --navy-700: #163a63;\n        --blue-600: #1d4e89;\n        --gold-500: #c9972b;\n        --gold-400: #d9ac4f;\n        --gold-100: #f7ecd8;\n        --slate-600: #475569;\n        --slate-400: #94a3b8;\n        --bg-page: #f5f6f8;\n        --border-color: #e6e9ee;\n        --text-main: #101828;\n        --text-muted: #64748b;\n        --white: #ffffff;\n    }\n\n    *, *::before, *::after {\n        box-sizing: border-box;\n    }\n\n    body {\n        font-family: 'Inter', sans-serif;\n        color: var(--text-main);\n        margin: 0;\n        padding: 0;\n    }\n\n    \/* \u2500\u2500 Calendar Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n    .calendar-app-container {\n        max-width: 1200px;\n        margin: 0 auto;\n        padding: 20px 0;\n    }\n\n    .calendar-wrapper {\n        background: var(--white);\n        border-radius: 20px;\n        padding: 0;\n        overflow: hidden;\n        box-shadow: 0 20px 45px -12px rgba(10, 31, 61, 0.16), 0 2px 8px rgba(10, 31, 61, 0.06);\n        position: relative;\n        border: 1px solid var(--border-color);\n    }\n\n    \/* \u2500\u2500 Loading Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n    #loading-overlay {\n        position: absolute;\n        inset: 0;\n        background: rgba(10, 31, 61, 0.97);\n        display: flex;\n        flex-direction: column;\n        gap: 14px;\n        justify-content: center;\n        align-items: center;\n        z-index: 10;\n        border-radius: 20px;\n        font-weight: 600;\n        font-size: 0.95rem;\n        color: var(--white);\n        letter-spacing: 0.01em;\n    }\n\n    .loading-spinner {\n        width: 34px;\n        height: 34px;\n        border-radius: 50%;\n        border: 3px solid rgba(255, 255, 255, 0.18);\n        border-top-color: var(--gold-500);\n        animation: spin 0.85s linear infinite;\n    }\n\n    @keyframes spin {\n        to { transform: rotate(360deg); }\n    }\n\n    \/* \u2500\u2500 FullCalendar Overrides \u2014 Bold Corporate Look \u2500\u2500 *\/\n    .fc {\n        font-family: 'Inter', sans-serif;\n    }\n\n    \/* Header toolbar becomes a full-bleed navy command bar *\/\n    .fc-header-toolbar.fc-toolbar {\n        background: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-700) 100%);\n        margin: 0 !important;\n        padding: 22px 28px;\n        gap: 12px;\n    }\n\n    .fc .fc-toolbar-title {\n        font-size: 1.4rem;\n        font-weight: 800;\n        color: var(--white);\n        letter-spacing: -0.01em;\n    }\n\n    .fc .fc-button-primary {\n        background-color: transparent;\n        color: rgba(255, 255, 255, 0.85);\n        border: 1.5px solid rgba(255, 255, 255, 0.28);\n        border-radius: 999px;\n        text-transform: capitalize;\n        font-weight: 600;\n        font-size: 0.85rem;\n        padding: 7px 16px;\n        transition: all 0.18s ease;\n        box-shadow: none;\n    }\n\n    .fc .fc-button-primary:hover {\n        background-color: rgba(255, 255, 255, 0.12);\n        color: var(--white);\n        border-color: rgba(255, 255, 255, 0.5);\n    }\n\n    .fc .fc-button-primary:not(:disabled):active,\n    .fc .fc-button-primary:not(:disabled).fc-button-active {\n        background-color: var(--gold-500);\n        color: var(--navy-900);\n        border-color: var(--gold-500);\n        box-shadow: none;\n    }\n\n    .fc .fc-button-primary:focus,\n    .fc .fc-button-primary:not(:disabled).fc-button-active:focus {\n        box-shadow: 0 0 0 3px rgba(201, 151, 43, 0.35);\n    }\n\n    .fc .fc-icon {\n        font-size: 1.05em;\n    }\n\n    \/* Body of the calendar sits on white below the navy bar *\/\n    .fc-view-harness {\n        padding: 0 8px 20px;\n        background: var(--white);\n    }\n\n    .fc-theme-standard .fc-scrollgrid,\n    .fc-theme-standard th,\n    .fc-theme-standard td {\n        border-color: var(--border-color);\n    }\n\n    .fc-theme-standard th {\n        padding: 14px 0;\n        background-color: var(--bg-page);\n        font-weight: 700;\n        font-size: 0.82rem;\n        color: var(--navy-800);\n        border-bottom: 2px solid var(--border-color);\n    }\n\n    .fc-daygrid-day-number {\n        font-weight: 600;\n        font-size: 0.88rem;\n        color: var(--text-main);\n        padding: 8px;\n    }\n\n    .fc-day-today {\n        background: var(--gold-100) !important;\n    }\n\n    .fc-day-today .fc-daygrid-day-number {\n        display: inline-flex;\n        align-items: center;\n        justify-content: center;\n        min-width: 26px;\n        height: 26px;\n        background: var(--gold-500);\n        color: var(--navy-900);\n        border-radius: 50%;\n        font-weight: 800;\n        margin: 4px;\n        padding: 0;\n    }\n\n    .fc-daygrid-day.fc-day-other {\n        background: #fbfbfc;\n    }\n\n    \/* Event chips: solid navy fill with a gold accent edge, no pastel *\/\n    .fc-daygrid-event {\n        border-radius: 6px;\n        padding: 4px 8px;\n        font-size: 0.8rem;\n        font-weight: 600;\n        border: none;\n        cursor: pointer;\n        background: var(--navy-800) !important;\n        color: var(--white) !important;\n        box-shadow: inset 3px 0 0 var(--gold-500);\n        transition: transform 0.15s ease, box-shadow 0.15s ease;\n    }\n\n    .fc-daygrid-event:hover {\n        transform: translateY(-1px);\n        box-shadow: inset 3px 0 0 var(--gold-500), 0 4px 10px rgba(10, 31, 61, 0.18);\n    }\n\n    .fc-daygrid-event .fc-event-time {\n        font-weight: 700;\n        color: var(--gold-400);\n        margin-right: 4px;\n    }\n\n    .fc-daygrid-more-link {\n        font-weight: 700;\n        font-size: 0.78rem;\n        color: var(--blue-600);\n    }\n\n    \/* Agenda \/ list view *\/\n    .fc-list-day-cushion {\n        background: var(--bg-page) !important;\n    }\n\n    .fc-list-day-text, .fc-list-day-side-text {\n        font-weight: 700;\n        color: var(--navy-800);\n    }\n\n    .fc-list-event:hover td {\n        background: var(--gold-100) !important;\n    }\n\n    .fc-list-event-dot {\n        border-color: var(--navy-800) !important;\n    }\n\n    .fc-list-event-title {\n        font-weight: 600;\n        color: var(--text-main);\n    }\n\n    .fc-list-event-time {\n        color: var(--text-muted);\n        font-weight: 600;\n    }\n\n    .fc-list-empty {\n        background: var(--white);\n        color: var(--text-muted);\n        font-weight: 500;\n        padding: 40px 0;\n    }\n\n    \/* \u2500\u2500 Event Detail Modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n    .modal-backdrop {\n        display: none;\n        position: fixed;\n        inset: 0;\n        background: rgba(10, 20, 35, 0.55);\n        backdrop-filter: blur(4px);\n        -webkit-backdrop-filter: blur(4px);\n        z-index: 1000;\n        align-items: center;\n        justify-content: center;\n        padding: 16px;\n    }\n\n    .modal-backdrop.is-open {\n        display: flex;\n    }\n\n    .modal-card {\n        background: var(--white);\n        border-radius: 16px;\n        box-shadow: 0 25px 60px -12px rgba(10, 31, 61, 0.4);\n        width: 100%;\n        max-width: 500px;\n        max-height: 90vh;\n        display: flex;\n        flex-direction: column;\n        overflow: hidden;\n        animation: modalIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n    }\n\n    @keyframes modalIn {\n        from { opacity: 0; transform: translateY(20px) scale(0.96); }\n        to { opacity: 1; transform: translateY(0) scale(1); }\n    }\n\n    .modal-header {\n        display: flex;\n        align-items: flex-start;\n        justify-content: space-between;\n        gap: 12px;\n        padding: 22px 24px;\n        background: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-700) 100%);\n        border-bottom: 3px solid var(--gold-500);\n    }\n\n    .modal-title {\n        font-size: 1.1rem;\n        font-weight: 800;\n        color: var(--white);\n        margin: 0;\n        line-height: 1.4;\n    }\n\n    .modal-close {\n        background: rgba(255, 255, 255, 0.12);\n        border: none;\n        border-radius: 50%;\n        width: 32px;\n        height: 32px;\n        min-width: 32px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        cursor: pointer;\n        font-size: 0.95rem;\n        color: var(--white);\n        transition: background 0.2s;\n    }\n\n    .modal-close:hover {\n        background: rgba(255, 255, 255, 0.25);\n    }\n\n    .modal-body {\n        padding: 22px 24px 26px;\n        display: flex;\n        flex-direction: column;\n        gap: 16px;\n        overflow-y: auto;\n    }\n\n    .modal-row {\n        display: flex;\n        gap: 14px;\n        align-items: flex-start;\n        font-size: 0.95rem;\n        color: var(--text-main);\n    }\n\n    .modal-icon {\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        width: 30px;\n        height: 30px;\n        min-width: 30px;\n        border-radius: 8px;\n        background: var(--gold-100);\n        font-size: 0.95rem;\n    }\n\n    .modal-date {\n        font-weight: 600;\n        padding-top: 4px;\n    }\n\n    .modal-desc {\n        white-space: normal;\n        line-height: 1.65;\n        color: var(--text-muted);\n        padding-top: 3px;\n    }\n\n    .modal-desc a {\n        color: var(--blue-600);\n        text-decoration: underline;\n        font-weight: 600;\n    }\n<\/style>\n\n<div class=\"calendar-app-container\">\n    <div class=\"calendar-wrapper\">\n        <div id=\"loading-overlay\">\n            <div class=\"loading-spinner\"><\/div>\n            <span>Memuatkan acara...<\/span>\n        <\/div>\n        <div id=\"calendar\"><\/div>\n    <\/div>\n<\/div>\n\n<!-- Event Detail Modal -->\n<div class=\"modal-backdrop\" id=\"event-modal\" role=\"dialog\" aria-modal=\"true\">\n    <div class=\"modal-card\" id=\"modal-card\">\n        <div class=\"modal-header\">\n            <h2 class=\"modal-title\" id=\"modal-event-title\"><\/h2>\n            <button class=\"modal-close\" id=\"modal-close-btn\" aria-label=\"Tutup\">&#x2715;<\/button>\n        <\/div>\n        <div class=\"modal-body\">\n            <div class=\"modal-row\" id=\"modal-date-row\">\n                <span class=\"modal-icon\">\ud83d\udcc5<\/span>\n                <span class=\"modal-date\" id=\"modal-date\"><\/span>\n            <\/div>\n            <div class=\"modal-row\" id=\"modal-desc-row\" style=\"display:none\">\n                <span class=\"modal-icon\">\ud83d\udcdd<\/span>\n                <span class=\"modal-desc\" id=\"modal-desc\"><\/span>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- FullCalendar Core JS -->\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/fullcalendar@6.1.11\/index.global.min.js\"><\/script>\n\n<script>\n    document.addEventListener('DOMContentLoaded', function () {\n\n        \/\/ ==========================================\n        \/\/ CONFIGURATION \u2014 PASTE YOUR CREDENTIALS HERE\n        \/\/ ==========================================\n        const API_KEY = 'AIzaSyDzJ1GB3_yPu_I_tyYzgDYIlLXwGJkdz6c';\n        const CALENDAR_ID = 'teknikal.bakat@ukm.edu.my';\n        \/\/ ==========================================\n\n        const calendarEl = document.getElementById('calendar');\n        const loadingEl = document.getElementById('loading-overlay');\n\n        let calendarInstance = new FullCalendar.Calendar(calendarEl, {\n            initialView: 'dayGridMonth',\n            headerToolbar: {\n                left: 'prev,next today',\n                center: 'title',\n                right: 'dayGridMonth,listMonth'\n            },\n            buttonText: {\n                today: 'Hari Ini',\n                month: 'Bulan',\n                list: 'Agenda'\n            },\n            height: 'auto',\n            events: [],\n\n            eventClick: function (info) {\n                info.jsEvent.preventDefault();\n\n                const event = info.event;\n                const modal = document.getElementById('event-modal');\n                const titleEl = document.getElementById('modal-event-title');\n                const dateEl = document.getElementById('modal-date');\n                const descEl = document.getElementById('modal-desc');\n                const descRow = document.getElementById('modal-desc-row');\n\n                titleEl.textContent = event.title;\n\n                const locale = 'ms-MY';\n                const start = event.start;\n                const end = event.end;\n                const allDay = event.allDay;\n\n                let dateStr;\n                if (allDay) {\n                    const opts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' };\n                    const displayEnd = end ? new Date(end.getTime() - 86400000) : null;\n                    dateStr = start.toLocaleDateString(locale, opts);\n                    if (displayEnd && displayEnd.toDateString() !== start.toDateString()) {\n                        dateStr += ' \u2013 ' + displayEnd.toLocaleDateString(locale, opts);\n                    }\n                } else {\n                    const dateOpts = { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' };\n                    const timeOpts = { hour: '2-digit', minute: '2-digit' };\n                    dateStr = start.toLocaleDateString(locale, dateOpts) + ', ' + start.toLocaleTimeString(locale, timeOpts);\n                    if (end) {\n                        dateStr += ' \u2013 ' + end.toLocaleTimeString(locale, timeOpts);\n                    }\n                }\n                dateEl.textContent = dateStr;\n\n                const desc = event.extendedProps.description || '';\n                if (desc.trim()) {\n                    descEl.innerHTML = desc; \/\/ Enables HTML formatting and clickable links\n                    descRow.style.display = 'flex';\n                } else {\n                    descRow.style.display = 'none';\n                }\n\n                modal.classList.add('is-open');\n            }\n        });\n\n        calendarInstance.render();\n\n        const modal = document.getElementById('event-modal');\n        const closeBtn = document.getElementById('modal-close-btn');\n        const modalCard = document.getElementById('modal-card');\n\n        function closeModal() { modal.classList.remove('is-open'); }\n        closeBtn.addEventListener('click', closeModal);\n        modal.addEventListener('click', function (e) {\n            if (!modalCard.contains(e.target)) closeModal();\n        });\n        document.addEventListener('keydown', function (e) {\n            if (e.key === 'Escape') closeModal();\n        });\n\n        async function fetchGoogleEvents() {\n            const timeMin = new Date();\n            timeMin.setMonth(timeMin.getMonth() - 3);\n\n            const url = `https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/${encodeURIComponent(CALENDAR_ID)}\/events`\n                + `?key=${API_KEY}`\n                + `&singleEvents=true`\n                + `&orderBy=startTime`\n                + `&timeMin=${timeMin.toISOString()}`\n                + `&maxResults=500`;\n\n            try {\n                const response = await fetch(url);\n                if (!response.ok) {\n                    const err = await response.json().catch(() => ({}));\n                    throw new Error(err.error?.message || `HTTP ${response.status}`);\n                }\n\n                const data = await response.json();\n                const allEventsData = (data.items || []).map(item => {\n                    return {\n                        title: item.summary ?? '(Tiada Tajuk)',\n                        start: item.start?.dateTime ?? item.start?.date,\n                        end: item.end?.dateTime ?? item.end?.date ?? null,\n                        description: item.description ?? '',\n                        extendedProps: {\n                            description: item.description ?? ''\n                        }\n                    };\n                });\n\n                loadingEl.style.display = 'none';\n                calendarInstance.addEventSource(allEventsData);\n\n            } catch (error) {\n                console.error('Google Calendar fetch error:', error);\n                loadingEl.innerHTML = `<span style=\"color:#f87171;\">\u26a0 Gagal memuatkan acara calendar.<\/span>`;\n            }\n        }\n\n        fetchGoogleEvents();\n    });\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Kalendar Latihan Memuatkan acara&#8230; &#x2715; \ud83d\udcc5 \ud83d\udcdd<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-7","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/pages\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":61,"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/pages\/7\/revisions"}],"predecessor-version":[{"id":124,"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/pages\/7\/revisions\/124"}],"wp:attachment":[{"href":"https:\/\/www.ukm.my\/bakatukm\/wp-json\/wp\/v2\/media?parent=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}