A dead simple time tracker that keeps everything in local storage. Next.js, no accounts and no server.
handcodedlocalstoragenextjsreactself-hostedserverlesstime-trackingtimer
1import React, { useContext } from "react";
2
3import Page from "../components/page";
4import L10n from "../components/l10n";
5import { Context } from "../components/context";
6import strings from "../l10n/about";
7
8import styles from "../styles/pages/about.module.css";
9
10const About = () => {
11 const { state } = useContext(Context);
12 strings.setLanguage(state.language);
13
14 return (
15 <Page title="About">
16 <a
17 className={styles.githubLink}
18 href="https://github.com/overshard/timelite"
19 target="_blank"
20 rel="noopener noreferrer"
21 aria-label="GitHub"
22 >
23 <div className={styles.githubLogo}>
24 <svg
25 xmlns="http://www.w3.org/2000/svg"
26 width="32"
27 height="32"
28 fill="currentColor"
29 viewBox="0 0 16 16"
30 >
31 <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z" />
32 </svg>
33 </div>
34 </a>
35 <div className="page-grid">
36 <main className="page-main">
37 <h1 className="page-title">{strings.title}</h1>
38 <blockquote className={styles.blockquote}>
39 {strings.quote}
40 </blockquote>
41 <a
42 className={styles.creator}
43 href="https://www.isaacbythewood.com/"
44 target="_blank"
45 rel="noopener noreferrer"
46 >
47 {strings.name}
48 </a>
49 <div className={styles.descriptionContainer}>
50 <div className={styles.keysColumn}>
51 <h2 className="section-label">{strings.sectionTimer}</h2>
52 <div className={styles.keysDescription}>
53 <span>⎇+r</span> {strings.keyReset}
54 </div>
55 <div className={styles.keysDescription}>
56 <span>⎇+a</span> {strings.keyAddLog}
57 </div>
58 <div className={styles.keysDescription}>
59 <span>⎇+p</span> {strings.keyPauseToggle}
60 </div>
61 <h2 className="section-label">{strings.sectionNavigation}</h2>
62 <div className={styles.keysDescription}>
63 <span>⎇+t</span> {strings.keyTimerPage}
64 </div>
65 <div className={styles.keysDescription}>
66 <span>⎇+l</span> {strings.keyLogPage}
67 </div>
68 <div className={styles.keysDescription}>
69 <span>⎇+s</span> {strings.keySummaryPage}
70 </div>
71 <div className={styles.keysDescription}>
72 <span>⎇+o</span> {strings.keyAboutPage}
73 </div>
74 </div>
75 <div className={styles.keysColumn}>
76 <h2 className="section-label">{strings.sectionLog}</h2>
77 <div className={styles.keysDescription}>
78 <span>↓</span> {strings.keyNextLogEntry}
79 </div>
80 <div className={styles.keysDescription}>
81 <span>↑</span> {strings.keyPreviousLogEntry}
82 </div>
83 <div className={styles.keysDescription}>
84 <span>⎇+e</span> {strings.keyEditEntry}
85 </div>
86 <div className={styles.keysDescription}>
87 <span>⎇+d</span> {strings.keyDeleteSingleEntry}
88 </div>
89 <div className={styles.keysDescription}>
90 <span>⎇+c</span> {strings.keyClearLog}
91 </div>
92 <div className={styles.keysDescription}>
93 <span>?</span> {strings.keyHelp}
94 </div>
95 </div>
96 </div>
97
98 <h2 className="section-label">{strings.sectionLanguage}</h2>
99 <div className={styles.languageRow}>
100 <L10n />
101 </div>
102 </main>
103 </div>
104 </Page>
105 );
106};
107
108export default About;