fix: persistentní theme - ukládání do localStorage bez cookie consent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
{"window_start":1773406850,"count":6}
|
||||
{"window_start":1773408334,"count":4}
|
||||
@@ -1 +1 @@
|
||||
{"window_start":1773406619,"count":1}
|
||||
{"window_start":1773407459,"count":1}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{j as e,m as f}from"./vendor-animation-0s3FMHwK.js";import{r as m}from"./vendor-react-BVs3cwbi.js";import{a9 as T}from"./vendor-utils-Dyr8OjFr.js";import{a as C,u as A,c as O,F as B,A as H}from"./index-c9Us0bor.js";import{F as I}from"./Forbidden-D25jV3Oq.js";import{c as W,b as k,g as w,d as z,e as S,a as v,h as E,i as y,f as b}from"./attendanceHelpers-D6sLEw0q.js";const L="/api/admin",R=s=>s.break_start&&s.break_end?`${b(s.break_start)} - ${b(s.break_end)}`:s.break_start?`${b(s.break_start)} - ?`:"—",Z=s=>s.project_logs&&s.project_logs.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.125rem"},children:s.project_logs.map((n,g)=>{let d,c,o=!1;if(n.hours!==null&&n.hours!==void 0)d=parseInt(n.hours)||0,c=parseInt(n.minutes)||0;else{o=!n.ended_at;const x=n.ended_at?new Date(n.ended_at):new Date,p=Math.floor((x-new Date(n.started_at))/6e4);d=Math.floor(p/60),c=p%60}return e.jsxs("span",{className:"admin-badge",style:{fontSize:"0.7rem",display:"inline-block",background:o?"var(--accent-light)":void 0},children:[n.project_name||`#${n.project_id}`," (",d,":",String(c).padStart(2,"0"),"h",o?" ▸":"",")"]},n.id||g)})}):s.project_name?e.jsx("span",{className:"admin-badge admin-badge-wrap",style:{fontSize:"0.75rem"},children:s.project_name}):"—",Y=s=>s.overtime>0?e.jsxs("span",{className:"leave-badge badge-overtime",children:["+",s.overtime,"h přesčas"]}):s.remaining>0?e.jsxs("span",{style:{color:"#dc2626"},children:["−",s.remaining,"h"]}):e.jsx("span",{style:{color:"#16a34a"},children:"splněno"});function Q(){const s=C(),{user:n,hasPermission:g}=A(),[d,c]=m.useState(!0),o=m.useRef(null),[x,p]=m.useState(()=>{const a=new Date;return`${a.getFullYear()}-${String(a.getMonth()+1).padStart(2,"0")}`}),[t,D]=m.useState({records:[],month_name:"",year:new Date().getFullYear(),total_minutes:0,vacation_hours:0,sick_hours:0,holiday_hours:0,unpaid_hours:0,leave_balance:null,monthly_fund:null}),_=m.useCallback(async()=>{c(!0);try{const a=await O(`${L}/attendance.php?action=history&month=${x}`);if(a.status===401)return;const i=await a.json();i.success&&D(i.data)}catch{s.error("Nepodařilo se načíst data")}finally{c(!1)}},[x,s]);if(m.useEffect(()=>{_()},[_]),!g("attendance.history"))return e.jsx(I,{});const $=()=>{if(!o.current)return;const a=window.open("","_blank");a.document.write(`
|
||||
import{j as e,m as f}from"./vendor-animation-0s3FMHwK.js";import{r as m}from"./vendor-react-BVs3cwbi.js";import{a9 as T}from"./vendor-utils-Dyr8OjFr.js";import{a as C,u as A,c as O,F as B,A as H}from"./index-fMsy8JiX.js";import{F as I}from"./Forbidden-D25jV3Oq.js";import{c as W,b as k,g as w,d as z,e as S,a as v,h as E,i as y,f as b}from"./attendanceHelpers-D6sLEw0q.js";const L="/api/admin",R=s=>s.break_start&&s.break_end?`${b(s.break_start)} - ${b(s.break_end)}`:s.break_start?`${b(s.break_start)} - ?`:"—",Z=s=>s.project_logs&&s.project_logs.length>0?e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.125rem"},children:s.project_logs.map((n,g)=>{let d,c,o=!1;if(n.hours!==null&&n.hours!==void 0)d=parseInt(n.hours)||0,c=parseInt(n.minutes)||0;else{o=!n.ended_at;const x=n.ended_at?new Date(n.ended_at):new Date,p=Math.floor((x-new Date(n.started_at))/6e4);d=Math.floor(p/60),c=p%60}return e.jsxs("span",{className:"admin-badge",style:{fontSize:"0.7rem",display:"inline-block",background:o?"var(--accent-light)":void 0},children:[n.project_name||`#${n.project_id}`," (",d,":",String(c).padStart(2,"0"),"h",o?" ▸":"",")"]},n.id||g)})}):s.project_name?e.jsx("span",{className:"admin-badge admin-badge-wrap",style:{fontSize:"0.75rem"},children:s.project_name}):"—",Y=s=>s.overtime>0?e.jsxs("span",{className:"leave-badge badge-overtime",children:["+",s.overtime,"h přesčas"]}):s.remaining>0?e.jsxs("span",{style:{color:"#dc2626"},children:["−",s.remaining,"h"]}):e.jsx("span",{style:{color:"#16a34a"},children:"splněno"});function Q(){const s=C(),{user:n,hasPermission:g}=A(),[d,c]=m.useState(!0),o=m.useRef(null),[x,p]=m.useState(()=>{const a=new Date;return`${a.getFullYear()}-${String(a.getMonth()+1).padStart(2,"0")}`}),[t,D]=m.useState({records:[],month_name:"",year:new Date().getFullYear(),total_minutes:0,vacation_hours:0,sick_hours:0,holiday_hours:0,unpaid_hours:0,leave_balance:null,monthly_fund:null}),_=m.useCallback(async()=>{c(!0);try{const a=await O(`${L}/attendance.php?action=history&month=${x}`);if(a.status===401)return;const i=await a.json();i.success&&D(i.data)}catch{s.error("Nepodařilo se načíst data")}finally{c(!1)}},[x,s]);if(m.useEffect(()=>{_()},[_]),!g("attendance.history"))return e.jsx(I,{});const $=()=>{if(!o.current)return;const a=window.open("","_blank");a.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{j as e,m as p,A as Z}from"./vendor-animation-0s3FMHwK.js";import{r as i,L as J}from"./vendor-react-BVs3cwbi.js";import{a9 as G}from"./vendor-utils-Dyr8OjFr.js";import{a as q,u as Q,c as b,b as X,F as r,A as C,f as l,C as ee}from"./index-c9Us0bor.js";import{F as se}from"./Forbidden-D25jV3Oq.js";import{b as $}from"./attendanceHelpers-D6sLEw0q.js";const N="/api/admin";function de(){const d=q(),{hasPermission:L}=Q(),[k,D]=i.useState(!0),[j,V]=i.useState(()=>{const s=new Date;return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-01`}),[g,A]=i.useState(()=>{const s=new Date,t=new Date(s.getFullYear(),s.getMonth()+1,0).getDate();return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(t).padStart(2,"0")}`}),[m,F]=i.useState(""),[h,E]=i.useState(""),[P,B]=i.useState({trips:[],vehicles:[],users:[],totals:{total:0,business:0,count:0}}),[n,I]=i.useState(null),w=i.useRef(null),[T,v]=i.useState(!1),[_,U]=i.useState(null),[a,o]=i.useState({vehicle_id:"",trip_date:"",start_km:"",end_km:"",route_from:"",route_to:"",is_business:1,notes:""}),[u,z]=i.useState({show:!1,trip:null}),y=i.useCallback(async(s=!0)=>{s&&D(!0);try{let t=`${N}/trips.php?action=admin&date_from=${j}&date_to=${g}`;m&&(t+=`&vehicle_id=${m}`),h&&(t+=`&user_id=${h}`);const c=await(await b(t)).json();c.success&&B(c.data)}catch{d.error("Nepodařilo se načíst data")}finally{s&&D(!1)}},[j,g,m,h,d]);if(i.useEffect(()=>{y()},[y]),X(T),!L("trips.admin"))return e.jsx(se,{});const H=s=>{U(s),o({vehicle_id:s.vehicle_id,trip_date:s.trip_date,start_km:s.start_km,end_km:s.end_km,route_from:s.route_from,route_to:s.route_to,is_business:s.is_business,notes:s.notes||""}),v(!0)},O=async()=>{if(parseInt(a.end_km)<=parseInt(a.start_km)){d.error("Konečný stav km musí být větší než počáteční");return}try{const t=await(await b(`${N}/trips.php?id=${_.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();t.success?(v(!1),await y(!1),await new Promise(x=>setTimeout(x,300)),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},W=async()=>{if(u.trip)try{const t=await(await b(`${N}/trips.php?id=${u.trip.id}`,{method:"DELETE"})).json();t.success?(z({show:!1,trip:null}),await y(!1),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},K=async()=>{try{let s=`${N}/trips.php?action=print&date_from=${j}&date_to=${g}`;m&&(s+=`&vehicle_id=${m}`),h&&(s+=`&user_id=${h}`);const x=await(await b(s)).json();x.success&&(I(x.data),setTimeout(()=>{if(w.current){const c=window.open("","_blank");c.document.write(`
|
||||
import{j as e,m as p,A as Z}from"./vendor-animation-0s3FMHwK.js";import{r as i,L as J}from"./vendor-react-BVs3cwbi.js";import{a9 as G}from"./vendor-utils-Dyr8OjFr.js";import{a as q,u as Q,c as b,b as X,F as r,A as C,f as l,C as ee}from"./index-fMsy8JiX.js";import{F as se}from"./Forbidden-D25jV3Oq.js";import{b as $}from"./attendanceHelpers-D6sLEw0q.js";const N="/api/admin";function de(){const d=q(),{hasPermission:L}=Q(),[k,D]=i.useState(!0),[j,V]=i.useState(()=>{const s=new Date;return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-01`}),[g,A]=i.useState(()=>{const s=new Date,t=new Date(s.getFullYear(),s.getMonth()+1,0).getDate();return`${s.getFullYear()}-${String(s.getMonth()+1).padStart(2,"0")}-${String(t).padStart(2,"0")}`}),[m,F]=i.useState(""),[h,E]=i.useState(""),[P,B]=i.useState({trips:[],vehicles:[],users:[],totals:{total:0,business:0,count:0}}),[n,I]=i.useState(null),w=i.useRef(null),[T,v]=i.useState(!1),[_,U]=i.useState(null),[a,o]=i.useState({vehicle_id:"",trip_date:"",start_km:"",end_km:"",route_from:"",route_to:"",is_business:1,notes:""}),[u,z]=i.useState({show:!1,trip:null}),y=i.useCallback(async(s=!0)=>{s&&D(!0);try{let t=`${N}/trips.php?action=admin&date_from=${j}&date_to=${g}`;m&&(t+=`&vehicle_id=${m}`),h&&(t+=`&user_id=${h}`);const c=await(await b(t)).json();c.success&&B(c.data)}catch{d.error("Nepodařilo se načíst data")}finally{s&&D(!1)}},[j,g,m,h,d]);if(i.useEffect(()=>{y()},[y]),X(T),!L("trips.admin"))return e.jsx(se,{});const H=s=>{U(s),o({vehicle_id:s.vehicle_id,trip_date:s.trip_date,start_km:s.start_km,end_km:s.end_km,route_from:s.route_from,route_to:s.route_to,is_business:s.is_business,notes:s.notes||""}),v(!0)},O=async()=>{if(parseInt(a.end_km)<=parseInt(a.start_km)){d.error("Konečný stav km musí být větší než počáteční");return}try{const t=await(await b(`${N}/trips.php?id=${_.id}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)})).json();t.success?(v(!1),await y(!1),await new Promise(x=>setTimeout(x,300)),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},W=async()=>{if(u.trip)try{const t=await(await b(`${N}/trips.php?id=${u.trip.id}`,{method:"DELETE"})).json();t.success?(z({show:!1,trip:null}),await y(!1),d.success(t.message)):d.error(t.error)}catch{d.error("Chyba připojení")}},K=async()=>{try{let s=`${N}/trips.php?action=print&date_from=${j}&date_to=${g}`;m&&(s+=`&vehicle_id=${m}`),h&&(s+=`&user_id=${h}`);const x=await(await b(s)).json();x.success&&(I(x.data),setTimeout(()=>{if(w.current){const c=window.open("","_blank");c.document.write(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{j as x}from"./vendor-animation-0s3FMHwK.js";import{r as t}from"./vendor-react-BVs3cwbi.js";import{a as L,c as O}from"./index-c9Us0bor.js";function J({column:e,sort:r,order:n}){return r!==e?null:x.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{marginLeft:4,verticalAlign:"middle"},children:x.jsx("path",{d:n==="ASC"?"M18 15l-6-6-6 6":"M6 9l6 6 6-6"})})}function V(e,r="DESC"){const[n,a]=t.useState(e),[o,c]=t.useState(r),i=t.useRef(!1),S=t.useCallback(u=>{i.current=!0,a(m=>m===u?(c(h=>h==="ASC"?"DESC":"ASC"),m):(c("DESC"),u))},[]),d=i.current?n:null;return{sort:n,order:o,handleSort:S,activeSort:d}}function I(e,r=300){const[n,a]=t.useState(e);return t.useEffect(()=>{const o=setTimeout(()=>a(e),r);return()=>clearTimeout(o)},[e,r]),n}const N="/api/admin";function _(e,{dataKey:r,search:n,sort:a,order:o,page:c,perPage:i,extraParams:S,errorMsg:d="Nepodařilo se načíst data"}={}){const u=L(),[m,h]=t.useState([]),[j,D]=t.useState(!0),[w,k]=t.useState(null),l=t.useRef(null),p=S?JSON.stringify(S):"",b=I(n,300),C=t.useCallback(async()=>{l.current&&l.current.abort();const g=new AbortController;l.current=g;try{const s=new URLSearchParams;if(b&&s.set("search",b),a&&s.set("sort",a),o&&s.set("order",o),c&&s.set("page",c),i&&s.set("per_page",i),p){const R=JSON.parse(p);Object.entries(R).forEach(([y,A])=>{A&&s.set(y,A)})}const E=await O(`${N}/${e}?${s}`,{signal:g.signal});if(E.status===401)return;const f=await E.json();f.success?(h(f.data[r]||[]),f.data.pagination&&k(f.data.pagination)):u.error(f.error||d)}catch(s){if(s.name==="AbortError")return;u.error("Chyba připojení")}finally{D(!1)}},[u,e,r,b,a,o,c,i,p,d]);return t.useEffect(()=>(C(),()=>{l.current&&l.current.abort()}),[C]),{items:m,setItems:h,loading:j,pagination:w,refetch:C}}export{J as S,_ as a,V as u};
|
||||
import{j as x}from"./vendor-animation-0s3FMHwK.js";import{r as t}from"./vendor-react-BVs3cwbi.js";import{a as L,c as O}from"./index-fMsy8JiX.js";function J({column:e,sort:r,order:n}){return r!==e?null:x.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",style:{marginLeft:4,verticalAlign:"middle"},children:x.jsx("path",{d:n==="ASC"?"M18 15l-6-6-6 6":"M6 9l6 6 6-6"})})}function V(e,r="DESC"){const[n,a]=t.useState(e),[o,c]=t.useState(r),i=t.useRef(!1),S=t.useCallback(u=>{i.current=!0,a(m=>m===u?(c(h=>h==="ASC"?"DESC":"ASC"),m):(c("DESC"),u))},[]),d=i.current?n:null;return{sort:n,order:o,handleSort:S,activeSort:d}}function I(e,r=300){const[n,a]=t.useState(e);return t.useEffect(()=>{const o=setTimeout(()=>a(e),r);return()=>clearTimeout(o)},[e,r]),n}const N="/api/admin";function _(e,{dataKey:r,search:n,sort:a,order:o,page:c,perPage:i,extraParams:S,errorMsg:d="Nepodařilo se načíst data"}={}){const u=L(),[m,h]=t.useState([]),[j,D]=t.useState(!0),[w,k]=t.useState(null),l=t.useRef(null),p=S?JSON.stringify(S):"",b=I(n,300),C=t.useCallback(async()=>{l.current&&l.current.abort();const g=new AbortController;l.current=g;try{const s=new URLSearchParams;if(b&&s.set("search",b),a&&s.set("sort",a),o&&s.set("order",o),c&&s.set("page",c),i&&s.set("per_page",i),p){const R=JSON.parse(p);Object.entries(R).forEach(([y,A])=>{A&&s.set(y,A)})}const E=await O(`${N}/${e}?${s}`,{signal:g.signal});if(E.status===401)return;const f=await E.json();f.success?(h(f.data[r]||[]),f.data.pagination&&k(f.data.pagination)):u.error(f.error||d)}catch(s){if(s.name==="AbortError")return;u.error("Chyba připojení")}finally{D(!1)}},[u,e,r,b,a,o,c,i,p,d]);return t.useEffect(()=>(C(),()=>{l.current&&l.current.abort()}),[C]),{items:m,setItems:h,loading:j,pagination:w,refetch:C}}export{J as S,_ as a,V as u};
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -29,7 +29,7 @@
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Plus+Jakarta+Sans:wght@400;500;600;700&family=Urbanist:wght@400;500;600;700;800&display=swap"
|
||||
rel="stylesheet" />
|
||||
<script type="module" crossorigin src="/assets/index-c9Us0bor.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-fMsy8JiX.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BVs3cwbi.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-animation-0s3FMHwK.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-utils-Dyr8OjFr.js">
|
||||
|
||||
4
dist/vendor/composer/installed.php
vendored
4
dist/vendor/composer/installed.php
vendored
@@ -3,7 +3,7 @@
|
||||
'name' => 'boha/website',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '019a8355dc85203c5fc76591ec9c01a01068edc9',
|
||||
'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -13,7 +13,7 @@
|
||||
'boha/website' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '019a8355dc85203c5fc76591ec9c01a01068edc9',
|
||||
'reference' => '4c8a41c1072f825e78f3a6381a0e2c27e90b7382',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
import { createContext, useContext, useState, useEffect } from 'react'
|
||||
|
||||
const ThemeContext = createContext()
|
||||
const COOKIE_NAME = 'boha_cookie_consent'
|
||||
|
||||
function hasAcceptedCookies() {
|
||||
return document.cookie.split(';').some(cookie =>
|
||||
cookie.trim() === `${COOKIE_NAME}=accepted`
|
||||
)
|
||||
}
|
||||
|
||||
export function ThemeProvider({ children }) {
|
||||
const [theme, setTheme] = useState(() => {
|
||||
if (typeof window !== 'undefined' && hasAcceptedCookies()) {
|
||||
if (typeof window !== 'undefined') {
|
||||
return localStorage.getItem('boha-theme') || 'dark'
|
||||
}
|
||||
return 'dark'
|
||||
@@ -19,10 +12,7 @@ export function ThemeProvider({ children }) {
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute('data-theme', theme)
|
||||
|
||||
if (hasAcceptedCookies()) {
|
||||
localStorage.setItem('boha-theme', theme)
|
||||
}
|
||||
|
||||
const themeColor = theme === 'dark' ? '#12121a' : '#ffffff'
|
||||
document.querySelector('meta[name="theme-color"]')?.setAttribute('content', themeColor)
|
||||
|
||||
Reference in New Issue
Block a user