Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/app/dashboard/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,6 @@ function SettingsPageContent() {
{statusMessage.message}
</div>
)}

{/* Public Profile Section */}
<div className="rounded-xl border border-[var(--border)] bg-[var(--card)] p-6 shadow-sm">
<div className="flex items-start justify-between mb-2 gap-4">
Expand Down
80 changes: 39 additions & 41 deletions src/components/StreakTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
longest: number;
lastCommitDate: string | null;
totalActiveDays: number;
freezeDates: string[];
Dates: string[];
}

interface ContributionData {
Expand All @@ -35,14 +35,14 @@

interface FreezeData {
hasFreeze: boolean;
freezeDate?: string | null;
Date?: string | null;
}

export function useStreakTracker() {
const { selectedAccount } = useAccount();
const [data, setData] = useState<StreakData | null>(null);
const [contributionData, setContributionData] = useState<ContributionData | null>(null);
const [freezeDates, setFreezeDates] = useState<string[]>([]);
const [Dates, setFreezeDates] = useState<string[]>([]);
const [loading, setLoading] = useState(true);
const [dismissedMilestones, setDismissedMilestones] = useState<number[]>([]);
const [lastCelebratedMilestone, setLastCelebratedMilestone] = useState<number>(0);
Expand All @@ -52,7 +52,7 @@
const [error, setError] = useState<string | null>(null);
const [calendarMonth, setCalendarMonth] = useState(new Date());
const [freeze, setFreeze] = useState<FreezeData | null>(null);
const [freezeLoading, setFreezeLoading] = useState(true);
const [Loading, setFreezeLoading] = useState(true);
const [cancelling, setCancelling] = useState(false);
const [confirmCancel, setConfirmCancel] = useState(false);
const [showFreezeConfirm, setShowFreezeConfirm] = useState(false);
Expand Down Expand Up @@ -124,7 +124,7 @@

const fetchFreeze = useCallback(() => {
setFreezeLoading(true);
fetch("/api/streak/freeze")
fetch("/api/streak/")
.then((r) => r.json())
.then((d: FreezeData) => setFreeze(d))
.catch((err) => {
Expand Down Expand Up @@ -184,20 +184,20 @@
async function handleApplyFreeze() {
setFreezeLoading(true);
try {
const res = await fetch("/api/streak/freeze", { method: "POST" });
if (!res.ok) throw new Error("Failed to apply freeze");
const res = await fetch("/api/streak/", { method: "POST" });
if (!res.ok) throw new Error("Failed to apply ");

const streakUrl =
selectedAccount !== null
? `/api/metrics/streak?accountId=${encodeURIComponent(selectedAccount)}`
: "/api/metrics/streak";
const [streakRes, freezeRes] = await Promise.all([
const [streakRes, Res] = await Promise.all([
fetch(streakUrl),
fetch("/api/streak/freeze"),
fetch("/api/streak/"),
]);
const [streakData, freezeData] = await Promise.all([
const [streakData, Data] = await Promise.all([
streakRes.json() as Promise<StreakData>,
freezeRes.json() as Promise<FreezeData>,
Res.json() as Promise<FreezeData>,
]);
setData(streakData);
setFreeze(freezeData);
Expand All @@ -219,22 +219,22 @@

setCancelling(true);
try {
const res = await fetch("/api/streak/freeze", { method: "DELETE" });
if (!res.ok) throw new Error("Failed to cancel freeze");
const res = await fetch("/api/streak/", { method: "DELETE" });
if (!res.ok) throw new Error("Failed to cancel ");

setConfirmCancel(false);

const streakUrl =
selectedAccount !== null
? `/api/metrics/streak?accountId=${encodeURIComponent(selectedAccount)}`
: "/api/metrics/streak";
const [streakRes, freezeRes] = await Promise.all([
const [streakRes, Res] = await Promise.all([
fetch(streakUrl),
fetch("/api/streak/freeze"),
fetch("/api/streak/"),
]);
const [streakData, freezeData] = await Promise.all([
const [streakData, Data] = await Promise.all([
streakRes.json() as Promise<StreakData>,
freezeRes.json() as Promise<FreezeData>,
Res.json() as Promise<FreezeData>,
]);
setData(streakData);
setFreeze(freezeData);
Expand Down Expand Up @@ -564,7 +564,7 @@



return (

Check failure on line 567 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

JSX fragment has no corresponding closing tag.
<>
{shouldShowBanner && currentMilestone && (
<StreakMilestoneBanner
Expand Down Expand Up @@ -782,25 +782,23 @@
</div>
)}

{freeze && !freeze.hasFreeze && (
<div className="mt-4 flex items-center justify-between rounded-lg border border-[var(--border)] bg-[var(--control)] px-4 py-3">
<div className="flex items-center gap-2">
<span className="text-sm font-medium text-[var(--foreground)]">Streak Freeze</span>
<span className="text-xs text-[var(--muted-foreground)]">❄️ 1 available</span>
<div className="group relative cursor-help">
<span
className="flex h-5 w-5 items-center justify-center rounded-full bg-[var(--card-muted)] text-[10px] font-bold text-[var(--muted-foreground)] hover:bg-[var(--accent-soft)] hover:text-[var(--accent)] transition-colors"
role="img"
aria-label="A streak freeze protects your streak for one missed day. You can only use one freeze at a time."
>
?
</span>
<div className="absolute bottom-full left-1/2 mb-2 -translate-x-1/2 w-64 rounded-lg bg-[var(--foreground)] px-3 py-2 text-xs font-medium leading-relaxed text-[var(--background)] opacity-0 pointer-events-none group-hover:opacity-100 transition-opacity z-20 shadow-lg text-center">
A streak freeze protects your streak for one missed day. You can only use one freeze at a time.
<div className="absolute top-full left-1/2 h-1 w-1 -translate-x-1/2 border-4 border-t-[var(--foreground)] border-transparent" />
</div>
</div>
</div>
{!Loading && ?.hasFreeze && (

Check failure on line 785 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Expression expected.
<div className="mt-4 flex items-center justify-between rounded-lg border border-[var(--accent)]/30 bg-[var(--accent-soft)] px-4 py-3">
<div className="flex items-center gap-2">
<CheckCircle size={18} className="text-[var(--accent)]" aria-hidden="true" />
<span className="text-sm font-medium text-[var(--accent)]">Freeze active today</span>
</div>
{confirmCancel ? (
<div className="flex items-center gap-2">
<span className="text-xs text-[var(--muted-foreground)]">Remove ?</span>
<button
type="button"
onClick={handleCancelFreeze}
disabled={cancelling}
className="rounded-md bg-[var(--destructive)]/10 px-2.5 py-1 text-xs font-medium text-[var(--destructive)] transition hover:bg-[var(--destructive)]/20 disabled:opacity-60"
>
{cancelling ? "Removing..." : "Yes, remove"}
</button>
<button
type="button"
data-testid="streak-freeze-button"
Expand All @@ -814,7 +812,7 @@
{freezeLoading ? "Freezing..." : "Freeze Streak"}
</button>
</div>
)}

Check failure on line 815 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

':' expected.

{/* Streak Calendar Section */}
{contributionData ? (
Expand All @@ -838,7 +836,7 @@
</>
) : null}
</div>
</div>

Check failure on line 839 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

')' expected.
<ConfirmModal
isOpen={showFreezeConfirm}
title="❄️ Use a Streak Freeze?"
Expand All @@ -852,15 +850,15 @@
onCancel={() => setShowFreezeConfirm(false)}
disabled={freezeLoading}
/>
</>

Check failure on line 853 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Identifier expected.
);
}

Check failure on line 855 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Unexpected token. Did you mean `{'}'}` or `&rbrace;`?

interface StreakCalendarProps {
contributions: Record<string, number>;

Check failure on line 858 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Unexpected token. Did you mean `{'>'}` or `&gt;`?

Check failure on line 858 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Identifier expected.

Check failure on line 858 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

'}' expected.
freezeDates: string[];
Dates: string[];
currentMonth: Date;
onMonthChange: (date: Date) => void;

Check failure on line 861 in src/components/StreakTracker.tsx

View workflow job for this annotation

GitHub Actions / Type check

Unexpected token. Did you mean `{'>'}` or `&gt;`?
}

function toLocalDateStr(d: Date): string {
Expand All @@ -869,7 +867,7 @@

function StreakCalendar({
contributions,
freezeDates,
Dates,
currentMonth,
onMonthChange,
}: StreakCalendarProps) {
Expand Down Expand Up @@ -901,7 +899,7 @@

const handlePrevMonth = () => onMonthChange(new Date(year, month - 1));
const handleNextMonth = () => onMonthChange(new Date(year, month + 1));
const freezeSet = new Set(freezeDates);
const Set = new Set(Dates);

return (
<div className="mt-6 pt-6 border-t border-[var(--border)]">
Expand Down Expand Up @@ -951,7 +949,7 @@
const commitCount = contributions[dateStr] ?? 0;
const isFuture = dayData.date > today;
const isToday = dayData.date.toDateString() === today.toDateString();
const isFrozen = freezeSet.has(dateStr) && commitCount === 0;
const isFrozen = Set.has(dateStr) && commitCount === 0;

let bgColor = "bg-transparent";
let borderColor = "border border-[var(--border)]";
Expand Down Expand Up @@ -1031,7 +1029,7 @@
</div>
</div>
<p className="mt-2 text-xs text-[var(--muted-foreground)]">
Frozen days are set via the streak freeze feature above.
Frozen days are set via the streak feature above.
</p>
</div>
);
Expand Down
Loading