A dead simple time tracker that keeps everything in local storage. Next.js, no accounts and no server.
handcodedlocalstoragenextjsreactself-hostedserverlesstime-trackingtimer
1import React, { useEffect } from "react";
2import { TransitionGroup, CSSTransition } from "react-transition-group";
3import { ToastContainer } from "react-toastify";
4import "react-toastify/dist/ReactToastify.css";
5
6import { ContextProvider } from "../components/context";
7
8import HotKeysMapping from "../components/HotKeysMapping";
9import Sidebar from "../components/sidebar";
10
11import "../styles/globals.css";
12
13const MyApp = ({ Component, pageProps, router }) => {
14 const pageNodeRef = React.useMemo(() => React.createRef(), [router.route]);
15
16 // Clean up any stale service worker registered by the old Workbox sw.js
17 // that used to ship with this project. Without this, browsers that
18 // visited an earlier version keep a dead SW cached and log filesystem
19 // / precache errors on every load.
20 useEffect(() => {
21 if (typeof window === "undefined" || !("serviceWorker" in navigator))
22 return;
23 navigator.serviceWorker
24 .getRegistrations()
25 .then((regs) => regs.forEach((r) => r.unregister()))
26 .catch(() => {});
27 if (window.caches && caches.keys) {
28 caches.keys().then((keys) => keys.forEach((k) => caches.delete(k))).catch(() => {});
29 }
30 }, []);
31
32 return (
33 <ContextProvider>
34 <HotKeysMapping>
35 <ToastContainer position="top-right" />
36 <TransitionGroup component={null}>
37 <CSSTransition
38 key={router.route}
39 appear
40 timeout={{
41 appear: 500,
42 enter: 500,
43 exit: 250,
44 }}
45 classNames="page-transition"
46 nodeRef={pageNodeRef}
47 >
48 <div className="page-transition" ref={pageNodeRef}>
49 <Component {...pageProps} />
50 </div>
51 </CSSTransition>
52 </TransitionGroup>
53 <Sidebar />
54 </HotKeysMapping>
55 </ContextProvider>
56 );
57};
58
59export default MyApp;