From 4343f8dfd10c0fd73e09eebaa596c396cabf38a6 Mon Sep 17 00:00:00 2001 From: Maniska Date: Tue, 19 May 2026 15:37:33 +0530 Subject: [PATCH 1/3] feat: add smooth mount animation to goal progress bars --- src/components/GoalTracker.tsx | 43 ++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/components/GoalTracker.tsx b/src/components/GoalTracker.tsx index 11afe57f..a8c2a83a 100644 --- a/src/components/GoalTracker.tsx +++ b/src/components/GoalTracker.tsx @@ -21,10 +21,11 @@ const RECURRENCE_LABELS: Record = { }; export default function GoalTracker() { + const [mounted, setMounted] = useState(false); +const [reducedMotion, setReducedMotion] = useState(false); const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); const [lastUpdated, setLastUpdated] = useState(null); - const [minutesAgo, setMinutesAgo] = useState(0); const [title, setTitle] = useState(""); const [target, setTarget] = useState(7); const [unit, setUnit] = useState("commits"); @@ -46,9 +47,21 @@ export default function GoalTracker() { .finally(() => { setLoading(false); setLastUpdated(new Date()); - setMinutesAgo(0); }); }, [loadGoals]); + useEffect(() => { + const mediaQuery = window.matchMedia( + "(prefers-reduced-motion: reduce)" + ); + + setReducedMotion(mediaQuery.matches); + + const timeout = setTimeout(() => { + setMounted(true); + }, 50); + + return () => clearTimeout(timeout); +}, []); async function handleCreate(e: React.FormEvent) { e.preventDefault(); @@ -106,14 +119,6 @@ export default function GoalTracker() { return ""; } - useEffect(() => { - if (!lastUpdated) return; - const interval = setInterval(() => { - const diff = Math.floor((Date.now() - lastUpdated.getTime()) / 60000); - setMinutesAgo(diff); - }, 60000); - return () => clearInterval(interval); - }, [lastUpdated]); if (loading) { return ( @@ -212,9 +217,16 @@ export default function GoalTracker() {
+ className={`h-full rounded-full transition-all duration-700 ease-out ${ + completed ? "bg-emerald-500" : "bg-[var(--accent)]" + }`} + style={{ + width: + reducedMotion || mounted + ? `${pct}%` + : "0%", + }} +/>
); @@ -222,11 +234,6 @@ export default function GoalTracker() { )} - {lastUpdated && ( -

- {minutesAgo === 0 ? "Updated just now" : `Updated ${minutesAgo} min ago`} -

- )} {/* Goal Creation Form */}
From d98debc6578950f6c2e8e405401b387ac8f20f99 Mon Sep 17 00:00:00 2001 From: Maniska Date: Tue, 19 May 2026 15:51:45 +0530 Subject: [PATCH 2/3] chore: refresh branch state --- src/components/GoalTracker.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/GoalTracker.tsx b/src/components/GoalTracker.tsx index a8c2a83a..675056ac 100644 --- a/src/components/GoalTracker.tsx +++ b/src/components/GoalTracker.tsx @@ -21,6 +21,7 @@ const RECURRENCE_LABELS: Record = { }; export default function GoalTracker() { + const [mounted, setMounted] = useState(false); const [reducedMotion, setReducedMotion] = useState(false); const [goals, setGoals] = useState([]); From 83b16b2af9e2f22a247653f344d67522988a3d8e Mon Sep 17 00:00:00 2001 From: Maniska Date: Tue, 19 May 2026 15:56:02 +0530 Subject: [PATCH 3/3] fix: resolve GoalTracker merge conflicts --- src/components/GoalTracker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/GoalTracker.tsx b/src/components/GoalTracker.tsx index 675056ac..6a814404 100644 --- a/src/components/GoalTracker.tsx +++ b/src/components/GoalTracker.tsx @@ -335,4 +335,4 @@ const [reducedMotion, setReducedMotion] = useState(false);
); -} \ No newline at end of file +}