From b8be23ee99f47c89d9c9f4ce508b940efc88b1ca Mon Sep 17 00:00:00 2001
From: Ellie Huxtable <ellie@elliehuxtable.com>
Date: Tue, 18 Jun 2024 17:11:24 +0100
Subject: feat(gui): add activity calendar to the homepage (#2160)

* feat(gui): add activity calendar to the homepage

* localise week start
---
 ui/src/pages/Home.tsx | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)

(limited to 'ui/src/pages/Home.tsx')

diff --git a/ui/src/pages/Home.tsx b/ui/src/pages/Home.tsx
index 00752326..51c1e934 100644
--- a/ui/src/pages/Home.tsx
+++ b/ui/src/pages/Home.tsx
@@ -1,10 +1,13 @@
-import { useEffect } from "react";
+import React, { useEffect, useState } from "react";
 import { formatRelative } from "date-fns";
+import { Tooltip as ReactTooltip } from "react-tooltip";
 
 import { useStore } from "@/state/store";
 import { useToast } from "@/components/ui/use-toast";
 import { invoke } from "@tauri-apps/api/core";
 
+import ActivityCalendar from "react-activity-calendar";
+
 function Stats({ stats }: any) {
   return (
     <div>
@@ -44,16 +47,32 @@ function Header({ name }: any) {
   );
 }
 
+const explicitTheme: ThemeInput = {
+  light: ["#f0f0f0", "#c4edde", "#7ac7c4", "#f73859", "#384259"],
+  dark: ["#383838", "#4D455D", "#7DB9B6", "#F5E9CF", "#E96479"],
+};
+
 export default function Home() {
+  const [weekStart, setWeekStart] = useState(0);
+
   const homeInfo = useStore((state) => state.homeInfo);
   const user = useStore((state) => state.user);
+  const calendar = useStore((state) => state.calendar);
+
   const refreshHomeInfo = useStore((state) => state.refreshHomeInfo);
   const refreshUser = useStore((state) => state.refreshUser);
+  const refreshCalendar = useStore((state) => state.refreshCalendar);
+
   const { toast } = useToast();
 
   useEffect(() => {
+    let locale = new Intl.Locale(navigator.language);
+    let weekinfo = locale.getWeekInfo();
+    setWeekStart(weekinfo.firstDay);
+
     refreshHomeInfo();
     refreshUser();
+    refreshCalendar();
 
     let setup = async () => {
       let installed = await invoke("is_cli_installed");
@@ -112,6 +131,24 @@ export default function Home() {
             ]}
           />
         </div>
+
+        <div className="pt-10">
+          <ActivityCalendar
+            theme={explicitTheme}
+            data={calendar}
+            weekStart={weekStart}
+            renderBlock={(block, activity) =>
+              React.cloneElement(block, {
+                "data-tooltip-id": "react-tooltip",
+                "data-tooltip-html": `${activity.count} commands on ${activity.date}`,
+              })
+            }
+            labels={{
+              totalCount: "{{count}} history records in the last year",
+            }}
+          />
+          <ReactTooltip id="react-tooltip" />
+        </div>
       </div>
     </div>
   );
-- 
cgit v1.3.1

