From 08f5413740a064c50a909f856386810a02d973a0 Mon Sep 17 00:00:00 2001 From: aronwoost Date: Sun, 6 Oct 2024 19:18:15 +0000 Subject: [PATCH] Update gh-pages to output generated at 3af8569 --- 404.html | 2 +- _next/static/chunks/app/page-f4f367308259435b.js | 1 + _next/static/chunks/app/page-f61664260347a81b.js | 1 - _next/static/css/06c17f67d215aa32.css | 1 + _next/static/css/fbd5526d4d827033.css | 1 - .../_buildManifest.js | 0 .../_ssgManifest.js | 0 index.html | 2 +- index.txt | 4 ++-- 9 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 _next/static/chunks/app/page-f4f367308259435b.js delete mode 100644 _next/static/chunks/app/page-f61664260347a81b.js create mode 100644 _next/static/css/06c17f67d215aa32.css delete mode 100644 _next/static/css/fbd5526d4d827033.css rename _next/static/{nAWyEkGb1sc3C9ZSnsRtI => d8pRbfMMUIWywRCL2v036}/_buildManifest.js (100%) rename _next/static/{nAWyEkGb1sc3C9ZSnsRtI => d8pRbfMMUIWywRCL2v036}/_ssgManifest.js (100%) diff --git a/404.html b/404.html index f961c97..e78d919 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -404: This page could not be found.Google Calendar Hours

404

This page could not be found.

\ No newline at end of file +404: This page could not be found.Google Calendar Hours

404

This page could not be found.

\ No newline at end of file diff --git a/_next/static/chunks/app/page-f4f367308259435b.js b/_next/static/chunks/app/page-f4f367308259435b.js new file mode 100644 index 0000000..d449726 --- /dev/null +++ b/_next/static/chunks/app/page-f4f367308259435b.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{5554:function(e,t,a){Promise.resolve().then(a.bind(a,3423))},3423:function(e,t,a){"use strict";a.r(t),a.d(t,{default:function(){return eV}});var n=a(7437),r=a(2265),s=a(8575),l=a(2239),o=a(1455);let c=(0,o.oM)({name:"authentication",initialState:null,reducers:{}}),i=e=>e.authentication.accessToken,d=e=>!!i(e);var u=c.reducer;let h=()=>{let e=(0,l.c)({client_id:"502172359025.apps.googleusercontent.com",redirect_uri:"https://google-calendar-hours.com",scope:"https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.readonly",response_type:"token"});return"https://accounts.google.com/o/oauth2/auth?".concat(e)};var p=()=>(0,n.jsxs)(r.Fragment,{children:[(0,n.jsx)("p",{children:"This web app lets you see how many hours you spend on a Google Calendar. It uses the Google Calendar API to fetch your calendars and events, crunches the data and displays it nicely. You can filter by day, week, month, year, total or add a custom time range."}),(0,n.jsx)("p",{children:"You need to authorize the app with the following link:"}),(0,n.jsx)("a",{href:h(),"data-testid":"AuthLink",children:(0,n.jsx)("img",{src:"./google_auth.png",alt:"Auth with Google",width:"191",height:"46"})}),(0,n.jsx)("h3",{children:"Privacy Policy"}),(0,n.jsx)("p",{children:"This app connects to the Google Calendar API to fetch your calendars and events, so that it can calculate the hours. This connection happens directly from your browser to the Google API. There are no server or services involved that might cache the data."}),(0,n.jsx)("p",{children:"None of the data fetched from the Google Calendar API is saved elsewhere but in your browser. After you close the browser window/tab all authentication data is delete (technical detail: sessionStorage is used). Thats why you need to reauthorize with Google the next time you visit the page."}),(0,n.jsx)("p",{children:"This app only has read-only access to your calendar data."})]}),m=a(1096),v=a.n(m);let y="https://www.googleapis.com/calendar/v3/",g=async e=>{let{url:t,accessToken:a,params:n}=e,r=await fetch("".concat(t,"?").concat((0,l.c)({access_token:a,...n})));return 200!==r.status?(sessionStorage.removeItem("accessToken"),window.location="/",Promise.reject()):r.json()},x=e=>{let{accessToken:t}=e;return g({url:"".concat(y,"users/me/calendarList"),accessToken:t})},w=async e=>{let{accessToken:t,calendarId:a,pageToken:n,acc:r}=e,{items:s,nextPageToken:l}=await g({url:"".concat(y,"calendars/").concat(encodeURIComponent(a),"/events"),accessToken:t,params:{singleEvents:!0,maxResults:2500,pageToken:n,timeMax:v()().add(2,"year").toJSON()}});return l?w({accessToken:t,calendarId:a,pageToken:l,acc:[...r,...s]}):[...r,...s]},j=e=>{let{accessToken:t,calendarId:a}=e;return w({accessToken:t,calendarId:a,acc:[]})};var _=a(2713);a(774);let f=(0,o.oM)({name:"calendarEvents",initialState:{loading:!1,map:{}},reducers:{setCalendarEvents:(e,t)=>{let{payload:a}=t;e.map[a.calendarId]=a.events},setLoading:(e,t)=>{let{payload:a}=t;e.loading=a}}}),{setCalendarEvents:S,setLoading:b}=f.actions,N=e=>{let{calendarId:t}=e;return async(e,a)=>{let n=i(a());try{e(b(!0));let a=await j({accessToken:n,calendarId:t});e(S({calendarId:t,events:a.map(e=>{let{id:t,summary:a,start:n,end:r}=e;return n.dateTime?{id:t,summary:a,start:n.dateTime,end:r.dateTime}:null}).filter(Boolean)}))}catch(e){}finally{e(b(!1))}}},k=e=>{var t,a;return null!==(a=null===(t=e.calendarEvents)||void 0===t?void 0:t.loading)&&void 0!==a&&a},D=(e,t)=>{var a,n;return null!==(n=!k(e)&&(null===(a=e.calendarEvents)||void 0===a?void 0:a.map[t]))&&void 0!==n?n:null};var T=f.reducer;let E=e=>{let t;try{t=JSON.parse(window.localStorage.getItem("config"))}catch(e){}let a={...t,...e};window.localStorage.setItem("config",JSON.stringify(a))},C=()=>{try{return JSON.parse(window.localStorage.getItem("config"))}catch(e){}return null},O={DAY:"day",WEEK:"week",MONTH:"month",YEAR:"year",TOTAL:"total",CUSTOM:"custom"},I="date",Y="amount",M={MONDAY:"monday",SUNDAY:"sunday"};var A=e=>Math.round(100*e)/100;let L=(0,o.oM)({name:"viewState",initialState:null,reducers:{setSelectedCalendarId:(e,t)=>{let{payload:a}=t;e.selectedCalendarId=a},setRangeType:(e,t)=>{let{payload:a}=t;e.selectedRangeType=a},changeRange:(e,t)=>{let{payload:a}=t;"prev"===a?e.currentDatePointerStart=v()(e.currentDatePointerStart).subtract(1,e.selectedRangeType).toJSON():"next"===a&&(e.currentDatePointerStart=v()(e.currentDatePointerStart).add(1,e.selectedRangeType).toJSON())},resetRange:e=>{e.currentDatePointerStart=v()().startOf("day").toJSON()},setWeekStart:(e,t)=>{let{payload:a}=t;e.weekStart=a},setStart:(e,t)=>{let{payload:a}=t;e.currentDatePointerStart=a},setEnd:(e,t)=>{let{payload:a}=t;e.currentDatePointerEnd=a}}}),{changeRange:R,resetRange:P}=L.actions,{setSelectedCalendarId:J,setRangeType:H,setWeekStart:B,setStart:F,setEnd:W}=L.actions,U=e=>e.viewState.selectedCalendarId,G=e=>e.viewState.currentDatePointerStart,Z=e=>e.viewState.selectedRangeType,K=e=>e.viewState.weekStart,q=e=>e.viewState.weekStart===M.SUNDAY?"en":"de",z=(0,_.P1)([e=>e],e=>{let t,a;let{selectedRangeType:n,currentDatePointerStart:r,currentDatePointerEnd:s}=e.viewState,l=v()(r);return n===O.CUSTOM?{start:v()(r),end:v()(s).add(1,"day")}:(n===O.DAY?a=(t=l.startOf("day")).add(1,"day"):n===O.WEEK?a=(t=l.locale(q(e)).startOf("day").weekday(0)).add(1,"week"):n===O.MONTH?a=(t=l.startOf("month")).add(1,"month"):n===O.YEAR?a=(t=l.startOf("year")).add(1,"year"):n===O.TOTAL&&(t=v()("2000-01-01T10:00:00Z"),a=v()("2040-01-01T10:00:00Z")),{start:t,end:a})}),V=(0,_.P1)([e=>e],e=>{let t=D(e,U(e));if(!t)return null;let{start:a,end:n}=z(e);return t.filter(e=>{let{start:t,end:r}=e;return!(new Date(r)n)}).map(e=>{let{start:t,end:r,...s}=e;return{...s,start:new Date(t)n?n.toJSON():r}})}),X=e=>{let t=V(e);if(!t)return null;let a=0;return t.forEach(e=>{let{start:t,end:n}=e;a+=(new Date(n)-new Date(t))/1e3/60/60}),A(a)},Q=e=>{var t;return(null===(t=V(e))||void 0===t?void 0:t.length)||0},$=e=>{let{calendarId:t}=e;return(e,a)=>{e(J(t)),E({selectedCalendarId:t}),D(a(),t)||e(N({calendarId:t}))}},ee=e=>{let{range:t}=e;return(e,a)=>{if(t===O.CUSTOM){let{start:t,end:n}=z(a()),r=n.subtract(1,"day");e(F(t.toJSON())),e(W(r.toJSON())),E({start:t.toJSON(),end:r.toJSON()})}e(H(t)),E({selectedRangeType:t})}},et=e=>t=>{t(B(e)),E({weekStart:e})},ea=e=>t=>{t(F(e)),E({start:e})},en=e=>t=>{t(W(e)),E({end:e})};var er=L.reducer;let es=(0,o.oM)({name:"calendars",initialState:{list:null},reducers:{setCalendars:(e,t)=>{let{payload:a}=t;e.list=a}}}),{setCalendars:el}=es.actions,eo=()=>async(e,t)=>{let a=i(t());try{var n;let{items:t}=await x({accessToken:a}),r=t.map(e=>{let{id:t,summary:a}=e;return{id:t,label:a}});e(el(r));let{selectedCalendarId:s}=null!==(n=C())&&void 0!==n?n:{};if(s){let t=null==r?void 0:r.find(e=>{let{id:t}=e;return t===s});e(t?$({calendarId:s}):$({calendarId:null}))}}catch(e){}},ec=e=>e.calendars.list;var ei=es.reducer,ed=()=>{let e=(0,s.I0)(),t=(0,s.v9)(ec),a=(0,s.v9)(U);return(0,n.jsxs)("select",{"data-testid":"CalendarsList",className:"form-select",onChange:t=>{e($({calendarId:t.target.value}))},value:null!=a?a:"",children:[!a&&(0,n.jsx)("option",{children:"Please select calendar"},"default"),t.map(e=>{let{id:t,label:a}=e;return(0,n.jsx)("option",{value:t,children:a},t)})]})},eu=()=>{let e=(0,s.I0)(),t=(0,s.v9)(Z);return(0,n.jsxs)("select",{"data-testid":"RangeSelectList",className:"form-select",onChange:t=>e(ee({range:t.target.value})),value:t,children:[(0,n.jsx)("option",{value:"day",children:"Day"}),(0,n.jsx)("option",{value:"week",children:"Week"}),(0,n.jsx)("option",{value:"month",children:"Month"}),(0,n.jsx)("option",{value:"year",children:"Year"}),(0,n.jsx)("option",{value:"total",children:"Total"}),(0,n.jsx)("option",{value:"custom",children:"Custom"})]})},eh=a(6760),ep=a.n(eh),em=()=>{let e=(0,s.I0)();return(0,n.jsxs)("div",{"data-testid":"RangeChanger",className:"btn-group",role:"group",children:[(0,n.jsx)("button",{type:"button",className:ep()("btn","btn-outline-secondary"),onClick:()=>e(R("prev")),children:"Prev"}),(0,n.jsx)("button",{type:"button",className:ep()("btn","btn-outline-secondary"),onClick:()=>e(P()),children:"Reset"}),(0,n.jsx)("button",{type:"button",className:ep()("btn","btn-outline-secondary"),onClick:()=>e(R("next")),children:"Next"})]})},ev=a(5304),ey=a.n(ev),eg=()=>{let e=(0,s.I0)(),{start:t,end:a}=(0,s.v9)(z);return(0,n.jsxs)("div",{className:ep()(ey().component,"input-group","input-group-sm"),"data-testid":"CustomRange",children:[(0,n.jsx)("label",{htmlFor:"dateStart",className:"input-group-text",children:"Start:"}),(0,n.jsx)("input",{className:ep()("form-control",ey().inputDate),type:"date",id:"dateStart",value:v()(t).format("YYYY-MM-DD"),onChange:t=>{let{target:a}=t;return e(ea(v()(a.value).toJSON()))}}),(0,n.jsx)("label",{htmlFor:"dateEnd",className:"input-group-text",children:"End:"}),(0,n.jsx)("input",{className:ep()("form-control",ey().inputDate),type:"date",id:"dateEnd",value:v()(a).subtract(1,"day").format("YYYY-MM-DD"),onChange:t=>{let{target:a}=t;return e(en(v()(a.value).toJSON()))}})]})},ex=a(6664),ew=a.n(ex),ej=()=>(0,n.jsx)("div",{className:ew().hours,children:"".concat((0,s.v9)(X),"h")}),e_=(e,t)=>new Intl.DateTimeFormat([navigator.language,"en-US"],t).format(e),ef=()=>{let e;let t=(0,s.v9)(G),a=(0,s.v9)(Z),r=(0,s.v9)(q),l=v()(t);if(a===O.DAY)e=e_(v()(l),{weekday:"long",day:"numeric",month:"long",year:"numeric"});else if(a===O.WEEK){let t=l.locale(r).weekday(0),a=e_(t,{day:"numeric",month:"numeric",year:"numeric"}),n=e_(t.add(1,"week").subtract(1,"day"),{day:"numeric",month:"numeric",year:"numeric"});e="".concat(a," - ").concat(n)}else a===O.MONTH?e=e_(l,{month:"long",year:"numeric"}):a===O.YEAR&&(e=e_(l,{year:"numeric"}));return(0,n.jsx)("div",{"data-testid":"RangeDisplay",children:e})},eS=a(5524),eb=a.n(eS),eN=e=>{let t=new Blob(["\uFEFF"+e],{type:"text/csv;charset=UTF-8"});return window.URL.createObjectURL(t)},ek=a(1546),eD=a.n(ek);v().extend(eb());let eT=(e,t)=>{let{hours:a}=e,{hours:n}=t;return a>n?-1:a{let{start:a}=e,{start:n}=t;return an?1:0},eC=async e=>{try{await navigator.clipboard.writeText(e)}catch(e){}},eO=e=>v()(e).format("DD.MM.YYYY HH:mm");var eI=()=>{var e;let t,a;let[l,o]=(0,r.useState)(I),c=(0,s.v9)(U),i=(0,s.v9)(V),d=(0,s.v9)(ec),u=(0,s.v9)(G),h=null===(e=d.find(e=>e.id===c))||void 0===e?void 0:e.label,p="dark",m=i.sort(eE).map((e,t,a)=>{var n,r;return v()(e.start).isoWeek()!==((null==a?void 0:null===(n=a[t-1])||void 0===n?void 0:n.start)&&v()(null==a?void 0:null===(r=a[t-1])||void 0===r?void 0:r.start).isoWeek())&&(p="dark"===p?"light":"dark"),{...e,hours:(new Date(e.end)-new Date(e.start))/1e3/60/60,background:p}});return l===Y?m=Object.entries(m.reduce((e,t)=>{let{summary:a,hours:n}=t;return e[a]=e[a]?e[a]+=n:n,e},{})).map(e=>{let[t,a]=e;return{summary:t,hours:a,id:t}}).sort(eT):(t=eN(["Start,End,Title,Hours"].concat(m.map(e=>{let{start:t,end:a,summary:n,hours:r}=e;return"".concat(eO(t),",").concat(eO(a),',"').concat(n,'",').concat(A(r))})).join("\n")),a="".concat(h,"_").concat(v()(u).locale("en").format("MMMM_YYYY"),"_(").concat(v()().format("YYYYMMDDHHmmss"),").csv")),(0,n.jsxs)("div",{children:[(0,n.jsx)("ul",{className:eD().list,children:m.map(e=>{let{id:t,start:a,end:r,summary:s,hours:o,background:c}=e;return(0,n.jsxs)("li",{className:ep()(eD().listItem,{[eD().listItemLight]:"light"===c,[eD().listItemDark]:"dark"===c}),children:[l===I&&(0,n.jsx)("span",{className:eD().eventDate,title:"".concat(e_(v()(a),{day:"2-digit",month:"2-digit",year:"numeric"}),", ").concat(e_(v()(a),{minute:"2-digit",hour:"2-digit"})," - ").concat(e_(v()(r),{minute:"2-digit",hour:"2-digit"})),children:e_(v()(a),{day:"2-digit",month:"2-digit"})}),(0,n.jsx)("span",{className:eD().eventName,title:s,children:s}),(0,n.jsx)("button",{type:"button",className:eD().copyButton,onClick:()=>eC(s),"aria-label":"Copy",children:(0,n.jsxs)("svg",{className:eD().copyIcon,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,n.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})}),(0,n.jsx)("span",{className:eD().eventHours,children:"".concat(A(o),"h")})]},t)})}),(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:eD().sortByLabel,children:"Sort by:"}),(0,n.jsxs)("div",{className:ep()("btn-group","btn-group-sm"),role:"group",children:[(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"date",id:"date",checked:l===I,onChange:e=>{let{target:t}=e;return o(t.value)}}),(0,n.jsx)("label",{className:ep()("btn","btn-outline-secondary"),htmlFor:"date",children:"Date"}),(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"amount",id:"amount",checked:l===Y,onChange:e=>{let{target:t}=e;return o(t.value)}}),(0,n.jsx)("label",{className:ep()("btn","btn-outline-secondary"),htmlFor:"amount",children:"Amount"})]}),t&&(0,n.jsx)("a",{href:t,download:a,className:ep()(eD().downloadLink,"btn","btn-outline-secondary","btn-sm"),children:"Export as CSV"})]})]})},eY=a(5021),eM=a.n(eY),eA=()=>{let e=(0,s.I0)(),t=(0,s.v9)(K);return(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:eM().weekStartLabel,children:"Week starts on:"}),(0,n.jsxs)("div",{className:ep()("btn-group","btn-group-sm"),role:"group",children:[(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"sunday",id:"sunday",checked:t===M.SUNDAY,onChange:t=>{let{target:a}=t;return e(et(a.value))}}),(0,n.jsx)("label",{className:ep()("btn","btn-outline-secondary"),htmlFor:"sunday",children:"Sunday"}),(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"monday",id:"monday",checked:t===M.MONDAY,onChange:t=>{let{target:a}=t;return e(et(a.value))}}),(0,n.jsx)("label",{className:ep()("btn","btn-outline-secondary"),htmlFor:"monday",children:"Monday"})]})]})},eL=a(1507),eR=a.n(eL),eP=e=>{let{isEventsOpen:t,setIsEventsOpen:a}=e,r=(0,s.v9)(Q);return(0,n.jsx)("div",{children:(0,n.jsx)("button",{type:"button","data-testid":t?"HideEventsButton":"ShowEventsButton",className:ep()(eR().showDetailsButton,"btn","btn-outline-secondary","btn-sm"),onClick:()=>a(!t),children:t?"hide details of ".concat(r," events"):"show details of ".concat(r," events")})})},eJ=a(8348),eH=a.n(eJ),eB=()=>{let e=(0,s.I0)(),[t,a]=(0,r.useState)(!1),l=(0,s.v9)(ec);(0,r.useEffect)(()=>{l||e(eo())});let o=(0,s.v9)(U),c=(0,s.v9)(e=>D(e,o)),i=(0,s.v9)(k),d=(0,s.v9)(Z),u=(0,s.v9)(X);return(0,n.jsxs)("div",{className:eH().interface,children:[l?(0,n.jsx)(ed,{}):(0,n.jsx)("div",{children:"loading"}),i&&"loading",c&&(0,n.jsxs)(r.Fragment,{children:[(0,n.jsx)(eu,{}),d!==O.TOTAL&&d!==O.CUSTOM&&(0,n.jsx)(em,{}),d===O.CUSTOM&&(0,n.jsx)(eg,{}),(0,n.jsx)(ej,{}),d===O.WEEK&&(0,n.jsx)(eA,{}),d!==O.TOTAL&&(0,n.jsx)(ef,{}),!!u&&(0,n.jsx)(eP,{isEventsOpen:t,setIsEventsOpen:a}),!!u&&t&&(0,n.jsx)(eI,{})]})]})},eF=a(8130),eW=a.n(eF),eU=()=>{let e=(0,s.v9)(d),[t,a]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{var e,t,a;let n=(0,l.J)(null!==(a=null===(t=window.location)||void 0===t?void 0:null===(e=t.hash)||void 0===e?void 0:e.slice(1))&&void 0!==a?a:"");n.access_token&&(sessionStorage.setItem("accessToken",n.access_token),window.location="/")},[]),(0,r.useEffect)(()=>{a(!0)},[]),(0,n.jsx)("div",{className:eW().appWrapper,children:(0,n.jsx)("div",{className:eW().app,children:(0,n.jsxs)("div",{className:eW().sticky,children:[(0,n.jsxs)("div",{className:eW().content,children:[(0,n.jsx)("h1",{className:eW().headline,children:"Google Calendar Hours Calculator"}),(!t||!e)&&(0,n.jsx)(p,{}),t&&e&&(0,n.jsx)(eB,{})]}),(0,n.jsx)("footer",{className:eW().footer,children:(0,n.jsxs)("p",{children:[(0,n.jsx)("span",{children:"\xa9 2011 - 2024. This app is open source. "}),(0,n.jsx)("a",{href:"https://github.com/aronwoost/google-calendar-hours",target:"_blank",rel:"noreferrer",children:"Check it on GitHub"}),(0,n.jsx)("span",{children:"."})]})})]})})})},eG=a(7292),eZ=a.n(eG);v().extend(eZ());let eK=()=>{try{return sessionStorage.getItem("accessToken")}catch(e){}return null},eq=()=>{var e,t,a;let n=null!==(e=C())&&void 0!==e?e:{};return{selectedRangeType:null!==(t=n.selectedRangeType)&&void 0!==t?t:O.MONTH,currentDatePointerStart:n.selectedRangeType===O.CUSTOM?n.start:v()().startOf("day").toJSON(),currentDatePointerEnd:n.end,weekStart:null!==(a=n.weekStart)&&void 0!==a?a:M.MONDAY}};var ez=()=>(0,o.xC)({reducer:{authentication:u,calendars:ei,viewState:er,calendarEvents:T},preloadedState:{authentication:{accessToken:eK()},viewState:eq()}});function eV(){return(0,n.jsx)(s.zt,{store:ez(),children:(0,n.jsx)(eU,{})})}a(6278),a(3282)},3282:function(){},8130:function(e){e.exports={appWrapper:"App_appWrapper__4ujfq",app:"App_app___XJFW",sticky:"App_sticky__jFcSd",content:"App_content__N51C7",headline:"App_headline__q2cYV",footer:"App_footer__H44bm"}},8348:function(e){e.exports={interface:"Interface_interface__U3bJY"}},5304:function(e){e.exports={component:"CustomRange_component__JTYTq",inputDate:"CustomRange_inputDate__K4yXZ"}},1546:function(e){e.exports={list:"Events_list__2CQgB",listItem:"Events_listItem__tesqm",listItemDark:"Events_listItemDark__BJsyA",listItemLight:"Events_listItemLight__23Kx7",eventDate:"Events_eventDate__7peIM",eventName:"Events_eventName__HsZcZ",copyButton:"Events_copyButton__wTk3T",copyIcon:"Events_copyIcon__3N2B_",eventHours:"Events_eventHours__MqwGH",sortByLabel:"Events_sortByLabel__B3F3n",downloadLink:"Events_downloadLink__LW6Qr"}},6664:function(e){e.exports={hours:"Hours_hours__bZzAy"}},1507:function(e){e.exports={showDetailsButton:"ShowDetailsButton_showDetailsButton__cXVZk"}},5021:function(e){e.exports={weekStartLabel:"WeekStart_weekStartLabel__z4_jD"}}},function(e){e.O(0,[735,231,667,907,971,117,744],function(){return e(e.s=5554)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/_next/static/chunks/app/page-f61664260347a81b.js b/_next/static/chunks/app/page-f61664260347a81b.js deleted file mode 100644 index d6b5760..0000000 --- a/_next/static/chunks/app/page-f61664260347a81b.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{5554:function(e,t,a){Promise.resolve().then(a.bind(a,3423))},3423:function(e,t,a){"use strict";a.r(t),a.d(t,{default:function(){return eV}});var n=a(7437),r=a(2265),s=a(8575),o=a(2239),l=a(1455);let c=(0,l.oM)({name:"authentication",initialState:null,reducers:{}}),i=e=>e.authentication.accessToken,d=e=>!!i(e);var u=c.reducer;let h=()=>{let e=(0,o.c)({client_id:"502172359025.apps.googleusercontent.com",redirect_uri:"https://google-calendar-hours.com",scope:"https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.readonly",response_type:"token"});return"https://accounts.google.com/o/oauth2/auth?".concat(e)};var m=()=>(0,n.jsxs)(r.Fragment,{children:[(0,n.jsx)("p",{children:"This web app lets you see how many hours you spend on a Google Calendar. It uses the Google Calendar API to fetch your calendars and events, crunches the data and displays it nicely. You can filter by day, week, month, year, total or add a custom time range."}),(0,n.jsx)("p",{children:"You need to authorize the app with the following link:"}),(0,n.jsx)("a",{href:h(),"data-testid":"AuthLink",children:(0,n.jsx)("img",{src:"./google_auth.png",alt:"Auth with Google",width:"191",height:"46"})}),(0,n.jsx)("h3",{children:"Privacy Policy"}),(0,n.jsx)("p",{children:"This app connects to the Google Calendar API to fetch your calendars and events, so that it can calculate the hours. This connection happens directly from your browser to the Google API. There are no server or services involved that might cache the data."}),(0,n.jsx)("p",{children:"None of the data fetched from the Google Calendar API is saved elsewhere but in your browser. After you close the browser window/tab all authentication data is delete (technical detail: sessionStorage is used). Thats why you need to reauthorize with Google the next time you visit the page."}),(0,n.jsx)("p",{children:"This app only has read-only access to your calendar data."})]}),p=a(1096),v=a.n(p);let y="https://www.googleapis.com/calendar/v3/",g=async e=>{let{url:t,accessToken:a,params:n}=e,r=await fetch("".concat(t,"?").concat((0,o.c)({access_token:a,...n})));return 200!==r.status?(sessionStorage.removeItem("accessToken"),window.location="/",Promise.reject()):r.json()},x=e=>{let{accessToken:t}=e;return g({url:"".concat(y,"users/me/calendarList"),accessToken:t})},w=async e=>{let{accessToken:t,calendarId:a,pageToken:n,acc:r}=e,{items:s,nextPageToken:o}=await g({url:"".concat(y,"calendars/").concat(encodeURIComponent(a),"/events"),accessToken:t,params:{singleEvents:!0,maxResults:2500,pageToken:n,timeMax:v()().add(2,"year").toJSON()}});return o?w({accessToken:t,calendarId:a,pageToken:o,acc:[...r,...s]}):[...r,...s]},j=e=>{let{accessToken:t,calendarId:a}=e;return w({accessToken:t,calendarId:a,acc:[]})};var _=a(2713);a(774);let f=(0,l.oM)({name:"calendarEvents",initialState:{loading:!1,map:{}},reducers:{setCalendarEvents:(e,t)=>{let{payload:a}=t;e.map[a.calendarId]=a.events},setLoading:(e,t)=>{let{payload:a}=t;e.loading=a}}}),{setCalendarEvents:S,setLoading:b}=f.actions,N=e=>{let{calendarId:t}=e;return async(e,a)=>{let n=i(a());try{e(b(!0));let a=await j({accessToken:n,calendarId:t});e(S({calendarId:t,events:a.map(e=>{let{id:t,summary:a,start:n,end:r}=e;return n.dateTime?{id:t,summary:a,start:n.dateTime,end:r.dateTime}:null}).filter(Boolean)}))}catch(e){}finally{e(b(!1))}}},k=e=>{var t,a;return null!==(a=null===(t=e.calendarEvents)||void 0===t?void 0:t.loading)&&void 0!==a&&a},D=(e,t)=>{var a,n;return null!==(n=!k(e)&&(null===(a=e.calendarEvents)||void 0===a?void 0:a.map[t]))&&void 0!==n?n:null};var T=f.reducer;let E=e=>{let t;try{t=JSON.parse(window.localStorage.getItem("config"))}catch(e){}let a={...t,...e};window.localStorage.setItem("config",JSON.stringify(a))},C=()=>{try{return JSON.parse(window.localStorage.getItem("config"))}catch(e){}return null},O={DAY:"day",WEEK:"week",MONTH:"month",YEAR:"year",TOTAL:"total",CUSTOM:"custom"},I="date",Y="amount",M={MONDAY:"monday",SUNDAY:"sunday"};var A=e=>Math.round(100*e)/100;let L=(0,l.oM)({name:"viewState",initialState:null,reducers:{setSelectedCalendarId:(e,t)=>{let{payload:a}=t;e.selectedCalendarId=a},setRangeType:(e,t)=>{let{payload:a}=t;e.selectedRangeType=a},changeRange:(e,t)=>{let{payload:a}=t;"prev"===a?e.currentDatePointerStart=v()(e.currentDatePointerStart).subtract(1,e.selectedRangeType).toJSON():"next"===a&&(e.currentDatePointerStart=v()(e.currentDatePointerStart).add(1,e.selectedRangeType).toJSON())},resetRange:e=>{e.currentDatePointerStart=v()().startOf("day").toJSON()},setWeekStart:(e,t)=>{let{payload:a}=t;e.weekStart=a},setStart:(e,t)=>{let{payload:a}=t;e.currentDatePointerStart=a},setEnd:(e,t)=>{let{payload:a}=t;e.currentDatePointerEnd=a}}}),{changeRange:R,resetRange:P}=L.actions,{setSelectedCalendarId:J,setRangeType:H,setWeekStart:B,setStart:F,setEnd:W}=L.actions,U=e=>e.viewState.selectedCalendarId,G=e=>e.viewState.currentDatePointerStart,Z=e=>e.viewState.selectedRangeType,K=e=>e.viewState.weekStart,q=e=>e.viewState.weekStart===M.SUNDAY?"en":"de",z=(0,_.P1)([e=>e],e=>{let t,a;let{selectedRangeType:n,currentDatePointerStart:r,currentDatePointerEnd:s}=e.viewState,o=v()(r);return n===O.CUSTOM?{start:v()(r),end:v()(s).add(1,"day")}:(n===O.DAY?a=(t=o.startOf("day")).add(1,"day"):n===O.WEEK?a=(t=o.locale(q(e)).startOf("day").weekday(0)).add(1,"week"):n===O.MONTH?a=(t=o.startOf("month")).add(1,"month"):n===O.YEAR?a=(t=o.startOf("year")).add(1,"year"):n===O.TOTAL&&(t=v()("2000-01-01T10:00:00Z"),a=v()("2040-01-01T10:00:00Z")),{start:t,end:a})}),V=(0,_.P1)([e=>e],e=>{let t=D(e,U(e));if(!t)return null;let{start:a,end:n}=z(e);return t.filter(e=>{let{start:t,end:r}=e;return!(new Date(r)n)}).map(e=>{let{start:t,end:r,...s}=e;return{...s,start:new Date(t)n?n.toJSON():r}})}),X=e=>{let t=V(e);if(!t)return null;let a=0;return t.forEach(e=>{let{start:t,end:n}=e;a+=(new Date(n)-new Date(t))/1e3/60/60}),A(a)},Q=e=>{var t;return(null===(t=V(e))||void 0===t?void 0:t.length)||0},$=e=>{let{calendarId:t}=e;return(e,a)=>{e(J(t)),E({selectedCalendarId:t}),D(a(),t)||e(N({calendarId:t}))}},ee=e=>{let{range:t}=e;return(e,a)=>{if(t===O.CUSTOM){let{start:t,end:n}=z(a()),r=n.subtract(1,"day");e(F(t.toJSON())),e(W(r.toJSON())),E({start:t.toJSON(),end:r.toJSON()})}e(H(t)),E({selectedRangeType:t})}},et=e=>t=>{t(B(e)),E({weekStart:e})},ea=e=>t=>{t(F(e)),E({start:e})},en=e=>t=>{t(W(e)),E({end:e})};var er=L.reducer;let es=(0,l.oM)({name:"calendars",initialState:{list:null},reducers:{setCalendars:(e,t)=>{let{payload:a}=t;e.list=a}}}),{setCalendars:eo}=es.actions,el=()=>async(e,t)=>{let a=i(t());try{var n;let{items:t}=await x({accessToken:a}),r=t.map(e=>{let{id:t,summary:a}=e;return{id:t,label:a}});e(eo(r));let{selectedCalendarId:s}=null!==(n=C())&&void 0!==n?n:{};if(s){let t=null==r?void 0:r.find(e=>{let{id:t}=e;return t===s});e(t?$({calendarId:s}):$({calendarId:null}))}}catch(e){}},ec=e=>e.calendars.list;var ei=es.reducer,ed=()=>{let e=(0,s.I0)(),t=(0,s.v9)(ec),a=(0,s.v9)(U);return(0,n.jsxs)("select",{"data-testid":"CalendarsList",className:"form-select",onChange:t=>{e($({calendarId:t.target.value}))},value:null!=a?a:"",children:[!a&&(0,n.jsx)("option",{children:"Please select calendar"},"default"),t.map(e=>{let{id:t,label:a}=e;return(0,n.jsx)("option",{value:t,children:a},t)})]})},eu=()=>{let e=(0,s.I0)(),t=(0,s.v9)(Z);return(0,n.jsxs)("select",{"data-testid":"RangeSelectList",className:"form-select",onChange:t=>e(ee({range:t.target.value})),value:t,children:[(0,n.jsx)("option",{value:"day",children:"Day"}),(0,n.jsx)("option",{value:"week",children:"Week"}),(0,n.jsx)("option",{value:"month",children:"Month"}),(0,n.jsx)("option",{value:"year",children:"Year"}),(0,n.jsx)("option",{value:"total",children:"Total"}),(0,n.jsx)("option",{value:"custom",children:"Custom"})]})},eh=a(6760),em=a.n(eh),ep=()=>{let e=(0,s.I0)();return(0,n.jsxs)("div",{"data-testid":"RangeChanger",className:"btn-group",role:"group",children:[(0,n.jsx)("button",{type:"button",className:em()("btn","btn-outline-secondary"),onClick:()=>e(R("prev")),children:"Prev"}),(0,n.jsx)("button",{type:"button",className:em()("btn","btn-outline-secondary"),onClick:()=>e(P()),children:"Reset"}),(0,n.jsx)("button",{type:"button",className:em()("btn","btn-outline-secondary"),onClick:()=>e(R("next")),children:"Next"})]})},ev=a(5304),ey=a.n(ev),eg=()=>{let e=(0,s.I0)(),{start:t,end:a}=(0,s.v9)(z);return(0,n.jsxs)("div",{className:em()(ey().component,"input-group","input-group-sm"),"data-testid":"CustomRange",children:[(0,n.jsx)("label",{htmlFor:"dateStart",className:"input-group-text",children:"Start:"}),(0,n.jsx)("input",{className:em()("form-control",ey().inputDate),type:"date",id:"dateStart",value:v()(t).format("YYYY-MM-DD"),onChange:t=>{let{target:a}=t;return e(ea(v()(a.value).toJSON()))}}),(0,n.jsx)("label",{htmlFor:"dateEnd",className:"input-group-text",children:"End:"}),(0,n.jsx)("input",{className:em()("form-control",ey().inputDate),type:"date",id:"dateEnd",value:v()(a).subtract(1,"day").format("YYYY-MM-DD"),onChange:t=>{let{target:a}=t;return e(en(v()(a.value).toJSON()))}})]})},ex=a(6664),ew=a.n(ex),ej=()=>(0,n.jsx)("div",{className:ew().hours,children:"".concat((0,s.v9)(X),"h")}),e_=(e,t)=>new Intl.DateTimeFormat([navigator.language,"en-US"],t).format(e),ef=()=>{let e;let t=(0,s.v9)(G),a=(0,s.v9)(Z),r=(0,s.v9)(q),o=v()(t);if(a===O.DAY)e=e_(v()(o),{weekday:"long",day:"numeric",month:"long",year:"numeric"});else if(a===O.WEEK){let t=o.locale(r).weekday(0),a=e_(t,{day:"numeric",month:"numeric",year:"numeric"}),n=e_(t.add(1,"week").subtract(1,"day"),{day:"numeric",month:"numeric",year:"numeric"});e="".concat(a," - ").concat(n)}else a===O.MONTH?e=e_(o,{month:"long",year:"numeric"}):a===O.YEAR&&(e=e_(o,{year:"numeric"}));return(0,n.jsx)("div",{"data-testid":"RangeDisplay",children:e})},eS=a(5524),eb=a.n(eS),eN=e=>{let t=new Blob(["\uFEFF"+e],{type:"text/csv;charset=UTF-8"});return window.URL.createObjectURL(t)},ek=a(1546),eD=a.n(ek);v().extend(eb());let eT=(e,t)=>{let{hours:a}=e,{hours:n}=t;return a>n?-1:a{let{start:a}=e,{start:n}=t;return an?1:0},eC=async e=>{try{await navigator.clipboard.writeText(e)}catch(e){}},eO=e=>v()(e).format("DD.MM.YYYY HH:mm");var eI=()=>{var e;let t,a;let[o,l]=(0,r.useState)(I),c=(0,s.v9)(U),i=(0,s.v9)(V),d=(0,s.v9)(ec),u=(0,s.v9)(G),h=null===(e=d.find(e=>e.id===c))||void 0===e?void 0:e.label,m="dark",p=i.sort(eE).map((e,t,a)=>{var n,r;return v()(e.start).isoWeek()!==((null==a?void 0:null===(n=a[t-1])||void 0===n?void 0:n.start)&&v()(null==a?void 0:null===(r=a[t-1])||void 0===r?void 0:r.start).isoWeek())&&(m="dark"===m?"light":"dark"),{...e,hours:(new Date(e.end)-new Date(e.start))/1e3/60/60,background:m}});return o===Y?p=Object.entries(p.reduce((e,t)=>{let{summary:a,hours:n}=t;return e[a]=e[a]?e[a]+=n:n,e},{})).map(e=>{let[t,a]=e;return{summary:t,hours:a,id:t}}).sort(eT):(t=eN(["Start,End,Title,Hours"].concat(p.map(e=>{let{start:t,end:a,summary:n,hours:r}=e;return"".concat(eO(t),",").concat(eO(a),',"').concat(n,'",').concat(A(r))})).join("\n")),a="".concat(h,"_").concat(v()(u).locale("en").format("MMMM_YYYY"),"_(").concat(v()().format("YYYYMMDDHHmmss"),").csv")),(0,n.jsxs)("div",{children:[(0,n.jsx)("ul",{className:eD().list,children:p.map(e=>{let{id:t,start:a,end:r,summary:s,hours:l,background:c}=e;return(0,n.jsxs)("li",{className:em()("row",eD().listItem,{[eD().listItemLight]:"light"===c,[eD().listItemDark]:"dark"===c}),children:[o===I&&(0,n.jsx)("span",{className:em()("col-sm",eD().eventDate),title:"".concat(e_(v()(a),{day:"2-digit",month:"2-digit",year:"numeric"}),", ").concat(e_(v()(a),{minute:"2-digit",hour:"2-digit"})," - ").concat(e_(v()(r),{minute:"2-digit",hour:"2-digit"})),children:e_(v()(a),{day:"2-digit",month:"2-digit"})}),(0,n.jsx)("span",{className:em()("col-sm",eD().eventName),title:s,children:s}),(0,n.jsx)("button",{type:"button",className:eD().copyButton,onClick:()=>eC(s),"aria-label":"Copy",children:(0,n.jsxs)("svg",{className:eD().copyIcon,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,n.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,n.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})}),(0,n.jsx)("span",{className:em()("col-sm",eD().eventHours),children:"".concat(A(l),"h")})]},t)})}),(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:eD().sortByLabel,children:"Sort by:"}),(0,n.jsxs)("div",{className:em()("btn-group","btn-group-sm"),role:"group",children:[(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"date",id:"date",checked:o===I,onChange:e=>{let{target:t}=e;return l(t.value)}}),(0,n.jsx)("label",{className:em()("btn","btn-outline-secondary"),htmlFor:"date",children:"Date"}),(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"amount",id:"amount",checked:o===Y,onChange:e=>{let{target:t}=e;return l(t.value)}}),(0,n.jsx)("label",{className:em()("btn","btn-outline-secondary"),htmlFor:"amount",children:"Amount"})]}),t&&(0,n.jsx)("a",{href:t,download:a,className:em()(eD().downloadLink,"btn","btn-outline-secondary","btn-sm"),children:"Export as CSV"})]})]})},eY=a(5021),eM=a.n(eY),eA=()=>{let e=(0,s.I0)(),t=(0,s.v9)(K);return(0,n.jsxs)("div",{children:[(0,n.jsx)("span",{className:eM().weekStartLabel,children:"Week starts on:"}),(0,n.jsxs)("div",{className:em()("btn-group","btn-group-sm"),role:"group",children:[(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"sunday",id:"sunday",checked:t===M.SUNDAY,onChange:t=>{let{target:a}=t;return e(et(a.value))}}),(0,n.jsx)("label",{className:em()("btn","btn-outline-secondary"),htmlFor:"sunday",children:"Sunday"}),(0,n.jsx)("input",{className:"btn-check",type:"radio",value:"monday",id:"monday",checked:t===M.MONDAY,onChange:t=>{let{target:a}=t;return e(et(a.value))}}),(0,n.jsx)("label",{className:em()("btn","btn-outline-secondary"),htmlFor:"monday",children:"Monday"})]})]})},eL=a(1507),eR=a.n(eL),eP=e=>{let{isEventsOpen:t,setIsEventsOpen:a}=e,r=(0,s.v9)(Q);return(0,n.jsx)("div",{children:(0,n.jsx)("button",{type:"button","data-testid":t?"HideEventsButton":"ShowEventsButton",className:em()(eR().showDetailsButton,"btn","btn-outline-secondary","btn-sm"),onClick:()=>a(!t),children:t?"hide details of ".concat(r," events"):"show details of ".concat(r," events")})})},eJ=a(8348),eH=a.n(eJ),eB=()=>{let e=(0,s.I0)(),[t,a]=(0,r.useState)(!1),o=(0,s.v9)(ec);(0,r.useEffect)(()=>{o||e(el())});let l=(0,s.v9)(U),c=(0,s.v9)(e=>D(e,l)),i=(0,s.v9)(k),d=(0,s.v9)(Z),u=(0,s.v9)(X);return(0,n.jsxs)("div",{className:eH().interface,children:[o?(0,n.jsx)(ed,{}):(0,n.jsx)("div",{children:"loading"}),i&&"loading",c&&(0,n.jsxs)(r.Fragment,{children:[(0,n.jsx)(eu,{}),d!==O.TOTAL&&d!==O.CUSTOM&&(0,n.jsx)(ep,{}),d===O.CUSTOM&&(0,n.jsx)(eg,{}),(0,n.jsx)(ej,{}),d===O.WEEK&&(0,n.jsx)(eA,{}),d!==O.TOTAL&&(0,n.jsx)(ef,{}),!!u&&(0,n.jsx)(eP,{isEventsOpen:t,setIsEventsOpen:a}),!!u&&t&&(0,n.jsx)(eI,{})]})]})},eF=a(8130),eW=a.n(eF),eU=()=>{let e=(0,s.v9)(d),[t,a]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{var e,t,a;let n=(0,o.J)(null!==(a=null===(t=window.location)||void 0===t?void 0:null===(e=t.hash)||void 0===e?void 0:e.slice(1))&&void 0!==a?a:"");n.access_token&&(sessionStorage.setItem("accessToken",n.access_token),window.location="/")},[]),(0,r.useEffect)(()=>{a(!0)},[]),(0,n.jsx)("div",{className:eW().appWrapper,children:(0,n.jsx)("div",{className:eW().app,children:(0,n.jsxs)("div",{className:eW().sticky,children:[(0,n.jsxs)("div",{className:eW().content,children:[(0,n.jsx)("h1",{className:eW().headline,children:"Google Calendar Hours Calculator"}),(!t||!e)&&(0,n.jsx)(m,{}),t&&e&&(0,n.jsx)(eB,{})]}),(0,n.jsx)("footer",{className:eW().footer,children:(0,n.jsxs)("p",{children:[(0,n.jsx)("span",{children:"\xa9 2011 - 2024. This app is open source. "}),(0,n.jsx)("a",{href:"https://github.com/aronwoost/google-calendar-hours",target:"_blank",rel:"noreferrer",children:"Check it on GitHub"}),(0,n.jsx)("span",{children:"."})]})})]})})})},eG=a(7292),eZ=a.n(eG);v().extend(eZ());let eK=()=>{try{return sessionStorage.getItem("accessToken")}catch(e){}return null},eq=()=>{var e,t,a;let n=null!==(e=C())&&void 0!==e?e:{};return{selectedRangeType:null!==(t=n.selectedRangeType)&&void 0!==t?t:O.MONTH,currentDatePointerStart:n.selectedRangeType===O.CUSTOM?n.start:v()().startOf("day").toJSON(),currentDatePointerEnd:n.end,weekStart:null!==(a=n.weekStart)&&void 0!==a?a:M.MONDAY}};var ez=()=>(0,l.xC)({reducer:{authentication:u,calendars:ei,viewState:er,calendarEvents:T},preloadedState:{authentication:{accessToken:eK()},viewState:eq()}});function eV(){return(0,n.jsx)(s.zt,{store:ez(),children:(0,n.jsx)(eU,{})})}a(6278),a(3282)},3282:function(){},8130:function(e){e.exports={appWrapper:"App_appWrapper__4ujfq",app:"App_app___XJFW",sticky:"App_sticky__jFcSd",content:"App_content__N51C7",headline:"App_headline__q2cYV",footer:"App_footer__H44bm"}},8348:function(e){e.exports={interface:"Interface_interface__U3bJY"}},5304:function(e){e.exports={component:"CustomRange_component__JTYTq",inputDate:"CustomRange_inputDate__K4yXZ"}},1546:function(e){e.exports={list:"Events_list__2CQgB",listItem:"Events_listItem__tesqm",listItemDark:"Events_listItemDark__BJsyA",listItemLight:"Events_listItemLight__23Kx7",eventDate:"Events_eventDate__7peIM",eventName:"Events_eventName__HsZcZ",copyButton:"Events_copyButton__wTk3T",copyIcon:"Events_copyIcon__3N2B_",eventHours:"Events_eventHours__MqwGH",sortByLabel:"Events_sortByLabel__B3F3n",downloadLink:"Events_downloadLink__LW6Qr"}},6664:function(e){e.exports={hours:"Hours_hours__bZzAy"}},1507:function(e){e.exports={showDetailsButton:"ShowDetailsButton_showDetailsButton__cXVZk"}},5021:function(e){e.exports={weekStartLabel:"WeekStart_weekStartLabel__z4_jD"}}},function(e){e.O(0,[735,231,667,907,971,117,744],function(){return e(e.s=5554)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/_next/static/css/06c17f67d215aa32.css b/_next/static/css/06c17f67d215aa32.css new file mode 100644 index 0000000..fca96ac --- /dev/null +++ b/_next/static/css/06c17f67d215aa32.css @@ -0,0 +1 @@ +.CustomRange_component__JTYTq{text-align:left}.CustomRange_inputDate__K4yXZ::-webkit-calendar-picker-indicator{position:absolute;top:0;right:0;bottom:0;left:0;width:auto;height:auto;background:transparent;color:transparent;cursor:pointer}.Hours_hours__bZzAy{color:grey;font-size:64px;font-weight:700;line-height:normal;text-align:center}.Events_list__2CQgB{padding:0;margin-top:12px;margin-left:0}.Events_listItem__tesqm{display:flex;gap:6px;padding:0 2px;margin:0}.Events_listItemDark__BJsyA{background-color:#eee}.Events_listItemLight__23Kx7{background-color:#fff}.Events_eventDate__7peIM{flex:1 0;padding-right:0;font-feature-settings:tabular-nums lining-nums;font-variant-numeric:tabular-nums lining-nums}.Events_eventName__HsZcZ{overflow:hidden;width:0;flex:1 0;flex-grow:1000;padding-right:0;text-align:left;text-overflow:ellipsis;white-space:nowrap;word-break:unset}.Events_copyButton__wTk3T{all:unset;color:grey;width:15px}.Events_copyButton__wTk3T:active svg{box-shadow:0 0 5px #51cbee}.Events_copyIcon__3N2B_{width:16px;height:16px}.Events_eventHours__MqwGH{flex:1 0}.Events_sortByLabel__B3F3n{margin-right:8px}.Events_downloadLink__LW6Qr{margin-left:8px}.WeekStart_weekStartLabel__z4_jD{margin-right:8px}.ShowDetailsButton_showDetailsButton__cXVZk{width:100%}.Interface_interface__U3bJY>*{width:100%;margin-bottom:8px}.App_appWrapper__4ujfq{display:flex;width:100%;height:100%;justify-content:center}.App_app___XJFW{width:380px;margin:8px 8px 0}.App_app___XJFW h3{padding-top:20px;color:grey;font-size:18px;font-weight:700}.App_sticky__jFcSd{display:flex;height:100%;flex-direction:column}.App_content__N51C7{flex:1 0 auto}.App_headline__q2cYV{color:grey;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:30px;font-weight:700;line-height:36px;text-rendering:optimizelegibility}.App_footer__H44bm{padding-bottom:8px}.App_footer__H44bm p{margin-bottom:0} \ No newline at end of file diff --git a/_next/static/css/fbd5526d4d827033.css b/_next/static/css/fbd5526d4d827033.css deleted file mode 100644 index 66c65f1..0000000 --- a/_next/static/css/fbd5526d4d827033.css +++ /dev/null @@ -1 +0,0 @@ -.CustomRange_component__JTYTq{text-align:left}.CustomRange_inputDate__K4yXZ::-webkit-calendar-picker-indicator{position:absolute;top:0;right:0;bottom:0;left:0;width:auto;height:auto;background:transparent;color:transparent;cursor:pointer}.Hours_hours__bZzAy{color:grey;font-size:64px;font-weight:700;line-height:normal;text-align:center}.Events_list__2CQgB{padding:0;margin-top:12px;margin-left:0}.Events_listItem__tesqm{padding:0 2px;margin:0}.Events_listItemDark__BJsyA{background-color:#eee}.Events_listItemLight__23Kx7{background-color:#fff}.Events_listItem__tesqm>:first-child{padding-left:0}.Events_listItem__tesqm>:last-child{padding-right:0}.Events_eventDate__7peIM{flex:1 0;padding-right:0;font-feature-settings:tabular-nums lining-nums;font-variant-numeric:tabular-nums lining-nums}.Events_eventName__HsZcZ{overflow:hidden;width:0;flex:1 0;flex-grow:1000;padding-right:0;text-align:left;text-overflow:ellipsis;white-space:nowrap;word-break:unset}.Events_copyButton__wTk3T{all:unset;padding-left:8px;color:grey}.Events_copyButton__wTk3T:active svg{box-shadow:0 0 5px #51cbee}.Events_copyIcon__3N2B_{width:16px;height:16px}.Events_eventHours__MqwGH{flex:1 0;padding-left:8px}.Events_sortByLabel__B3F3n{margin-right:8px}.Events_downloadLink__LW6Qr{margin-left:8px}.WeekStart_weekStartLabel__z4_jD{margin-right:8px}.ShowDetailsButton_showDetailsButton__cXVZk{width:100%}.Interface_interface__U3bJY>*{width:100%;margin-bottom:8px}.App_appWrapper__4ujfq{display:flex;width:100%;height:100%;justify-content:center}.App_app___XJFW{width:380px;margin:8px 8px 0}.App_app___XJFW h3{padding-top:20px;color:grey;font-size:18px;font-weight:700}.App_sticky__jFcSd{display:flex;height:100%;flex-direction:column}.App_content__N51C7{flex:1 0 auto}.App_headline__q2cYV{color:grey;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:30px;font-weight:700;line-height:36px;text-rendering:optimizelegibility}.App_footer__H44bm{padding-bottom:8px}.App_footer__H44bm p{margin-bottom:0} \ No newline at end of file diff --git a/_next/static/nAWyEkGb1sc3C9ZSnsRtI/_buildManifest.js b/_next/static/d8pRbfMMUIWywRCL2v036/_buildManifest.js similarity index 100% rename from _next/static/nAWyEkGb1sc3C9ZSnsRtI/_buildManifest.js rename to _next/static/d8pRbfMMUIWywRCL2v036/_buildManifest.js diff --git a/_next/static/nAWyEkGb1sc3C9ZSnsRtI/_ssgManifest.js b/_next/static/d8pRbfMMUIWywRCL2v036/_ssgManifest.js similarity index 100% rename from _next/static/nAWyEkGb1sc3C9ZSnsRtI/_ssgManifest.js rename to _next/static/d8pRbfMMUIWywRCL2v036/_ssgManifest.js diff --git a/index.html b/index.html index 6976a04..3d7da67 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Google Calendar Hours

Google Calendar Hours Calculator

This web app lets you see how many hours you spend on a Google Calendar. It uses the Google Calendar API to fetch your calendars and events, crunches the data and displays it nicely. You can filter by day, week, month, year, total or add a custom time range.

You need to authorize the app with the following link:

Auth with Google

Privacy Policy

This app connects to the Google Calendar API to fetch your calendars and events, so that it can calculate the hours. This connection happens directly from your browser to the Google API. There are no server or services involved that might cache the data.

None of the data fetched from the Google Calendar API is saved elsewhere but in your browser. After you close the browser window/tab all authentication data is delete (technical detail: sessionStorage is used). Thats why you need to reauthorize with Google the next time you visit the page.

This app only has read-only access to your calendar data.

\ No newline at end of file +Google Calendar Hours

Google Calendar Hours Calculator

This web app lets you see how many hours you spend on a Google Calendar. It uses the Google Calendar API to fetch your calendars and events, crunches the data and displays it nicely. You can filter by day, week, month, year, total or add a custom time range.

You need to authorize the app with the following link:

Auth with Google

Privacy Policy

This app connects to the Google Calendar API to fetch your calendars and events, so that it can calculate the hours. This connection happens directly from your browser to the Google API. There are no server or services involved that might cache the data.

None of the data fetched from the Google Calendar API is saved elsewhere but in your browser. After you close the browser window/tab all authentication data is delete (technical detail: sessionStorage is used). Thats why you need to reauthorize with Google the next time you visit the page.

This app only has read-only access to your calendar data.

\ No newline at end of file diff --git a/index.txt b/index.txt index da48415..1261af0 100644 --- a/index.txt +++ b/index.txt @@ -1,8 +1,8 @@ 2:I[9107,[],"ClientPageRoot"] -3:I[3423,["907","static/chunks/907-9ace4ef683b7ced7.js","931","static/chunks/app/page-f61664260347a81b.js"],"default",1] +3:I[3423,["907","static/chunks/907-9ace4ef683b7ced7.js","931","static/chunks/app/page-f4f367308259435b.js"],"default",1] 4:I[4707,[],""] 5:I[6423,[],""] 6:I[8003,["185","static/chunks/app/layout-61d3f2da8b6dd07e.js"],""] -0:["nAWyEkGb1sc3C9ZSnsRtI",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/fbd5526d4d827033.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/cc6cbf47a7d40733.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","2",{"rel":"stylesheet","href":"/_next/static/css/efe305ad5ecc6b1a.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":[["$","meta",null,{"property":"version","content":"9e2f3e9"}],["$","body",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}],["$","$L6",null,{"src":"https://www.googletagmanager.com/gtag/js?id=G-4BZFZ94R2D"}],["$","$L6",null,{"children":"\n window.dataLayer = window.dataLayer || [];\n function gtag() {\n dataLayer.push(arguments);\n }\n gtag('js', new Date());\n \n gtag('config', 'G-4BZFZ94R2D');\n "}],["$","$L6",null,{"children":"\n var _gaq = [\n ['_setAccount', 'UA-344954-14'],\n ['_trackPageview'],\n ['_trackPageLoadTime'],\n ];\n (function (d, t) {\n var g = d.createElement(t),\n s = d.getElementsByTagName(t)[0];\n g.src =\n ('https:' == location.protocol ? '//ssl' : '//www') +\n '.google-analytics.com/ga.js';\n s.parentNode.insertBefore(g, s);\n })(document, 'script');\n "}],["$","$L6",null,{"src":"https://js.sentry-cdn.com/72dc5f435c6c4bf8a7c455a11ad94e89.min.js","crossOrigin":"anonymous"}]]}]],null],null],["$L7",null]]]] +0:["d8pRbfMMUIWywRCL2v036",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/06c17f67d215aa32.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/cc6cbf47a7d40733.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","2",{"rel":"stylesheet","href":"/_next/static/css/efe305ad5ecc6b1a.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":[["$","meta",null,{"property":"version","content":"3af8569"}],["$","body",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}],["$","$L6",null,{"src":"https://www.googletagmanager.com/gtag/js?id=G-4BZFZ94R2D"}],["$","$L6",null,{"children":"\n window.dataLayer = window.dataLayer || [];\n function gtag() {\n dataLayer.push(arguments);\n }\n gtag('js', new Date());\n \n gtag('config', 'G-4BZFZ94R2D');\n "}],["$","$L6",null,{"children":"\n var _gaq = [\n ['_setAccount', 'UA-344954-14'],\n ['_trackPageview'],\n ['_trackPageLoadTime'],\n ];\n (function (d, t) {\n var g = d.createElement(t),\n s = d.getElementsByTagName(t)[0];\n g.src =\n ('https:' == location.protocol ? '//ssl' : '//www') +\n '.google-analytics.com/ga.js';\n s.parentNode.insertBefore(g, s);\n })(document, 'script');\n "}],["$","$L6",null,{"src":"https://js.sentry-cdn.com/72dc5f435c6c4bf8a7c455a11ad94e89.min.js","crossOrigin":"anonymous"}]]}]],null],null],["$L7",null]]]] 7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Google Calendar Hours"}]] 1:null