feat(web): recurring timer badge, recurringTimerId field, generateTimerFromRecurrence helper

This commit is contained in:
saravanakumardb1 2026-02-27 22:33:57 -08:00
parent d909830fcd
commit a2e8f985d2
3 changed files with 57 additions and 0 deletions

View File

@ -103,6 +103,15 @@ export function TimerCard({ timer }: TimerCardProps) {
<Tag size={10} /> {timer.category}
</span>
)}
{timer.recurringTimerId && (
<span
className="text-xs px-1.5 py-0.5 rounded-full flex items-center gap-0.5"
style={{ backgroundColor: 'rgba(46,230,214,0.15)', color: 'var(--cm-accent-secondary)' }}
title="Recurring timer"
>
<Repeat size={10} />
</span>
)}
{timer.linkedTimerId && (
<span
className="text-xs px-1.5 py-0.5 rounded-full"

View File

@ -240,6 +240,53 @@ export function createCustomRule(
return { frequency: 'custom', daysOfWeek, timeOfDay: timeOfDayMinutes, endDate };
}
// ── Timer Generation ─────────────────────────────────────────
/**
* Generate a Timer from a RecurringTimer for the next occurrence.
* The generated timer has `recurringTimerId` set for badge display.
*/
export function generateTimerFromRecurrence(
recurring: RecurringTimer,
label: string,
urgency: import('./urgency').UrgencyLevel = 'standard',
category?: string,
): import('./timer-engine').Timer | null {
if (recurring.paused) return null;
const afterDate = recurring.skipNext
? getOccurrenceAfterSkip(recurring.recurrence, recurring.lastOccurrence ?? Date.now())
: getNextOccurrence(recurring.recurrence, recurring.lastOccurrence ?? Date.now());
if (!afterDate) return null;
const now = Date.now();
const id = `${recurring.id}-${afterDate}`;
return {
id,
type: 'alarm',
label,
urgency,
state: 'active',
targetTime: afterDate,
duration: null,
createdAt: now,
startedAt: now,
pausedAt: null,
firedAt: null,
dismissedAt: null,
completedAt: null,
elapsedBeforePause: 0,
cascade: { preset: 'standard', intervals: [] },
warnings: [],
snoozeCount: 0,
snoozedUntil: null,
category,
recurringTimerId: recurring.id,
};
}
// ── Display Helpers ───────────────────────────────────────────
/**

View File

@ -57,6 +57,7 @@ export interface Timer {
category?: string;
tags?: string[];
linkedTimerId?: string | null;
recurringTimerId?: string | null;
}
export interface PomodoroConfig {