Skip to content

Commit 203ddee

Browse files
committed
feat: Cache WakaTime stats and use async fetch
Store WakaTime stats and timestamp in sessionStorage with a 5-minute TTL. Convert fetchStats to an async useCallback, add network error handling and proper syncing state, and update effect to call fetchStats.
1 parent c24103b commit 203ddee

1 file changed

Lines changed: 40 additions & 17 deletions

File tree

app/components/dashboard/Stats.tsx

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22

3-
import { useEffect, useState } from "react";
3+
import { useCallback, useEffect, useState } from "react";
44
import AOS from "aos";
55
import "devicon/devicon.min.css";
66
import { toast } from "react-toastify";
@@ -59,25 +59,48 @@ export default function Stats({
5959
best_day: { date: "", total_seconds: 0 },
6060
});
6161

62-
const fetchStats = () => {
63-
fetch("/api/wakatime/sync")
64-
.then((res) => res.json())
65-
.then((data) => {
66-
if (data.success) {
67-
setStats(data.data);
68-
} else {
69-
toast.error(
70-
data.error || "Failed to fetch stats. Please try syncing again.",
71-
);
72-
}
73-
setSyncing(false);
74-
});
75-
};
62+
const fetchStats = useCallback(async () => {
63+
setSyncing(true);
7664

77-
useEffect(() => {
78-
fetchStats();
65+
const cached = sessionStorage.getItem("wakatimeStats");
66+
const cacheTime = Number(sessionStorage.getItem("wakatimeStatsTime"));
67+
const now = Date.now();
68+
69+
if (cached && cacheTime && now - cacheTime < 1000 * 60 * 5) {
70+
setStats(JSON.parse(cached));
71+
setSyncing(false);
72+
return;
73+
}
74+
75+
try {
76+
const res = await fetch("/api/wakatime/sync");
77+
const data = await res.json();
78+
79+
if (data.success) {
80+
setStats(data.data);
81+
82+
sessionStorage.setItem("wakatimeStats", JSON.stringify(data.data));
83+
sessionStorage.setItem("wakatimeStatsTime", now.toString());
84+
} else {
85+
toast.error(
86+
data.error || "Failed to fetch stats. Please try syncing again.",
87+
);
88+
}
89+
} catch (err) {
90+
toast.error("Network error. Please try again.");
91+
}
92+
93+
setSyncing(false);
7994
}, []);
8095

96+
useEffect(() => {
97+
const run = async () => {
98+
await fetchStats();
99+
};
100+
101+
run();
102+
}, [fetchStats]);
103+
81104
useEffect(() => {
82105
if (!syncing) {
83106
setTimeout(() => {

0 commit comments

Comments
 (0)