From 3ec69516b54ba825b4f2cfa66c64de5cac822975 Mon Sep 17 00:00:00 2001 From: Carsten Koch Date: Sat, 27 Apr 2024 21:31:15 +0200 Subject: [PATCH 1/5] docs: plan changes for this release --- docs/releases/next.md | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/docs/releases/next.md b/docs/releases/next.md index 217430d74..713a3e4ae 100644 --- a/docs/releases/next.md +++ b/docs/releases/next.md @@ -1,30 +1,6 @@ -# Projektdetails anzeigen (Version :VERSION) +# Projekte gruppieren (Version :VERSION) ## Neue Funktionen und Änderungen -### Projektdetails - -Zusätzliche Projektdetails wie das Fälligkeitsdatum und bis wann es stummgeschaltet ist, werden jetzt angezeigt und sind editierbar. -Ein Projekt kann jetzt auch erledigt werden und ist anschließend nicht mehr auswählbar. Für weitere 90 Tage wird das Projekt noch angezeigt. Taucht der Projektname in Aktivitäten oder Meetings auf, wird angezeigt, wenn das Projekt als erledigt markiert ist. -Außerdem können Projekten nun Accounts zugeordnet werden. - -### Listenansichten und Detailansichten - -Ist implementiert für Accounts und Projekte. - -### Verantwortung für Accounts - -Tabelle angelegt, in der der Zeitraum gespeichert werden kann, wann ich für einen bestimmten Account verantwortlich gewesen bin. -Die Funktion ist auf der Oberfläche noch nicht implementiert. - -### Wichtigkeit der Accounts - -In der Tabelle `Account` gibt es ein Feld `Order`. Damit soll die Wichtigkeit eines Accounts definiert werden. Die Funktion ist an der Oberfläche noch nicht implementiert. - -### Kleinere Änderungen - -Habe eine Umgebungsvariable `NEXT_PUBLIC_ALLOW_FAKE_DATA_CREATION` eingeführt. Außerhalb der Produktionsumgebung soll damit an verschiedenen Stellen ein Button zur Erstellung von Dummy-Daten angeboten werden. Damit sollen potentiell leere Umgebungen schnell mit Daten befüllt werden können, um das Testen zu erleichtern. Im Moment ist die Funktion selbst noch nicht implementiert. - -Accounts werden jetzt über einen React Context geladen. Das wirkt sich positiv auf die Stabilität und Performance der Applikation aus. - -`ReactDatePicker` wird nun durchgehend für die Auswahl eines Datums und einer Uhrzeit verwendet. +#40 +#41 From 47bd69acae61228ef9b8e1c11404e6f76e9dff2f Mon Sep 17 00:00:00 2001 From: Carsten Koch Date: Mon, 29 Apr 2024 14:00:38 +0200 Subject: [PATCH 2/5] feat: stabilize UI --- components/CategoryTitle.module.css | 14 ++++++++++++++ docs/releases/next.md | 3 +-- pages/_document.tsx | 4 ++++ styles/globals.css | 20 +------------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/components/CategoryTitle.module.css b/components/CategoryTitle.module.css index 927113b73..b7d0f2f28 100644 --- a/components/CategoryTitle.module.css +++ b/components/CategoryTitle.module.css @@ -4,6 +4,20 @@ } } +.content { + position: sticky; + top: 5rem; + background-color: var(--color-bg-sheet-transparent); + z-index: 20; +} + +@media (max-width: 40em) { + .content { + top: 4rem; + padding-bottom: 1rem; + } +} + .content h1, .content textarea { font-size: var(--font-size-xx-large); diff --git a/docs/releases/next.md b/docs/releases/next.md index 713a3e4ae..04f7b4ba0 100644 --- a/docs/releases/next.md +++ b/docs/releases/next.md @@ -2,5 +2,4 @@ ## Neue Funktionen und Änderungen -#40 -#41 +- Die Ansicht in der App ist stabilisiert worden und zoomt nicht mehr in Eingabefelder ([#40](https://github.com/cabcookie/personal-crm/issues/40)) diff --git a/pages/_document.tsx b/pages/_document.tsx index d7a41ab83..fb58c0474 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -7,6 +7,10 @@ export default function Document() { +
diff --git a/styles/globals.css b/styles/globals.css index f626ddaf5..60f9939f7 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,6 +1,7 @@ :root { /* Base colors */ --color-bg-sheet: #fefefe; + --color-bg-sheet-transparent: rgba(254, 254, 254, 0.9); --background-color: #e9e9e9; --bg-color-transparent: #e9e9e9f2; --header-text-color: #333333; @@ -41,25 +42,6 @@ --navigation-menu-width: 40rem; } -/* @media (min-width: 40em) { - :root { - --font-size-base: "10px"; - } -} */ - -/* @media (min-width: 60em) { - :root { - --font-size-xxx-small: 1.1rem; - --font-size-xx-small: 1.2rem; - --font-size-x-small: 1.4rem; - --font-size-small: 1.6rem; - --font-size-medium: 1.8rem; - --font-size-large: 2rem; - --font-size-x-large: 2.8rem; - --font-size-xx-large: 4rem; - } -} */ - @font-face { font-family: "Inter"; src: url("/fonts/Inter-VariableFont_slnt,wght.ttf") format("truetype"); From b205da875b0dd06a6ff84dda7bf317b9dbe5c910 Mon Sep 17 00:00:00 2001 From: Carsten Koch Date: Mon, 29 Apr 2024 14:01:51 +0200 Subject: [PATCH 3/5] feat: filter projects --- .../ContextSwitcher.module.css | 58 ----------- .../navigation-menu/ContextSwitcher.tsx | 72 ++------------ .../SelectionSlider.module.css | 57 +++++++++++ .../selection-slider/selection-slider.tsx | 98 +++++++++++++++++++ docs/releases/next.md | 1 + pages/projects/ProjectList.module.css | 14 +++ pages/projects/index.tsx | 36 +++++-- 7 files changed, 210 insertions(+), 126 deletions(-) create mode 100644 components/ui-elements/selection-slider/SelectionSlider.module.css create mode 100644 components/ui-elements/selection-slider/selection-slider.tsx create mode 100644 pages/projects/ProjectList.module.css diff --git a/components/navigation-menu/ContextSwitcher.module.css b/components/navigation-menu/ContextSwitcher.module.css index 5290cbf5f..c2a997342 100644 --- a/components/navigation-menu/ContextSwitcher.module.css +++ b/components/navigation-menu/ContextSwitcher.module.css @@ -6,61 +6,3 @@ font-weight: bold; margin-bottom: 0.5rem; } - -.switcher { - --border-radius: 1.2rem; - --border-thick: 1px; - display: flex; - position: relative; - border: var(--border-thick) solid rgb(198, 195, 195); - font-size: var(--font-size-small); - border-radius: var(--border-radius); - width: 100%; - justify-content: space-around; - background: none; - transition: background-color 0.3s ease; -} - -@media (max-width: 40em) { - .switcher { - --border-radius: 0.8rem; - font-size: var(--font-size-x-small); - } -} - -.context { - --context-padding: 0.1rem; - flex-grow: 1; - text-align: center; - cursor: pointer; - padding-top: var(--context-padding); - padding-bottom: var(--context-padding); - transition: color 0.3s ease; - color: var(--context-color); - position: relative; - text-transform: capitalize; -} - -@media (max-width: 40em) { - .context { - --context-padding: 0rem; - } -} - -.highlighter { - position: absolute; - height: calc(100% + var(--border-thick) * 2); - top: calc(var(--border-thick) * -1); - left: 0; - border-radius: var(--border-radius); - transition: transform 0.3s ease, background-color 0.3s ease; -} - -.context:hover { - color: var(--context-color-hover); -} - -.isActive, -.isActive:hover { - color: white; -} diff --git a/components/navigation-menu/ContextSwitcher.tsx b/components/navigation-menu/ContextSwitcher.tsx index 6c2211fa1..64733884d 100644 --- a/components/navigation-menu/ContextSwitcher.tsx +++ b/components/navigation-menu/ContextSwitcher.tsx @@ -1,55 +1,20 @@ -import { - CSSProperties, - FC, - MutableRefObject, - useEffect, - useRef, - useState, -} from "react"; +import { FC, useEffect, useState } from "react"; import styles from "./ContextSwitcher.module.css"; import contextStyles from "../layouts/ContextColors.module.css"; import { Context, useContextContext } from "@/contexts/ContextContext"; +import SelectionSlider from "../ui-elements/selection-slider/selection-slider"; export const contexts: Context[] = ["family", "hobby", "work"]; -const moveSlider = ( - setHighlighterStyle: (style: CSSProperties) => void, - contextRef: MutableRefObject, - context?: Context -) => { - const activeIndex = contexts.findIndex((c) => c === context); - const activeElement = contextRef.current[activeIndex]; - - if (activeElement) { - const { offsetWidth: width, offsetLeft: left } = activeElement; - const innerOffset = contextRef.current[0].offsetLeft + 2; - setHighlighterStyle({ - width: `${width + innerOffset * 2}px`, - transform: `translateX(${left - innerOffset}px)`, - backgroundColor: `var(--${context}-color-main)`, - }); - } -}; - type ContextSwitcherProps = { context?: Context; }; const ContextSwitcher: FC = ({ context }) => { - const [highlighterStyle, setHighlighterStyle] = useState({}); const { setContext } = useContextContext(); - const contextRef = useRef([]); - - useEffect( - () => moveSlider(setHighlighterStyle, contextRef, context), - [context] - ); + const [btnColor, setBtnColor] = useState(`var(--${context}-color-main)`); - useEffect(() => { - const listener = () => moveSlider(setHighlighterStyle, contextRef, context); - window.addEventListener("resize", listener); - return () => window.removeEventListener("resize", listener); - }, [context]); + useEffect(() => setBtnColor(`var(--${context}-color-main)`), [context]); return (
= ({ context }) => { }`} >
Switch Context:
- +
); }; diff --git a/components/ui-elements/selection-slider/SelectionSlider.module.css b/components/ui-elements/selection-slider/SelectionSlider.module.css new file mode 100644 index 000000000..2fcf23d97 --- /dev/null +++ b/components/ui-elements/selection-slider/SelectionSlider.module.css @@ -0,0 +1,57 @@ +.switcher { + --border-radius: 1.2rem; + --border-thick: 1px; + display: flex; + position: relative; + border: var(--border-thick) solid rgb(198, 195, 195); + font-size: var(--font-size-small); + border-radius: var(--border-radius); + width: 100%; + justify-content: space-around; + background: none; + transition: background-color 0.3s ease; +} + +@media (max-width: 40em) { + .switcher { + --border-radius: 0.8rem; + font-size: var(--font-size-x-small); + } +} + +.value { + --value-padding: 0.1rem; + flex-grow: 1; + text-align: center; + cursor: pointer; + padding-top: var(--value-padding); + padding-bottom: var(--value-padding); + transition: color 0.3s ease; + color: var(--value-color); + position: relative; + text-transform: capitalize; +} + +@media (max-width: 40em) { + .value { + --value-padding: 0rem; + } +} + +.highlighter { + position: absolute; + height: calc(100% + var(--border-thick) * 2); + top: calc(var(--border-thick) * -1); + left: 0; + border-radius: var(--border-radius); + transition: transform 0.3s ease, background-color 0.3s ease; +} + +.value:hover { + color: var(--value-color-hover); +} + +.isActive, +.isActive:hover { + color: white; +} diff --git a/components/ui-elements/selection-slider/selection-slider.tsx b/components/ui-elements/selection-slider/selection-slider.tsx new file mode 100644 index 000000000..dde7df967 --- /dev/null +++ b/components/ui-elements/selection-slider/selection-slider.tsx @@ -0,0 +1,98 @@ +import { + CSSProperties, + FC, + MutableRefObject, + useEffect, + useRef, + useState, +} from "react"; +import styles from "./SelectionSlider.module.css"; + +const moveSlider = ( + setHighlighterStyle: (style: CSSProperties) => void, + sliderRef: MutableRefObject, + valueList: string[], + btnColor: string, + value?: string +) => { + const activeIndex = valueList.findIndex((c) => c === value); + const activeElement = sliderRef.current[activeIndex]; + + if (activeElement) { + const { offsetWidth: width, offsetLeft: left } = activeElement; + const innerOffset = sliderRef.current[0].offsetLeft + 2; + setHighlighterStyle({ + width: `${width + innerOffset * 2}px`, + transform: `translateX(${left - innerOffset}px)`, + backgroundColor: btnColor, + }); + } +}; + +type SelectionSliderProps = { + valueList: any[]; + value: any; + onChange: (val: any) => void; + btnColor?: string; +}; + +const SelectionSlider: FC = ({ + valueList, + value, + onChange, + btnColor, +}) => { + const [highlighterStyle, setHighlighterStyle] = useState({}); + const sliderRef = useRef([]); + + useEffect( + () => + moveSlider( + setHighlighterStyle, + sliderRef, + valueList, + btnColor || "gray", + value + ), + [value, valueList, btnColor] + ); + + useEffect(() => { + const listener = () => + moveSlider( + setHighlighterStyle, + sliderRef, + valueList, + btnColor || "gray", + value + ); + window.addEventListener("resize", listener); + return () => window.removeEventListener("resize", listener); + }, [value, valueList, btnColor]); + + return ( + + ); +}; + +export default SelectionSlider; diff --git a/docs/releases/next.md b/docs/releases/next.md index 04f7b4ba0..518b0af1d 100644 --- a/docs/releases/next.md +++ b/docs/releases/next.md @@ -3,3 +3,4 @@ ## Neue Funktionen und Änderungen - Die Ansicht in der App ist stabilisiert worden und zoomt nicht mehr in Eingabefelder ([#40](https://github.com/cabcookie/personal-crm/issues/40)) +- Projektlisten lassen sich jetzt filtern nach Work In Progress, On Hold und Done ([#41](https://github.com/cabcookie/personal-crm/issues/41)) diff --git a/pages/projects/ProjectList.module.css b/pages/projects/ProjectList.module.css new file mode 100644 index 000000000..12c7bd3d3 --- /dev/null +++ b/pages/projects/ProjectList.module.css @@ -0,0 +1,14 @@ +.filter { + margin-bottom: 1rem; + padding-bottom: 1rem; + position: sticky; + top: 10rem; + background-color: var(--color-bg-sheet-transparent); + z-index: 20; +} + +@media (max-width: 40em) { + .filter { + top: 8rem; + } +} diff --git a/pages/projects/index.tsx b/pages/projects/index.tsx index 6dfa4705f..22d94ad05 100644 --- a/pages/projects/index.tsx +++ b/pages/projects/index.tsx @@ -1,11 +1,16 @@ import { useProjectsContext } from "@/api/ContextProjects"; import MainLayout from "@/components/layouts/MainLayout"; import ProjectDetails from "@/components/ui-elements/project-details/project-details"; +import SelectionSlider from "@/components/ui-elements/selection-slider/selection-slider"; import ProjectName from "@/components/ui-elements/tokens/project-name"; +import { isTodayOrFuture } from "@/helpers/functional"; import { useRouter } from "next/router"; +import { useState } from "react"; +import styles from "./ProjectList.module.css"; const ProjectListPage = () => { const { projects, createProject } = useProjectsContext(); + const [filter, setFilter] = useState("WIP"); const router = useRouter(); const createAndOpenNewProject = async () => { @@ -20,14 +25,33 @@ const ProjectListPage = () => { sectionName="Projects" addButton={{ label: "New", onClick: createAndOpenNewProject }} > +
+ +
{!projects ? "Loading projects..." - : projects.map((project) => ( -
- - -
- ))} + : projects + .filter( + ({ done, onHoldTill }) => + (filter === "WIP" && + !done && + (!onHoldTill || !isTodayOrFuture(onHoldTill))) || + (filter === "On Hold" && + !done && + onHoldTill && + isTodayOrFuture(onHoldTill)) || + (filter === "Done" && done) + ) + .map((project) => ( +
+ + +
+ ))} ); }; From bb3c1ceea8bd3685f71c29d283978ab292f70195 Mon Sep 17 00:00:00 2001 From: Carsten Koch Date: Mon, 29 Apr 2024 14:02:22 +0200 Subject: [PATCH 4/5] feat: change activitiy dates --- api/useActivity.ts | 19 +++++++++++++++++++ components/activities/activity.tsx | 23 ++++++++++++++++++----- docs/releases/next.md | 1 + 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/api/useActivity.ts b/api/useActivity.ts index 7a24a6ac5..56379ad05 100644 --- a/api/useActivity.ts +++ b/api/useActivity.ts @@ -60,6 +60,24 @@ const useActivity = (activityId?: string) => { mutate: mutateActivity, } = useSWR(`/api/activities/${activityId}`, fetchActivity(activityId)); + const updateDate = async (date: Date) => { + if (!activity) return; + const updated: Activity = { + ...activity, + finishedOn: date, + updatedAt: new Date(), + }; + mutateActivity(updated, false); + const { data, errors } = await client.models.Activity.update({ + id: activity.id, + finishedOn: date.toISOString(), + }); + if (errors) handleApiErrors(errors, "Error updating date of activity"); + + mutateActivity(updated); + return data.id; + }; + const updateNotes = async (notes: string) => { if (!activity?.id) return; const updated: Activity = { ...activity, notes, updatedAt: new Date() }; @@ -102,6 +120,7 @@ const useActivity = (activityId?: string) => { errorActivity, updateNotes, addProjectToActivity, + updateDate, }; }; diff --git a/components/activities/activity.tsx b/components/activities/activity.tsx index 799d898f8..b151ad474 100644 --- a/components/activities/activity.tsx +++ b/components/activities/activity.tsx @@ -1,13 +1,14 @@ -import { FC, useState } from "react"; +import { FC, useEffect, useState } from "react"; import { Descendant } from "slate"; import { TransformNotesToMdFunction } from "../ui-elements/notes-writer/notes-writer-helpers"; import { debouncedUpdateNotes } from "../ui-elements/activity-helper"; import useActivity from "@/api/useActivity"; -import { toLocaleDateTimeString } from "@/helpers/functional"; import ProjectName from "../ui-elements/tokens/project-name"; import MeetingName from "../ui-elements/tokens/meeting-name"; import NotesWriter from "../ui-elements/notes-writer/NotesWriter"; import ActivityMetaData from "../ui-elements/activity-meta-data"; +import DateSelector from "../ui-elements/date-selector"; +import SavedState from "../ui-elements/project-notes-form/saved-state"; type ActivityComponentProps = { activityId: string; @@ -26,9 +27,14 @@ const ActivityComponent: FC = ({ autoFocus, createActivity, }) => { - const { activity, updateNotes } = useActivity(activityId); + const { activity, updateNotes, updateDate } = useActivity(activityId); const [notesSaved, setNotesSaved] = useState(true); + const [dateSaved, setDateSaved] = useState(true); + const [date, setDate] = useState(activity?.finishedOn || new Date()); + useEffect(() => { + setDate(activity?.finishedOn || new Date()); + }, [activity]); const handleNotesUpdate = ( notes: Descendant[], transformerFn: TransformNotesToMdFunction @@ -43,12 +49,19 @@ const ActivityComponent: FC = ({ }); }; + const handleDateUpdate = async (date: Date) => { + setDateSaved(false); + setDate(date); + const data = await updateDate(date); + if (data) setDateSaved(true); + }; + return (
{showDates && (

- {toLocaleDateTimeString(activity?.finishedOn) || - "Create new activity"} + +

)} {showProjects && diff --git a/docs/releases/next.md b/docs/releases/next.md index 518b0af1d..57577445b 100644 --- a/docs/releases/next.md +++ b/docs/releases/next.md @@ -4,3 +4,4 @@ - Die Ansicht in der App ist stabilisiert worden und zoomt nicht mehr in Eingabefelder ([#40](https://github.com/cabcookie/personal-crm/issues/40)) - Projektlisten lassen sich jetzt filtern nach Work In Progress, On Hold und Done ([#41](https://github.com/cabcookie/personal-crm/issues/41)) +- Bei Aktivitäten kann nun das Datum geändert werden. From 8533da87ce7be458beec84682ecbf850f5142144 Mon Sep 17 00:00:00 2001 From: Carsten Koch Date: Mon, 29 Apr 2024 14:03:29 +0200 Subject: [PATCH 5/5] feat: add navigation to projects and accounts --- components/navigation-menu/NavigationMenu.tsx | 4 ++ .../OtherNavigationSection.module.css | 34 ++++++++++++++++ .../OtherNavigationSection.tsx | 40 +++++++++++++++++++ docs/releases/next.md | 1 + helpers/keyboard-events/main-layout.ts | 2 + 5 files changed, 81 insertions(+) create mode 100644 components/navigation-menu/OtherNavigationSection.module.css create mode 100644 components/navigation-menu/OtherNavigationSection.tsx diff --git a/components/navigation-menu/NavigationMenu.tsx b/components/navigation-menu/NavigationMenu.tsx index f1086073a..36259f89d 100644 --- a/components/navigation-menu/NavigationMenu.tsx +++ b/components/navigation-menu/NavigationMenu.tsx @@ -3,6 +3,7 @@ import ContextSwitcher from "./ContextSwitcher"; import MainNavigationSection from "./MainNavigationSection"; import styles from "./NavigationMenu.module.css"; import { Context } from "@/contexts/ContextContext"; +import OtherNavigationSection from "./OtherNavigationSection"; type NavigationMenuProps = { context?: Context; @@ -18,6 +19,9 @@ const NavigationMenu = forwardRef(
+
+ +
); } diff --git a/components/navigation-menu/OtherNavigationSection.module.css b/components/navigation-menu/OtherNavigationSection.module.css new file mode 100644 index 000000000..4fc157720 --- /dev/null +++ b/components/navigation-menu/OtherNavigationSection.module.css @@ -0,0 +1,34 @@ +.wrapper { + display: flex; + flex-direction: column; + width: 100%; + justify-content: center; + align-items: center; + gap: 0.6rem; +} + +.menuItem { + border-radius: 0.4rem; + text-align: center; + padding: 0.6rem; + width: 100%; + border: none; + background-color: var(--color-btn); + box-shadow: none; + color: var(--color-text); + text-decoration: none; + transition: background-color 1s ease, color 1s ease; + font-weight: bold; +} + +.menuItem:hover { + filter: brightness(98%); + box-shadow: 2px 2px 8px rgba(89, 88, 88, 0.344); +} + +@media (max-width: 24.999em) { + .menuItem { + font-size: var(--font-size-xx-small); + font-weight: normal; + } +} diff --git a/components/navigation-menu/OtherNavigationSection.tsx b/components/navigation-menu/OtherNavigationSection.tsx new file mode 100644 index 000000000..f6ea2ef1d --- /dev/null +++ b/components/navigation-menu/OtherNavigationSection.tsx @@ -0,0 +1,40 @@ +import { Context } from "@/contexts/ContextContext"; +import { FC } from "react"; +import styles from "./OtherNavigationSection.module.css"; +import contextStyles from "@/components/layouts/ContextColors.module.css"; +import Link from "next/link"; + +type OtherNavigationSectionProps = { + context?: Context; +}; + +type MenuItem = { + name: string; + link: string; +}; + +const menuItems: MenuItem[] = [ + { name: "Projects", link: "/projects" }, + { name: "Accounts", link: "/accounts" }, + // { name: "People", link: "/people" }, +]; + +const OtherNavigationSection: FC = ({ + context, +}) => { + return ( +
+ {menuItems.map(({ name, link }, idx) => ( + + {name} + + ))} +
+ ); +}; + +export default OtherNavigationSection; diff --git a/docs/releases/next.md b/docs/releases/next.md index 57577445b..3200e75e5 100644 --- a/docs/releases/next.md +++ b/docs/releases/next.md @@ -5,3 +5,4 @@ - Die Ansicht in der App ist stabilisiert worden und zoomt nicht mehr in Eingabefelder ([#40](https://github.com/cabcookie/personal-crm/issues/40)) - Projektlisten lassen sich jetzt filtern nach Work In Progress, On Hold und Done ([#41](https://github.com/cabcookie/personal-crm/issues/41)) - Bei Aktivitäten kann nun das Datum geändert werden. +- In der Navigation kann nun auch zu Projekten und Accounts gewechselt werden. Mit ^+p und ^+a kann man auch direkt hinspringen. diff --git a/helpers/keyboard-events/main-layout.ts b/helpers/keyboard-events/main-layout.ts index 2048d95d5..f5b12a102 100644 --- a/helpers/keyboard-events/main-layout.ts +++ b/helpers/keyboard-events/main-layout.ts @@ -11,6 +11,8 @@ export const addKeyDownListener = ( t: () => router.push("/today"), m: () => router.push("/meetings"), c: () => router.push("/commitments"), + p: () => router.push("/projects"), + a: () => router.push("/accounts"), w: () => setContext("work"), h: () => setContext("hobby"), f: () => setContext("family"),