{"id":684,"date":"2025-08-31T23:01:23","date_gmt":"2025-08-31T21:01:23","guid":{"rendered":"https:\/\/ontime-timing.com\/?page_id=684"},"modified":"2026-01-05T00:28:43","modified_gmt":"2026-01-04T23:28:43","slug":"kalendar","status":"publish","type":"page","link":"https:\/\/ontime-timing.com\/en\/kalendar\/","title":{"rendered":"Calendar"},"content":{"rendered":"<div class=\"calendar-wrapper\">\n        <div class=\"calendar-header\">\n            <button class=\"calendar-prev\">&lt;<\/button>\n            <h2 class=\"calendar-month\"><\/h2>\n            <button class=\"calendar-next\">&gt;<\/button>\n        <\/div>\n        <div class=\"calendar-weekdays\" id=\"calendarWeekdays\"><\/div>\n        <div class=\"calendar-grid\" id=\"calendarGrid\"><\/div>\n    <\/div>\n\n    <style>\n        .calendar-wrapper {\n            margin: 0 auto;\n            font-family: Arial, sans-serif;\n        }\n        .calendar-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 10px;\n        }\n        .calendar-weekdays {\n            display: grid;\n            grid-template-columns: repeat(7, 1fr);\n            font-weight: bold;\n            text-align: center;\n            margin-bottom: 5px;\n        }\n        .calendar-weekdays div {\n            padding: 5px 0;\n        }\n        .calendar-grid {\n            display: grid;\n            grid-template-columns: repeat(7, 1fr);\n            gap: 5px;\n        }\n        .calendar-day {\n            min-height: 100px;\n            border: 1px solid #ddd;\n            padding: 4px;\n            font-size: 12px;\n            position: relative;\n            background: #f9f9f9;\n        }\n        .calendar-day.today {\n            border: 2px solid #007bff;\n        }\n        .calendar-day .event {\n            background: #007bff;\n            color: #fff;\n            padding: 2px 4px;\n            margin-top: 3px;\n            border-radius: 3px;\n            display: block;\n            text-decoration: none;\n            font-size: 11px;\n            word-break: break-word;\n        }\n        @media (max-width: 768px) {\n            .calendar-day { min-height: 80px; font-size: 10px; }\n            .calendar-weekdays { display: none; }\n        }\n        @media (max-width: 500px) {\n            .calendar-weekdays { display: none; }\n            .calendar-grid { grid-template-columns: repeat(2, 1fr); }\n            .calendar-day { min-height: 60px; }\n        }\n        .calendar-prev,\n        .calendar-next {\n          background: #f5f5f5;\n          border: none;\n          padding: 0.5rem 0.9rem;\n          border-radius: 50%;\n          font-size: 1.2rem;\n          font-weight: bold;\n          cursor: pointer;\n          transition: all 0.2s ease;\n          box-shadow: 0 2px 6px rgba(0,0,0,0.1);\n        }\n        .calendar-prev:hover,\n        .calendar-next:hover {\n          background: #007bff;\n          color: #fff;\n          transform: scale(1.1);\n        }\n        .calendar-prev:active,\n        .calendar-next:active {\n          transform: scale(0.95);\n        }\n    <\/style>\n\n    <script>\n        document.addEventListener(\"DOMContentLoaded\", function () {\n            const grid = document.getElementById(\"calendarGrid\");\n            const weekdaysContainer = document.getElementById(\"calendarWeekdays\");\n            const monthLabel = document.querySelector(\".calendar-month\");\n            const prevBtn = document.querySelector(\".calendar-prev\");\n            const nextBtn = document.querySelector(\".calendar-next\");\n\n            \/\/ Language from PHP (bs-BA or en-GB)\n            const userLang = \"en-GB\";\n            let currentDate = new Date();\n\n            const weekdayNames = {\n                'en-GB': [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"],\n                'bs-BA': [\"Pon\",\"Uto\",\"Sre\",\"\u010cet\",\"Pet\",\"Sub\",\"Ned\"]\n            };\n            \n            \/\/ Render weekday headers (starting Monday)\n            function renderWeekdays() {\n                weekdaysContainer.innerHTML = \"\";\n                \/\/ Use current language or fallback to English\n                const days = weekdayNames[userLang] || weekdayNames['en-GB'];\n            \n                days.forEach(name => {\n                    const div = document.createElement(\"div\");\n                    div.textContent = name;\n                    weekdaysContainer.appendChild(div);\n                });\n            }\n\n            function fetchCalendar(year, month) {\n                const formData = new FormData();\n                formData.append('action', 'load_calendar_events');\n                formData.append('year', year);\n                formData.append('month', month);\n\n                fetch(\"https:\/\/ontime-timing.com\/wp-admin\/admin-ajax.php\", {\n                    method: \"POST\",\n                    credentials: \"same-origin\",\n                    body: formData\n                })\n                .then(res => res.json())\n                .then(data => {\n                    renderCalendar(year, month, data);\n                });\n            }\n\n            function renderCalendar(year, month, events) {\n                grid.innerHTML = \"\";\n                const firstDay = new Date(year, month, 1);\n                const lastDay = new Date(year, month + 1, 0);\n\n               const monthNames = {\n                    'en-GB': [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],\n                    'bs-BA': [\"Januar\",\"Februar\",\"Mart\",\"April\",\"Maj\",\"Juni\",\"Juli\",\"August\",\"Septembar\",\"Oktobar\",\"Novembar\",\"Decembar\"]\n                };\n                \n                monthLabel.textContent = monthNames[userLang] ? monthNames[userLang][currentDate.getMonth()] + \" \" + currentDate.getFullYear() \n                                                               : currentDate.getFullYear();\n\n                \/\/ Adjust first day so Monday = 0, Sunday = 6\n                let startDay = firstDay.getDay();\n                startDay = (startDay === 0) ? 6 : startDay - 1;\n\n                for (let i = 0; i < startDay; i++) {\n                    grid.appendChild(document.createElement(\"div\"));\n                }\n\n                for (let day = 1; day <= lastDay.getDate(); day++) {\n                    const cell = document.createElement(\"div\");\n                    cell.classList.add(\"calendar-day\");\n\n                    let fullDate = `${year}-${String(month+1).padStart(2,'0')}-${String(day).padStart(2,'0')}`;\n                    if (fullDate === \"2026-05-13\") {\n                        cell.classList.add(\"today\");\n                    }\n\n                    cell.innerHTML = `<strong>${day}<\/strong>`;\n\n                    if (events[fullDate]) {\n                        events[fullDate].forEach(ev => {\n                            const link = document.createElement(\"a\");\n                            link.classList.add(\"event\");\n                            link.target = \"_blank\";\n                            link.href = ev.link;\n                            link.textContent = ev.title + (ev.entries ? ` (${ev.entries})` : \"\");\n                            cell.appendChild(link);\n                        });\n                    }\n\n                    grid.appendChild(cell);\n                }\n            }\n\n            prevBtn.addEventListener(\"click\", () => {\n                currentDate.setMonth(currentDate.getMonth() - 1);\n                fetchCalendar(currentDate.getFullYear(), currentDate.getMonth());\n            });\n\n            nextBtn.addEventListener(\"click\", () => {\n                currentDate.setMonth(currentDate.getMonth() + 1);\n                fetchCalendar(currentDate.getFullYear(), currentDate.getMonth());\n            });\n\n            \/\/ Initial load\n            renderWeekdays();\n            fetchCalendar(currentDate.getFullYear(), currentDate.getMonth());\n        });\n    <\/script>\n    \n\n\n    <div class=\"fe-export-events-wrapper\">\n        <button id=\"fe-export-events-btn\" class=\"custom-btn calendar-btn\">\ud83d\udcc5 Dodaj sve budu\u0107e trke u kalendar<\/button>\n    <\/div>\n    <script type=\"text\/javascript\">\n    (function(){\n        const btn = document.getElementById('fe-export-events-btn');\n        btn.addEventListener('click', function(){\n            btn.textContent = 'Preparing calendar...';\n\n            fetch('https:\/\/ontime-timing.com\/wp-admin\/admin-ajax.php', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n                body: new URLSearchParams({\n                    action: 'export_future_events',\n                    nonce: 'bd2fd7f7cc'\n                })\n            })\n            .then(response => response.blob())\n            .then(blob => {\n                const link = document.createElement('a');\n                link.href = window.URL.createObjectURL(blob);\n                link.download = \"future-events.ics\";\n                document.body.appendChild(link);\n                link.click();\n                document.body.removeChild(link);\n                btn.textContent = '\ud83d\udcc5 Dodaj sve budu\u0107e trke u kalendar';\n            })\n            .catch(() => {\n                alert('Failed to generate calendar.');\n                btn.textContent = '\ud83d\udcc5 Dodaj sve budu\u0107e trke u kalendar';\n            });\n        });\n    })();\n    <\/script>\n    <style>\n    .fe-export-events-wrapper {\n        margin: 10px 0;\n        margin-top: 20px;\n    }\n    .custom-btn.calendar-btn {\n        background: #2f5bea;\n        color: #fff !important;\n        padding: 10px 18px;\n        border-radius: 10px;\n        font-size: 15px;\n        font-weight: 600;\n        border: none;\n        cursor: pointer;\n    }\n    .custom-btn.calendar-btn:hover {\n        background: #2447c6;\n    }\n    <\/style>\n    \n\n\n\n<p class=\"\"><\/p>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-684","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Kalendar - OnTime Timing<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ontime-timing.com\/en\/kalendar\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kalendar - OnTime Timing\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ontime-timing.com\/en\/kalendar\/\" \/>\n<meta property=\"og:site_name\" content=\"OnTime Timing\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/OnTimeBiH\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-04T23:28:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/ontime-timing.com\/wp-content\/uploads\/2025\/07\/cropped-image001-1.webp?fit=512%2C512&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/kalendar\\\/\",\"url\":\"https:\\\/\\\/ontime-timing.com\\\/kalendar\\\/\",\"name\":\"Kalendar - OnTime Timing\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#website\"},\"datePublished\":\"2025-08-31T21:01:23+00:00\",\"dateModified\":\"2026-01-04T23:28:43+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/kalendar\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ontime-timing.com\\\/kalendar\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/kalendar\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ontime-timing.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Kalendar\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#website\",\"url\":\"https:\\\/\\\/ontime-timing.com\\\/\",\"name\":\"OnTime Timing\",\"description\":\"OnTime provides race timing services for all types of sport events\",\"publisher\":{\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#organization\"},\"alternateName\":\"OnTime\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ontime-timing.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#organization\",\"name\":\"OnTime Timing\",\"alternateName\":\"OnTime\",\"url\":\"https:\\\/\\\/ontime-timing.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/ontime-timing.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/image001.png?fit=500%2C500&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/ontime-timing.com\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/image001.png?fit=500%2C500&ssl=1\",\"width\":500,\"height\":500,\"caption\":\"OnTime Timing\"},\"image\":{\"@id\":\"https:\\\/\\\/ontime-timing.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/OnTimeBiH\",\"https:\\\/\\\/www.instagram.com\\\/ontimetimingbih\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kalendar - OnTime Timing","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ontime-timing.com\/en\/kalendar\/","og_locale":"en_GB","og_type":"article","og_title":"Kalendar - OnTime Timing","og_url":"https:\/\/ontime-timing.com\/en\/kalendar\/","og_site_name":"OnTime Timing","article_publisher":"https:\/\/www.facebook.com\/OnTimeBiH","article_modified_time":"2026-01-04T23:28:43+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/i0.wp.com\/ontime-timing.com\/wp-content\/uploads\/2025\/07\/cropped-image001-1.webp?fit=512%2C512&ssl=1","type":"image\/webp"}],"twitter_card":"summary_large_image","twitter_misc":{"Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ontime-timing.com\/kalendar\/","url":"https:\/\/ontime-timing.com\/kalendar\/","name":"Kalendar - OnTime Timing","isPartOf":{"@id":"https:\/\/ontime-timing.com\/#website"},"datePublished":"2025-08-31T21:01:23+00:00","dateModified":"2026-01-04T23:28:43+00:00","breadcrumb":{"@id":"https:\/\/ontime-timing.com\/kalendar\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ontime-timing.com\/kalendar\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ontime-timing.com\/kalendar\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ontime-timing.com\/"},{"@type":"ListItem","position":2,"name":"Kalendar"}]},{"@type":"WebSite","@id":"https:\/\/ontime-timing.com\/#website","url":"https:\/\/ontime-timing.com\/","name":"OnTime Timing","description":"OnTime provides race timing services for all types of sport events","publisher":{"@id":"https:\/\/ontime-timing.com\/#organization"},"alternateName":"OnTime","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ontime-timing.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/ontime-timing.com\/#organization","name":"OnTime Timing","alternateName":"OnTime","url":"https:\/\/ontime-timing.com\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/ontime-timing.com\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/ontime-timing.com\/wp-content\/uploads\/2025\/06\/image001.png?fit=500%2C500&ssl=1","contentUrl":"https:\/\/i0.wp.com\/ontime-timing.com\/wp-content\/uploads\/2025\/06\/image001.png?fit=500%2C500&ssl=1","width":500,"height":500,"caption":"OnTime Timing"},"image":{"@id":"https:\/\/ontime-timing.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/OnTimeBiH","https:\/\/www.instagram.com\/ontimetimingbih"]}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/pages\/684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/comments?post=684"}],"version-history":[{"count":3,"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/pages\/684\/revisions"}],"predecessor-version":[{"id":1285,"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/pages\/684\/revisions\/1285"}],"wp:attachment":[{"href":"https:\/\/ontime-timing.com\/en\/wp-json\/wp\/v2\/media?parent=684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}