diff --git a/src/components/AccountStreak/AccountStreak.tsx b/src/components/AccountStreak/AccountStreak.tsx index b269011f5..938bcda3d 100644 --- a/src/components/AccountStreak/AccountStreak.tsx +++ b/src/components/AccountStreak/AccountStreak.tsx @@ -2,9 +2,9 @@ import { useEffect, useRef, useState } from 'react'; import { isLoggedIn } from '../../lib/jwt'; import { httpGet } from '../../lib/http'; import { useToast } from '../../hooks/use-toast'; -import { ChevronDown, Flame, X } from 'lucide-react'; +import { Flame, X } from 'lucide-react'; import { useOutsideClick } from '../../hooks/use-outside-click'; -import { cn } from '../../lib/classname'; +import { StreakDay } from './StreakDay'; type StreakResponse = { count: number; @@ -69,7 +69,9 @@ export function AccountStreak(props: AccountStreakProps) { const currentCircleCount = Math.min(currentCount, 5) + 1; // Adding one day to show the streak they broke const leftCircleCount = Math.min(5 - currentCircleCount, previousCount) + 1; + // In the maximum case, we will show 10 circles const remainingCount = Math.max(0, 10 - leftCircleCount - currentCircleCount); + const totalCircles = leftCircleCount + currentCircleCount + remainingCount; return (
@@ -86,98 +88,70 @@ export function AccountStreak(props: AccountStreakProps) { {showDropdown && (
-
+
-

+

Current Streak - + {accountStreak?.count || 0}

-

+

Longest Streak - + {accountStreak?.longestCount || 0}

-
-
- {[...Array(leftCircleCount)].map((_, index) => { - const isLast = index === leftCircleCount - 1; - const dayCount = - previousCount - leftCircleCount + index + 1 + 1; +
+
+ {Array.from({ length: totalCircles }).map((_, index) => { + let dayCount, + icon, + isPreviousStreakDay, + isCurrentStreakDay, + isRemainingStreakDay, + isToday; + + if (index < leftCircleCount) { + // Previous streak days + dayCount = previousCount - leftCircleCount + index + 1 + 1; + isPreviousStreakDay = true; + icon = + index === leftCircleCount - 1 ? ( + + ) : ( + + ); + } else if (index < leftCircleCount + currentCircleCount) { + // Current streak days + const currentIndex = index - leftCircleCount; + dayCount = + currentCount - currentCircleCount + currentIndex + 1 + 1; + isCurrentStreakDay = true; + isToday = currentIndex === currentCircleCount - 1; + icon = ; + } else { + // Remaining streak days + const remainingIndex = + index - leftCircleCount - currentCircleCount; + dayCount = currentCount + remainingIndex + 1 + 1; + isRemainingStreakDay = true; + } return ( -
-
- {isLast ? ( - - ) : ( - - )} -
- {dayCount} -
- ); - })} - {[...Array(currentCircleCount)].map((_, index) => { - const dayCount = - currentCount - currentCircleCount + index + 1 + 1; - const isLast = index === currentCircleCount - 1; - - return ( -
-
- {!isLast && ( - - )} -
- {dayCount} - {isLast && ( - - )} -
- ); - })} - - {[...Array(remainingCount)].map((_, index) => { - const dayCount = currentCount + index + 1 + 1; - - return ( -
-
- {dayCount} -
+ ); })}
diff --git a/src/components/AccountStreak/StreakDay.tsx b/src/components/AccountStreak/StreakDay.tsx new file mode 100644 index 000000000..e181f5ccb --- /dev/null +++ b/src/components/AccountStreak/StreakDay.tsx @@ -0,0 +1,56 @@ +import type { ReactNode } from 'react'; +import { cn } from '../../lib/classname'; +import { ChevronDown } from 'lucide-react'; + +type StreakDayProps = { + isToday?: boolean; + isCurrentStreakDay?: boolean; + isPreviousStreakDay?: boolean; + isRemainingStreakDay?: boolean; + dayCount: number; + icon?: ReactNode; +}; + +export function StreakDay(props: StreakDayProps) { + const { + isCurrentStreakDay, + isPreviousStreakDay, + isRemainingStreakDay, + dayCount, + icon, + isToday = false, + } = props; + + return ( +
+
+ {isToday ? null : icon} +
+ + {dayCount} + + {isToday && ( + + )} +
+ ); +}