{"id":19,"date":"2026-05-06T21:05:57","date_gmt":"2026-05-06T21:05:57","guid":{"rendered":"https:\/\/julia.julsoft.pl\/?page_id=19"},"modified":"2026-05-06T21:06:45","modified_gmt":"2026-05-06T21:06:45","slug":"health_diary_app","status":"publish","type":"page","link":"https:\/\/julia.julsoft.pl\/","title":{"rendered":"health_diary_app"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"19\" class=\"elementor elementor-19\">\n\t\t\t\t<div class=\"elementor-element elementor-element-471800e e-flex e-con-boxed e-con e-parent\" data-id=\"471800e\" 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-d85832b elementor-widget elementor-widget-shortcode\" data-id=\"d85832b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n    <link rel=\"apple-touch-icon\" href=\"https:\/\/julia.julsoft.pl\/wp-content\/uploads\/2026\/05\/Designer.png\">\n    \n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.4.0\/css\/all.min.css\">\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@300;400;500;600;700;900&display=swap\" rel=\"stylesheet\">\n\n        <script src=\"https:\/\/cdn.onesignal.com\/sdks\/web\/v16\/OneSignalSDK.page.js\" defer><\/script>\n    <script>\n      window.OneSignalDeferred = window.OneSignalDeferred || [];\n      OneSignalDeferred.push(function(OneSignal) {\n        OneSignal.init({ \n            appId: \"79b0782f-be15-4fdf-a094-0efc13e43c40\", \n            notifyButton: { enable: false },\n            serviceWorkerParam: { scope: \"\/\" },\n            serviceWorkerPath: \"\/?hd_pwa=sw\"\n        });\n      });\n    <\/script>\n    \n    <style>\n        #hd-app-container { font-family: 'Inter', sans-serif; }\n        .app-wrapper { height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }\n        .bg-medical-pattern { background-image: radial-gradient(rgba(236, 72, 153, 0.15) 2px, transparent 2px); background-size: 24px 24px; }\n        \n        .glass-card { background: rgba(255, 255, 255, 0.85); backdrop-filter: blur(20px); border-radius: 24px; box-shadow: 0 10px 40px -10px rgba(236, 72, 153, 0.15); border: 1px solid rgba(255, 255, 255, 0.8); margin-bottom: 1.25rem; position: relative; overflow: hidden; transition: all 0.3s ease; padding: 16px 20px; }\n        .glass-card:focus-within { box-shadow: 0 15px 50px -10px rgba(217, 70, 239, 0.3); transform: translateY(-2px); }\n        \n        @keyframes pulse-ring { 0% { transform: scale(0.8); box-shadow: 0 0 0 0 rgba(217, 70, 239, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 15px rgba(217, 70, 239, 0); } 100% { transform: scale(0.8); box-shadow: 0 0 0 0 rgba(217, 70, 239, 0); } }\n        .pulse-btn-icon { animation: pulse-ring 2s infinite; }\n        input[type=\"number\"]::-webkit-inner-spin-button, input[type=\"number\"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }\n        \n        \/* Flexbox dla zak\u0142adek by wype\u0142nia\u0142y dost\u0119pne miejsce *\/\n        .tab-content { display: none; width: 100%; flex: 1 1 auto; flex-direction: column; min-height: 0; }\n        .tab-content.active { display: flex; animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1); }\n        @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }\n        \n        \/* ELASTYCZNY WYKRES DOPASOWUJ\u0104CY SI\u0118 DO EKRANU *\/\n        .chart-main-container { display: flex; flex: 1; min-height: 250px; background: #fff; border-radius: 12px; box-shadow: 0 4px 20px -5px rgba(236, 72, 153, 0.08); border: 1px solid #fce7f3; overflow: hidden; position: relative; }\n    <\/style>\n\n    <div id=\"hd-app-container\" class=\"app-wrapper relative w-full max-w-md mx-auto bg-[#fffcfd] bg-medical-pattern text-slate-800 sm:border border-pink-100\">\n        \n        <!-- BANER INSTALACJI PWA NA G\u00d3RZE -->\n        <div id=\"hd-install-banner\" class=\"hidden bg-gradient-to-r from-pink-500 to-purple-600 text-white p-3 flex justify-between items-center text-sm font-bold cursor-pointer shadow-md w-full flex-shrink-0 z-50\" onclick=\"hdInstallPWA()\">\n            <span class=\"flex items-center\"><i class=\"fa-solid fa-download mr-2 animate-bounce\"><\/i> Zainstaluj aplikacj\u0119 na telefonie<\/span>\n            <span class=\"bg-white text-purple-600 px-3 py-1 rounded-full text-xs shadow-sm\">Instaluj<\/span>\n        <\/div>\n\n        <div id=\"hd-ios-install-hint\" class=\"hidden bg-pink-50 border-b border-pink-200 text-pink-800 p-3 text-xs md:text-sm shadow-inner text-center w-full flex-shrink-0 z-50\">\n            <strong>Masz iPhone'a?<\/strong> Dodaj t\u0119 stron\u0119 jako aplikacj\u0119! Kliknij ikon\u0119 udost\u0119pniania na dole ekranu, a nast\u0119pnie wybierz <strong>\"Dodaj do ekranu g\u0142\u00f3wnego\"<\/strong>.\n        <\/div>\n\n        <!-- HEADER -->\n        <div class=\"px-5 py-4 flex justify-between items-center bg-white\/80 backdrop-blur-md z-30 border-b border-pink-50 shadow-sm flex-shrink-0\">\n            <div class=\"flex items-center gap-3\">\n                <div class=\"w-10 h-10 rounded-xl bg-blue-50 text-blue-500 flex items-center justify-center border border-blue-100 shadow-sm\">\n                    <img decoding=\"async\" src=\"https:\/\/julia.julsoft.pl\/wp-content\/uploads\/2026\/05\/Designer.png\" alt=\"Ikona\" class=\"w-full h-full object-cover rounded-lg\">\n                <\/div>\n                <h1 class=\"text-xl font-black tracking-tight text-slate-800\">VitalSync<\/h1>\n            <\/div>\n            <div class=\"flex items-center gap-2 bg-white px-3 py-1.5 rounded-full border border-slate-100 shadow-sm\">\n                <span class=\"text-[9px] font-bold text-slate-500 uppercase tracking-widest\">Aktywna<\/span>\n                <div class=\"w-2.5 h-2.5 rounded-full bg-[#2dd4bf] shadow-[0_0_8px_#2dd4bf]\"><\/div>\n            <\/div>\n        <\/div>\n\n        <!-- OBSZAR PRZEWIJANY -->\n        <div class=\"flex-1 min-h-0 flex flex-col overflow-y-auto px-5 pt-6 pb-24 scroll-smooth relative z-20\">\n            \n            <div class=\"absolute top-10 left-10 w-32 h-32 bg-pink-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-pulse pointer-events-none\"><\/div>\n            <div class=\"absolute bottom-40 right-10 w-32 h-32 bg-purple-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-pulse pointer-events-none\"><\/div>\n\n            <!-- ZAK\u0141ADKA 1: NOWY POMIAR -->\n            <div id=\"tab-add\" class=\"tab-content active relative z-10\">\n                <div class=\"text-center mb-6\">\n                    <div class=\"text-[10px] text-pink-500 mb-1 font-black tracking-[0.2em] uppercase drop-shadow-sm\">System Pomiarowy<\/div>\n                    <div id=\"current-date-display\" class=\"text-2xl font-light text-slate-700 tracking-tight\">--:--<\/div>\n                <\/div>\n\n                <form id=\"add-log-form\" class=\"space-y-4 flex flex-col\">\n                    <div class=\"glass-card\">\n                        <div class=\"absolute -right-6 -top-6 text-pink-100 opacity-40 pointer-events-none\"><i class=\"fa-solid fa-droplet text-8xl\"><\/i><\/div>\n                        <div class=\"relative z-10\">\n                            <label class=\"block text-[10px] text-[#f472b6] font-black uppercase tracking-widest mb-1\">Skurczowe (SYS)<\/label>\n                            <div class=\"flex items-end justify-between\">\n                                <input type=\"number\" id=\"input-sys\" required min=\"50\" max=\"250\" class=\"w-2\/3 bg-transparent text-5xl font-black text-slate-800 outline-none placeholder-slate-200\" placeholder=\"120\">\n                                <div class=\"bg-pink-50\/80 text-pink-500 px-3 py-1.5 rounded-lg text-xs font-bold border border-pink-100 shadow-sm backdrop-blur-sm\">mmHg<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    \n                    <div class=\"glass-card\">\n                        <div class=\"absolute -right-4 -top-4 text-purple-100 opacity-40 pointer-events-none\"><i class=\"fa-solid fa-heart text-8xl\"><\/i><\/div>\n                        <div class=\"relative z-10\">\n                            <label class=\"block text-[10px] text-[#a855f7] font-black uppercase tracking-widest mb-1\">Rozkurczowe (DIA)<\/label>\n                            <div class=\"flex items-end justify-between\">\n                                <input type=\"number\" id=\"input-dia\" required min=\"30\" max=\"150\" class=\"w-2\/3 bg-transparent text-5xl font-black text-slate-800 outline-none placeholder-slate-200\" placeholder=\"80\">\n                                <div class=\"bg-purple-50\/80 text-purple-500 px-3 py-1.5 rounded-lg text-xs font-bold border border-purple-100 shadow-sm backdrop-blur-sm\">mmHg<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    \n                    <div class=\"glass-card\">\n                        <div class=\"absolute -right-6 -top-4 text-rose-100 opacity-40 pointer-events-none\"><i class=\"fa-solid fa-heart-pulse text-8xl\"><\/i><\/div>\n                        <div class=\"relative z-10\">\n                            <label class=\"block text-[10px] text-[#fb7185] font-black uppercase tracking-widest mb-1\">Puls (BPM)<\/label>\n                            <div class=\"flex items-end justify-between\">\n                                <input type=\"number\" id=\"input-pulse\" required min=\"30\" max=\"200\" class=\"w-2\/3 bg-transparent text-5xl font-black text-slate-800 outline-none placeholder-slate-200\" placeholder=\"70\">\n                                <div class=\"bg-rose-50\/80 text-rose-500 px-3 py-1.5 rounded-lg text-xs font-bold border border-rose-100 shadow-sm backdrop-blur-sm\">bpm<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    \n                    <div class=\"mt-4 mb-4 relative z-20\">\n                        <button type=\"submit\" id=\"btn-save-log\" class=\"w-full h-16 bg-gradient-to-r from-pink-500 via-purple-500 to-pink-500 bg-[length:200%_auto] hover:bg-[position:right_center] text-white rounded-2xl font-black text-lg shadow-[0_10px_30px_rgba(217,70,239,0.4)] transition-all duration-300 active:scale-95 flex items-center justify-center gap-3 overflow-hidden\">\n                            <div class=\"pulse-btn-icon rounded-full bg-white\/20 p-2 flex items-center justify-center\"><i class=\"fa-solid fa-check text-white\"><\/i><\/div>\n                            <span>ZAPISZ POMIAR<\/span>\n                        <\/button>\n                    <\/div>\n                <\/form>\n            <\/div>\n\n            <!-- ZAK\u0141ADKA 2: WYKRESY Z ELASTYCZNYM RENDEROWANIEM (Flexbox) -->\n            <div id=\"tab-charts\" class=\"tab-content relative z-10\">\n                <div class=\"flex justify-between items-end mb-4 flex-shrink-0\">\n                    <h2 class=\"text-2xl font-black text-transparent bg-clip-text bg-gradient-to-r from-slate-700 to-slate-900\">Karta Parametr\u00f3w<\/h2>\n                <\/div>\n                \n                <div class=\"chart-main-container flex-row mb-4\">\n                    <!-- Lewa kolumna (ZABLOKOWANA) - O\u015b Y + Nag\u0142\u00f3wki Wierszy -->\n                    <div class=\"w-[50px] flex-shrink-0 bg-[#fffafc] border-r border-pink-100 flex flex-col z-20 shadow-[2px_0_5px_rgba(0,0,0,0.03)]\">\n                        <!-- O\u015b Y elastycznie rozszerza si\u0119 -->\n                        <div id=\"karta-y-axis\" class=\"flex-grow relative w-full\"><\/div>\n                        \n                        <!-- Stopka tabeli w lewej kolumnie -->\n                        <div class=\"flex flex-col border-t border-pink-100 w-full bg-[#fffafc] flex-shrink-0\">\n                            <div class=\"h-[45px] flex items-center justify-center text-[9px] font-bold text-[#a855f7] border-b border-pink-50\">BP<\/div>\n                            <div class=\"h-[35px] flex items-center justify-center text-[9px] font-bold text-[#fb7185] border-b border-pink-50\">PULS<\/div>\n                            <div class=\"h-[35px] flex items-center justify-center text-[9px] font-bold text-slate-500 border-b border-pink-50\">DATA<\/div>\n                            <div class=\"h-[35px] flex items-center justify-center text-[9px] font-bold text-slate-400\">CZAS<\/div>\n                        <\/div>\n                    <\/div>\n\n                    <!-- Prawa kolumna (PRZEWIJANA POZIOMO) - Wykres + Kom\u00f3rki Tabeli -->\n                    <div class=\"flex-grow overflow-x-auto overflow-y-hidden scroll-smooth flex flex-col bg-white relative\" id=\"karta-scroll-area\">\n                        <!-- Wykres elastycznie dopasowany wielko\u015bci\u0105 do osi Y -->\n                        <div id=\"karta-graph-area\" class=\"flex-grow relative w-full min-w-full\">\n                            <svg id=\"karta-bg-grid\" class=\"absolute top-0 left-0 pointer-events-none\" style=\"z-index: 1;\"><\/svg>\n                            <svg id=\"karta-svg\" class=\"absolute top-0 left-0 pointer-events-none\" style=\"z-index: 10;\"><\/svg>\n                        <\/div>\n                        \n                        <!-- Wiersze z warto\u015bciami pod wykresem -->\n                        <div class=\"flex flex-col border-t border-pink-100 w-full flex-shrink-0\" id=\"karta-data-area\">\n                            <div class=\"flex h-[45px] border-b border-pink-50\" id=\"row-bp\"><\/div>\n                            <div class=\"flex h-[35px] border-b border-pink-50\" id=\"row-pulse\"><\/div>\n                            <div class=\"flex h-[35px] border-b border-pink-50\" id=\"row-date\"><\/div>\n                            <div class=\"flex h-[35px]\" id=\"row-time\"><\/div>\n                        <\/div>\n                    <\/div>\n                <\/div>\n                \n                <div class=\"flex-shrink-0 pb-2\">\n                    <div class=\"text-center text-[10px] text-slate-400 font-medium bg-white\/50 py-2 rounded-full backdrop-blur-sm border border-white mb-2\">\n                        <i class=\"fa-solid fa-arrows-left-right mr-1\"><\/i> Przesu\u0144 wykres w prawo\/lewo\n                    <\/div>\n                    \n                    <div class=\"flex justify-center gap-6 text-[10px] font-bold text-slate-600 uppercase bg-white\/80 p-3 rounded-2xl shadow-sm border border-white backdrop-blur-md\">\n                        <div class=\"flex items-center gap-2\"><div class=\"w-3 h-3 bg-[#a855f7] rounded-sm shadow-sm\"><\/div> Ci\u015bnienie<\/div>\n                        <div class=\"flex items-center gap-2\"><div class=\"w-3 h-3 bg-[#fb7185] rounded-full shadow-sm\"><\/div> Puls<\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- ZAK\u0141ADKA 3: HISTORIA Z MO\u017bLIWO\u015aCI\u0104 KASOWANIA -->\n            <div id=\"tab-history\" class=\"tab-content relative z-10\">\n                <div class=\"flex justify-between items-end mb-6 flex-shrink-0\">\n                    <h2 class=\"text-2xl font-black text-transparent bg-clip-text bg-gradient-to-r from-slate-700 to-slate-900\">Historia<\/h2>\n                    <span class=\"text-xs font-black text-pink-500 bg-pink-100 px-3 py-1.5 rounded-full shadow-inner border border-pink-200\" id=\"history-count\">0 wpis\u00f3w<\/span>\n                <\/div>\n                <div id=\"history-list\" class=\"space-y-4 mb-8\"><\/div>\n            <\/div>\n\n            <!-- ZAK\u0141ADKA 4: KONFIGURACJA -->\n            <div id=\"tab-settings\" class=\"tab-content relative z-10\">\n                <h2 class=\"text-2xl font-black mb-6 text-slate-800 tracking-tight flex-shrink-0\">Konfiguracja<\/h2>\n                \n                <div class=\"bg-white\/95 backdrop-blur-xl border border-white shadow-xl rounded-[24px] p-5 sm:p-6 relative overflow-hidden mb-8 flex-shrink-0\">\n                    <div class=\"bg-[#fdf2f8] p-4 rounded-2xl border border-pink-100 mb-6 text-center sm:text-left\">\n                        <p class=\"text-[11px] sm:text-xs text-slate-600 font-medium leading-relaxed\">\n                            Dostosuj godziny przypomnie\u0144 poni\u017cej. Aplikacja powiadomi Ci\u0119 o pomiarze zgodnie z Twoim planem.\n                        <\/p>\n                    <\/div>\n                    \n                    <div class=\"flex items-center justify-between border-b border-gray-100 pb-5 mb-5\">\n                        <div class=\"flex flex-col\">\n                            <span class=\"font-bold text-slate-800 text-sm mb-2\">Rano<\/span>\n                            <div class=\"flex items-center gap-2\">\n                                <i class=\"fa-regular fa-sun text-pink-400 text-lg\"><\/i>\n                                <div class=\"bg-white border border-gray-200 rounded-lg flex items-center px-2 py-1 shadow-sm w-[90px] focus-within:border-pink-400 transition-colors\">\n                                    <input type=\"time\" id=\"time-morning\" class=\"text-slate-700 text-xs font-bold outline-none bg-transparent w-full\">\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                        <label class=\"relative inline-flex items-center cursor-pointer mt-5\">\n                            <input type=\"checkbox\" id=\"toggle-morning\" class=\"sr-only peer\">\n                            <div class=\"w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-pink-500 shadow-inner\"><\/div>\n                        <\/label>\n                    <\/div>\n\n                    <div class=\"flex items-center justify-between border-b border-gray-100 pb-5 mb-6\">\n                        <div class=\"flex flex-col\">\n                            <span class=\"font-bold text-slate-800 text-sm mb-2\">Wieczorem<\/span>\n                            <div class=\"flex items-center gap-2\">\n                                <i class=\"fa-regular fa-moon text-purple-400 text-lg\"><\/i>\n                                <div class=\"bg-white border border-gray-200 rounded-lg flex items-center px-2 py-1 shadow-sm w-[90px] focus-within:border-purple-400 transition-colors\">\n                                    <input type=\"time\" id=\"time-evening\" class=\"text-slate-700 text-xs font-bold outline-none bg-transparent w-full\">\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                        <label class=\"relative inline-flex items-center cursor-pointer mt-5\">\n                            <input type=\"checkbox\" id=\"toggle-evening\" class=\"sr-only peer\">\n                            <div class=\"w-11 h-6 bg-gray-200 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-400 shadow-inner\"><\/div>\n                        <\/label>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Dolna Nawigacja -->\n        <div class=\"absolute bottom-0 left-0 w-full bg-white\/95 backdrop-blur-xl border-t border-pink-100 flex justify-around items-center pb-safe pt-2 px-2 z-50 shadow-[0_-10px_30px_rgba(236,72,153,0.05)] flex-shrink-0\">\n            <button class=\"nav-btn flex flex-col items-center p-2 pt-3 pb-3 w-16 text-pink-500 transition-colors\" data-target=\"tab-add\">\n                <div class=\"relative\"><i class=\"fa-solid fa-plus text-xl mb-1.5 relative z-10 drop-shadow-md\"><\/i><div class=\"nav-glow absolute top-1\/2 left-1\/2 transform -translate-x-1\/2 -translate-y-1\/2 w-8 h-8 bg-pink-400 rounded-full blur-md opacity-30\"><\/div><\/div>\n                <span class=\"text-[9px] font-black tracking-widest uppercase\">Dodaj<\/span>\n            <\/button>\n            <button class=\"nav-btn flex flex-col items-center p-2 pt-3 pb-3 w-16 text-slate-400 transition-colors\" data-target=\"tab-charts\">\n                <div class=\"relative\"><i class=\"fa-solid fa-chart-line text-xl mb-1.5 relative z-10\"><\/i><div class=\"nav-glow absolute top-1\/2 left-1\/2 transform -translate-x-1\/2 -translate-y-1\/2 w-8 h-8 bg-pink-400 rounded-full blur-md opacity-0\"><\/div><\/div>\n                <span class=\"text-[9px] font-black tracking-widest uppercase\">Wykres<\/span>\n            <\/button>\n            <button class=\"nav-btn flex flex-col items-center p-2 pt-3 pb-3 w-16 text-slate-400 transition-colors\" data-target=\"tab-history\">\n                <div class=\"relative\"><i class=\"fa-solid fa-clock-rotate-left text-xl mb-1.5 relative z-10\"><\/i><div class=\"nav-glow absolute top-1\/2 left-1\/2 transform -translate-x-1\/2 -translate-y-1\/2 w-8 h-8 bg-pink-400 rounded-full blur-md opacity-0\"><\/div><\/div>\n                <span class=\"text-[9px] font-black tracking-widest uppercase\">Historia<\/span>\n            <\/button>\n            <button class=\"nav-btn flex flex-col items-center p-2 pt-3 pb-3 w-16 text-slate-400 transition-colors\" data-target=\"tab-settings\">\n                <div class=\"relative\"><i class=\"fa-solid fa-bell text-xl mb-1.5 relative z-10\"><\/i><div class=\"nav-glow absolute top-1\/2 left-1\/2 transform -translate-x-1\/2 -translate-y-1\/2 w-8 h-8 bg-pink-400 rounded-full blur-md opacity-0\"><\/div><\/div>\n                <span class=\"text-[9px] font-black tracking-widest uppercase\">Alarmy<\/span>\n            <\/button>\n        <\/div>\n    <\/div>\n\n    <script>\n    let deferredPrompt;\n\n    if ('serviceWorker' in navigator) {\n        window.addEventListener('load', () => {\n            navigator.serviceWorker.register('https:\/\/julia.julsoft.pl\/?hd_pwa=sw').catch(err => console.log('B\u0142\u0105d PWA: ', err));\n        });\n    }\n\n    window.addEventListener('beforeinstallprompt', (e) => {\n        e.preventDefault();\n        deferredPrompt = e;\n        const banner = document.getElementById('hd-install-banner');\n        if(banner) banner.classList.remove('hidden');\n    });\n\n    window.hdInstallPWA = function() {\n        if (deferredPrompt) {\n            deferredPrompt.prompt();\n            deferredPrompt.userChoice.then((choiceResult) => {\n                if (choiceResult.outcome === 'accepted') {\n                    document.getElementById('hd-install-banner').classList.add('hidden');\n                }\n                deferredPrompt = null;\n            });\n        }\n    };\n\n    const isIos = () => \/iphone|ipad|ipod\/.test(window.navigator.userAgent.toLowerCase());\n    const isInStandaloneMode = () => ('standalone' in window.navigator) && (window.navigator.standalone);\n    \n    if (isIos() && !isInStandaloneMode()) {\n        const hint = document.getElementById('hd-ios-install-hint');\n        if(hint) hint.classList.remove('hidden');\n    }\n\n    \/\/ --- LOGIKA G\u0141\u00d3WNA APLIKACJI ---\n    document.addEventListener('DOMContentLoaded', () => {\n        const API_URL = 'https:\/\/julia.julsoft.pl\/index.php?rest_route=\/health-diary\/v1\/logs';\n        const NONCE = '5973652226';\n        let logsData = [];\n\n        \/\/ Obs\u0142uga Nawigacji\n        const navBtns = document.querySelectorAll('.nav-btn');\n        const tabs = document.querySelectorAll('.tab-content');\n        \n        navBtns.forEach(btn => {\n            btn.addEventListener('click', () => {\n                navBtns.forEach(b => {\n                    b.classList.remove('text-pink-500'); \n                    b.classList.add('text-slate-400');\n                    b.querySelector('.nav-glow').classList.remove('opacity-30');\n                    b.querySelector('.nav-glow').classList.add('opacity-0');\n                    b.querySelector('i').classList.remove('drop-shadow-md');\n                });\n                \n                btn.classList.add('text-pink-500'); \n                btn.classList.remove('text-slate-400');\n                btn.querySelector('.nav-glow').classList.add('opacity-30');\n                btn.querySelector('.nav-glow').classList.remove('opacity-0');\n                btn.querySelector('i').classList.add('drop-shadow-md');\n                \n                tabs.forEach(t => t.classList.remove('active'));\n                document.getElementById(btn.dataset.target).classList.add('active');\n                \n                if(btn.dataset.target === 'tab-charts') {\n                    setTimeout(renderCustomChart, 50);\n                }\n            });\n        });\n\n        \/\/ Obs\u0142uga Zegara\n        const dateDisplay = document.getElementById('current-date-display');\n        if(dateDisplay) {\n            setInterval(() => {\n                const now = new Date();\n                const months = ['stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca', 'lipca', 'sierpnia', 'wrze\u015bnia', 'pa\u017adziernika', 'listopada', 'grudnia'];\n                const days = ['Niedziela', 'Poniedzia\u0142ek', 'Wtorek', '\u015aroda', 'Czwartek', 'Pi\u0105tek', 'Sobota'];\n                const hours = String(now.getHours()).padStart(2, '0');\n                const minutes = String(now.getMinutes()).padStart(2, '0');\n                dateDisplay.innerText = `${days[now.getDay()]}, ${now.getDate()} ${months[now.getMonth()]} ${hours}:${minutes}`;\n            }, 1000);\n        }\n\n        \/\/ --- FUNKCJA USUWANIA WPIS\u00d3W Z BAZY ---\n        window.deleteLog = async function(id) {\n            if(!confirm('Czy na pewno chcesz bezpowrotnie usun\u0105\u0107 ten wpis pomiaru?')) return;\n            try {\n                const res = await fetch(`${API_URL}\/${id}`, { \n                    method: 'DELETE', \n                    headers: { 'X-WP-Nonce': NONCE } \n                });\n                if(res.ok) {\n                    await fetchLogs(); \/\/ Od\u015bwie\u017c logi po usuni\u0119ciu\n                } else {\n                    alert('Nie uda\u0142o si\u0119 usun\u0105\u0107 wpisu.');\n                }\n            } catch (e) {\n                console.error(\"B\u0142\u0105d podczas usuwania:\", e);\n            }\n        };\n\n        \/\/ Pobieranie danych\n        async function fetchLogs() {\n            try {\n                const res = await fetch(API_URL, { headers: { 'X-WP-Nonce': NONCE } });\n                if (res.ok) { \n                    logsData = await res.json(); \n                    updateHistoryUI(); \n                    if(document.getElementById('tab-charts').classList.contains('active')) {\n                        renderCustomChart(); \n                    }\n                }\n            } catch (e) {\n                console.error(\"B\u0142\u0105d pobierania:\", e);\n            }\n        }\n\n        const addForm = document.getElementById('add-log-form');\n        if(addForm) {\n            addForm.addEventListener('submit', async (e) => {\n                e.preventDefault();\n                const btnSave = document.getElementById('btn-save-log');\n                const originalContent = btnSave.innerHTML;\n                \n                btnSave.innerHTML = '<i class=\"fa-solid fa-spinner fa-spin text-white\"><\/i> <span>PRZETWARZANIE...<\/span>';\n                btnSave.disabled = true;\n                \n                const payload = { \n                    systolic: document.getElementById('input-sys').value, \n                    diastolic: document.getElementById('input-dia').value, \n                    pulse: document.getElementById('input-pulse').value \n                };\n                \n                try {\n                    const res = await fetch(API_URL, { \n                        method: 'POST', \n                        headers: { 'Content-Type': 'application\/json', 'X-WP-Nonce': NONCE }, \n                        body: JSON.stringify(payload) \n                    });\n                    \n                    if (res.ok) { \n                        e.target.reset(); \n                        await fetchLogs(); \n                        document.querySelector('[data-target=\"tab-charts\"]').click(); \n                    }\n                } catch (error) {\n                    console.error(\"B\u0142\u0105d zapisu:\", error);\n                } finally {\n                    btnSave.innerHTML = originalContent;\n                    btnSave.disabled = false;\n                }\n            });\n        }\n\n        \/\/ Generowanie historii (Z WYRA\u0179NYM PRZYCISKIEM USUWANIA)\n        function updateHistoryUI() {\n            const list = document.getElementById('history-list');\n            const historyCount = document.getElementById('history-count');\n            if(!list || !historyCount) return;\n            \n            historyCount.innerText = logsData.length + ' wpis\u00f3w';\n            list.innerHTML = '';\n            \n            if (logsData.length === 0) {\n                list.innerHTML = '<div class=\"text-center text-slate-400 text-sm py-10 bg-white\/60 rounded-2xl border border-pink-50\">Brak danych.<\/div>';\n                return;\n            }\n            \n            const reversedLogs = [...logsData].reverse();\n            let htmlContent = '';\n            \n            reversedLogs.forEach(log => {\n                const parts = log.measured_at.split(' ');\n                const datePart = parts[0].substring(5).replace('-', '.');\n                const timePart = parts[1].substring(0, 5);\n                \n                htmlContent += `\n                <div class=\"p-4 rounded-2xl bg-white\/80 backdrop-blur-md shadow-sm border border-pink-100 flex justify-between items-center mb-3 group transition-all\">\n                    <div class=\"flex items-center gap-4\">\n                        <div class=\"text-center bg-gradient-to-b from-pink-50 to-purple-50 rounded-xl p-2 min-w-[60px] border border-white shadow-inner\">\n                            <div class=\"text-xs font-black text-slate-600\">${timePart}<\/div>\n                            <div class=\"text-[9px] font-bold text-slate-400 tracking-wider\">${datePart}<\/div>\n                        <\/div>\n                        <div>\n                            <div class=\"text-xl font-black text-transparent bg-clip-text bg-gradient-to-r from-purple-500 to-pink-500 tracking-tight\">${log.systolic} <span class=\"text-slate-300 font-light text-base mx-0.5\">\/<\/span> ${log.diastolic}<\/div>\n                            <div class=\"text-[10px] font-black text-rose-500 mt-0.5 flex items-center gap-1.5 uppercase tracking-wider\"><i class=\"fa-solid fa-heart-pulse\"><\/i> ${log.pulse} bpm<\/div>\n                        <\/div>\n                    <\/div>\n                    <!-- Wyra\u017any przycisk usuni\u0119cia z animacj\u0105 hover -->\n                    <button onclick=\"deleteLog(${log.id})\" class=\"bg-red-50 text-red-500 hover:bg-red-500 hover:text-white p-3 rounded-2xl transition-all duration-300 shadow-sm border border-red-100 flex flex-col items-center justify-center min-w-[60px]\" title=\"Usu\u0144 wpis\">\n                        <i class=\"fa-solid fa-trash-can mb-1 text-lg\"><\/i>\n                        <span class=\"text-[9px] font-bold uppercase tracking-wider\">Usu\u0144<\/span>\n                    <\/button>\n                <\/div>`;\n            });\n            list.innerHTML = htmlContent;\n        }\n\n        \/\/ --- CA\u0141KOWICIE ELASTYCZNY WYKRES ---\n        function renderCustomChart() {\n            const yAxis = document.getElementById('karta-y-axis');\n            const bgGrid = document.getElementById('karta-bg-grid');\n            const dataSvg = document.getElementById('karta-svg');\n            const graphArea = document.getElementById('karta-graph-area');\n            \n            if(!yAxis || !bgGrid || !dataSvg || !graphArea) return;\n            \n            \/\/ Dynamiczna wysoko\u015b\u0107 na podstawie Flexboxa rodzica\n            const GRAPH_HEIGHT = graphArea.clientHeight; \n            \n            \/\/ Bezpieczne marginesy - daj\u0105 pewno\u015b\u0107, \u017ce \"220\" na g\u00f3rze i \"40\" na dole nie ulegn\u0105 obci\u0119ciu\n            const PADDING_TOP = 25; \n            const PADDING_BOTTOM = 25; \n            \n            \/\/ Zapobiega \"wybuchowi\" na bardzo, bardzo ma\u0142ych rozdzielczo\u015bciach\n            const USABLE_HEIGHT = Math.max(50, GRAPH_HEIGHT - PADDING_TOP - PADDING_BOTTOM);\n            \n            const MAX_VAL = 220;\n            const MIN_VAL = 40;\n            const RANGE = MAX_VAL - MIN_VAL;\n            \n            \/\/ Perfekcyjne wyliczenie wsp\u00f3\u0142rz\u0119dnej Y\n            const getY = (val) => {\n                const safeVal = Math.max(MIN_VAL, Math.min(MAX_VAL, val));\n                return PADDING_TOP + ((MAX_VAL - safeVal) \/ RANGE) * USABLE_HEIGHT;\n            };\n            \n            let yHTML = '';\n            let bgHTML = '';\n            \n            for (let v = MAX_VAL; v >= MIN_VAL; v -= 20) {\n                const yPos = getY(v);\n                yHTML += `<div style=\"position: absolute; top: ${yPos}px; left: 0; width: 100%; text-align: center; transform: translateY(-50%); font-size: 10px; font-weight: 700; color: #94a3b8; z-index: 20;\">${v}<\/div>`;\n                bgHTML += `<line x1=\"0\" y1=\"${yPos}\" x2=\"100%\" y2=\"${yPos}\" stroke=\"#fce7f3\" stroke-width=\"1.5\"\/>`;\n            }\n            \n            yAxis.innerHTML = yHTML;\n            bgGrid.innerHTML = bgHTML;\n            \n            const rBp = document.getElementById('row-bp');\n            const rPulse = document.getElementById('row-pulse');\n            const rDate = document.getElementById('row-date');\n            const rTime = document.getElementById('row-time');\n            \n            rBp.innerHTML = '';\n            rPulse.innerHTML = '';\n            rDate.innerHTML = '';\n            rTime.innerHTML = '';\n            \n            const colWidth = 50;\n            const scrollAreaWidth = document.getElementById('karta-scroll-area').clientWidth || window.innerWidth;\n            const dataCount = logsData.length > 0 ? logsData.length : 1; \n            const calculatedWidth = dataCount * colWidth;\n            const totalWidth = Math.max(calculatedWidth, scrollAreaWidth);\n            \n            \/\/ Ustawienie elastycznej szeroko\u015bci i wysoko\u015bci SVG\n            bgGrid.setAttribute('width', totalWidth); \n            bgGrid.setAttribute('height', GRAPH_HEIGHT);\n            dataSvg.setAttribute('width', totalWidth); \n            dataSvg.setAttribute('height', GRAPH_HEIGHT);\n            \n            document.getElementById('karta-data-area').style.width = `${totalWidth}px`;\n            \n            if (logsData.length === 0) return;\n            \n            let lp = null; \n            let dataContent = '';\n            \n            let bpRowHTML = '';\n            let pulseRowHTML = '';\n            let dateRowHTML = '';\n            let timeRowHTML = '';\n\n            logsData.forEach((log, index) => {\n                const cx = (index * colWidth) + 25; \n                const ys = getY(log.systolic);\n                const yd = getY(log.diastolic);\n                const yp = getY(log.pulse);\n                \n                \/\/ Bezb\u0142\u0119dne renderowanie s\u0142upk\u00f3w ci\u015bnienia \n                dataContent += `<line x1=\"${cx}\" y1=\"${ys}\" x2=\"${cx}\" y2=\"${yd}\" stroke=\"#a855f7\" stroke-width=\"3\" stroke-linecap=\"round\"\/>`;\n                dataContent += `<line x1=\"${cx-6}\" y1=\"${ys}\" x2=\"${cx+6}\" y2=\"${ys}\" stroke=\"#a855f7\" stroke-width=\"3\" stroke-linecap=\"round\"\/>`;\n                dataContent += `<line x1=\"${cx-6}\" y1=\"${yd}\" x2=\"${cx+6}\" y2=\"${yd}\" stroke=\"#a855f7\" stroke-width=\"3\" stroke-linecap=\"round\"\/>`;\n                \n                \/\/ Liniowy Puls\n                if (lp) {\n                    dataContent += `<line x1=\"${lp.x}\" y1=\"${lp.y}\" x2=\"${cx}\" y2=\"${yp}\" stroke=\"#fb7185\" stroke-width=\"2\"\/>`;\n                }\n                dataContent += `<circle cx=\"${cx}\" cy=\"${yp}\" r=\"4\" fill=\"#ffffff\" stroke=\"#fb7185\" stroke-width=\"2.5\"\/>`; \n                lp = { x: cx, y: yp };\n                \n                const parts = log.measured_at.split(' ');\n                const datePart = parts[0].substring(5).replace('-', '.'); \n                const timePart = parts[1].substring(0, 5);\n                \n                bpRowHTML += `<div class=\"w-[50px] flex-shrink-0 border-r border-pink-50 flex flex-col items-center justify-center text-[#a855f7] text-[11px] font-bold leading-tight h-[45px]\"><span>${log.systolic}<\/span><span class=\"text-[9px] border-t border-[#fce7f3] w-[80%] mt-[2px] pt-[2px] text-center\">${log.diastolic}<\/span><\/div>`;\n                pulseRowHTML += `<div class=\"w-[50px] flex-shrink-0 border-r border-pink-50 flex items-center justify-center text-[#fb7185] text-[11px] font-bold h-[35px]\">${log.pulse}<\/div>`;\n                dateRowHTML += `<div class=\"w-[50px] flex-shrink-0 border-r border-pink-50 flex items-center justify-center text-[9px] font-bold text-slate-500 h-[35px]\">${datePart}<\/div>`;\n                timeRowHTML += `<div class=\"w-[50px] flex-shrink-0 border-r border-pink-50 flex items-center justify-center text-[9px] font-bold text-slate-400 h-[35px]\">${timePart}<\/div>`;\n            });\n            \n            dataSvg.innerHTML = dataContent;\n            rBp.innerHTML = bpRowHTML;\n            rPulse.innerHTML = pulseRowHTML;\n            rDate.innerHTML = dateRowHTML;\n            rTime.innerHTML = timeRowHTML;\n            \n            const scrollArea = document.getElementById('karta-scroll-area'); \n            setTimeout(() => { \n                scrollArea.scrollLeft = scrollArea.scrollWidth; \n            }, 50);\n        }\n\n        \/\/ Nas\u0142uchiwanie na zmiany wymiar\u00f3w okna (ResizeObserver), aby wykres automatycznie reagowa\u0142\n        const graphAreaElement = document.getElementById('karta-graph-area');\n        if (graphAreaElement && window.ResizeObserver) {\n            new ResizeObserver(() => {\n                if(document.getElementById('tab-charts').classList.contains('active')) {\n                    renderCustomChart();\n                }\n            }).observe(graphAreaElement);\n        }\n\n        \/\/ --- Obs\u0142uga Ustawie\u0144 i Alarm\u00f3w OneSignal ---\n        const tm = document.getElementById('time-morning'); \n        const te = document.getElementById('time-evening');\n        const checkMorning = document.getElementById('toggle-morning');\n        const checkEvening = document.getElementById('toggle-evening');\n        \n        if(tm && te) {\n            const set = JSON.parse(localStorage.getItem('hd_settings') || '{\"morning\":false,\"evening\":false,\"morningTime\":\"07:00\",\"eveningTime\":\"22:00\"}');\n            \n            checkMorning.checked = set.morning; \n            checkEvening.checked = set.evening;\n            tm.value = set.morningTime; \n            te.value = set.eveningTime;\n            \n            function saveSettings() { \n                localStorage.setItem('hd_settings', JSON.stringify({ \n                    morning: checkMorning.checked, \n                    evening: checkEvening.checked, \n                    morningTime: tm.value, \n                    eveningTime: te.value \n                })); \n            }\n            \n            tm.addEventListener('change', saveSettings);\n            te.addEventListener('change', saveSettings);\n            checkMorning.addEventListener('change', saveSettings);\n            checkEvening.addEventListener('change', saveSettings);\n\n            let lastNotifiedMinute = '';\n            setInterval(() => {\n                const now = new Date(); \n                const h = String(now.getHours()).padStart(2,'0');\n                const m = String(now.getMinutes()).padStart(2,'0');\n                const currentTimeStr = `${h}:${m}`;\n                \n                if (lastNotifiedMinute !== currentTimeStr) {\n                    const s = JSON.parse(localStorage.getItem('hd_settings') || '{}');\n                    let notified = false;\n                    \n                    if (s.morning && currentTimeStr === (s.morningTime || '07:00')) {\n                        showNotif(\"Poranny Pomiar\", \"Rozpocznij dzie\u0144 ze zdrowiem! Czas zmierzy\u0107 ci\u015bnienie i puls.\");\n                        notified = true;\n                    }\n                    if (s.evening && currentTimeStr === (s.eveningTime || '22:00')) {\n                        showNotif(\"Wieczorny Pomiar\", \"Pami\u0119taj o wieczornej kontroli parametr\u00f3w.\");\n                        notified = true;\n                    }\n                    \n                    if (notified) {\n                        lastNotifiedMinute = currentTimeStr;\n                    }\n                }\n            }, 10000);\n        }\n\n        function showNotif(title, body) { \n            if (Notification.permission === 'granted' && navigator.serviceWorker.controller) {\n                navigator.serviceWorker.ready.then(reg => {\n                    reg.showNotification(title, { \n                        body: body, \n                        icon: 'https:\/\/julia.julsoft.pl\/wp-content\/uploads\/2026\/05\/Designer.png',\n                        badge: 'https:\/\/julia.julsoft.pl\/wp-content\/uploads\/2026\/05\/Designer.png',\n                        vibrate: [200, 100, 200]\n                    });\n                });\n            }\n        }\n\n        fetchLogs(); \n    });\n    <\/script>\n    <\/div>\n\t\t\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":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-19","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/19","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=19"}],"version-history":[{"count":4,"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/19\/revisions"}],"predecessor-version":[{"id":23,"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=\/wp\/v2\/pages\/19\/revisions\/23"}],"wp:attachment":[{"href":"https:\/\/julia.julsoft.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=19"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}