modified
components/HotKeysMapping.js
@@ -21,6 +21,7 @@ const keyMap = { TIMER_PAGE: "alt+t", LOG_PAGE: "alt+l", ABOUT_PAGE: "alt+o", SUMMARY_PAGE: "alt+s", CLEAR_LOG: "alt+c", LOG_NEXT: "ArrowDown", LOG_PREVIOUS: "ArrowUp",
@@ -45,6 +46,7 @@ const HotKeysMapping = (props) => { }, LOG_PAGE: () => router.push("/log"), ABOUT_PAGE: () => router.push("/about"), SUMMARY_PAGE: () => router.push("/summary"), CLEAR_LOG: () => dispatch({ type: "CLEAR_LOG" }), LOG_NEXT: (event) => { event.preventDefault();
modified
components/sidebar.js
@@ -25,6 +25,14 @@ const Sidebar = ({ router }) => { <LogIcon /> </Page> </Link> <Link href="/summary" passHref> <Page active={router.pathname === "/summary"} aria-label={strings.summary} > <SummaryIcon /> </Page> </Link> </Pages> <Link href="/about" passHref> <About aria-label={strings.about}>
@@ -189,3 +197,27 @@ const LogIcon = () => { </svg> );};const SummaryIcon = () => { return ( <svg xmlns="http://www.w3.org/2000/svg" enableBackground="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000" > <g> <rect fill="none" height="24" width="24" /> <g> <path d="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M19,19H5V5h14V19z" /> <rect height="5" width="2" x="7" y="12" /> <rect height="10" width="2" x="15" y="7" /> <rect height="3" width="2" x="11" y="14" /> <rect height="2" width="2" x="11" y="10" /> </g> </g> </svg> );};
@@ -6,6 +6,7 @@ const strings = new LocalizedStrings({ timer: "Timer", log: "Log", about: "About", summary: "Summary", }, // None of this is accurate past this line, someone please help me translate... jp: {
@@ -13,12 +14,14 @@ const strings = new LocalizedStrings({ timer: "タイマー", log: "ログ", about: "約", summary: "概要", }, pl: { name: "Timelite", timer: "Zegar", log: "Dziennik", about: "O Timelite", summary: "Streszczenie", },});
@@ -6,6 +6,7 @@ "prod:start": "next start --port 80" }, "dependencies": { "chart.js": "^3.0.2", "localforage": "^1.9.0", "next": "^10.1.3", "next-offline": "^5.0.3",
@@ -0,0 +1,100 @@import React, { useEffect, useRef, useContext } from "react";import styled from "styled-components";import Chart from "chart.js/auto";import Page from "../components/page";import { Context } from "../components/context";const Summary = () => { const { state, dispatch } = useContext(Context); const canvasRef = useRef(null); // strings.setLanguage(state.language); const getLabels = (entries) => { let tags = []; entries.map((entry) => tags.push(...entry.tags)); return [...new Set(tags)]; }; const getDatasets = (entries) => { const labels = getLabels(entries); let datasets = []; labels.map((label) => { const labeledEntries = [ ...entries.filter((entry) => entry.tags.includes(label)), ]; let totalTime = 0; labeledEntries.map((entry) => { totalTime += entry.end - entry.start; }); datasets.push(totalTime / 1000 / 60 / 60); }); return datasets; }; useEffect(() => { const chart = new Chart(canvasRef.current, { type: "bar", data: { labels: getLabels(state.log), datasets: [ { label: "# of Hours", data: getDatasets(state.log), }, ], }, options: { scales: { y: { beginAtZero: true, }, }, }, }); chart.canvas.parentNode.style.height = "400px"; return () => { chart.destroy(); }; }, []); return ( <Page title="Summary"> <Grid> <Main> <Title>Summary</Title> <CanvasWrapper> <canvas ref={canvasRef} /> </CanvasWrapper> </Main> </Grid> </Page> );};export default Summary;const Grid = styled.div` display: grid; grid-template-columns: 20% 1fr 20%; width: 100%; height: 100vh;`;const Main = styled.main` grid-area: 1/2;`;const Title = styled.h1` font-weight: 300; text-transform: uppercase; font-size: 3em;`;const CanvasWrapper = styled.div` background-color: white; padding: 0.25rem;`;
@@ -1804,6 +1804,11 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0"chart.js@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.0.2.tgz#5893b0548714445b5190cbda9ac307357a56a0c7" integrity sha512-DR0GmFSlxcFJp/w//ZmbxSduAkH/AqwxoiZxK97KHnWZf6gvsKWS3160WvNMMHYvzW9OXqGWjPjVh1Qu+xDabg==chokidar@3.5.1, chokidar@^3.4.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"