feat: add webpush and sadhna tracker
This commit is contained in:
@@ -91,6 +91,29 @@ export type SadhnaDashboard = {
|
||||
// plus an in-progress fold for an unfinished today. Capped server-side;
|
||||
// current_streak holds the true length.
|
||||
vine_days: VineDay[];
|
||||
// Rewards. `next_reward_date` is the projected UTC date (YYYY-MM-DD) of the
|
||||
// next gift if the streak continues. `pending_reward` is a freshly earned
|
||||
// gift to celebrate now (null when there's nothing to show).
|
||||
next_reward_date: string | null;
|
||||
pending_reward: SadhnaRewardGrant | null;
|
||||
};
|
||||
|
||||
/** A gift item in the streak-reward catalog. */
|
||||
export type SadhnaReward = {
|
||||
id: string;
|
||||
key: string;
|
||||
name: string;
|
||||
meaning: string;
|
||||
image_url: string;
|
||||
active: boolean;
|
||||
sort: number;
|
||||
};
|
||||
|
||||
/** A reward earned at a streak milestone (a multiple of 7 days). */
|
||||
export type SadhnaRewardGrant = {
|
||||
milestone: number;
|
||||
granted_at: string;
|
||||
reward: SadhnaReward;
|
||||
};
|
||||
|
||||
// ─── API ───────────────────────────────────────────────────────────────
|
||||
@@ -99,10 +122,41 @@ export const sadhna = {
|
||||
/** Today's progress + streak + plant state. */
|
||||
dashboard: () => call<SadhnaDashboard>("/sadhna/dashboard"),
|
||||
|
||||
/** Per-day state for an inclusive UTC date range (YYYY-MM-DD), for the
|
||||
* calendar's week/month views. Range is bounded to a year server-side. */
|
||||
history: (from: string, to: string) =>
|
||||
call<SadhnaDay[]>(
|
||||
`/sadhna/history?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`,
|
||||
),
|
||||
|
||||
/** Save today's chanting round count; returns the recomputed dashboard. */
|
||||
saveChant: (roundsCompleted: number) =>
|
||||
call<SadhnaDashboard>("/sadhna/chant", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ rounds_completed: roundsCompleted }),
|
||||
}),
|
||||
|
||||
/** The user's collected gifts (newest first) + giftable catalog size. */
|
||||
rewards: () =>
|
||||
call<{ collected: SadhnaRewardGrant[]; total: number }>("/sadhna/rewards"),
|
||||
|
||||
/** Acknowledge pending celebrations after showing the confetti. */
|
||||
ackRewards: () => call<void>("/sadhna/rewards/ack", { method: "POST" }),
|
||||
|
||||
/** Whether daily sādhana reminders are enabled for the caller. */
|
||||
reminderPrefs: () => call<{ enabled: boolean }>("/sadhna/reminders"),
|
||||
|
||||
/** Toggle daily sādhana reminders. */
|
||||
setReminderPrefs: (enabled: boolean) =>
|
||||
call<{ enabled: boolean }>("/sadhna/reminders", {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({ enabled }),
|
||||
}),
|
||||
|
||||
/** Report the browser's IANA timezone so reminders fire at local time. */
|
||||
setTimezone: (timezone: string) =>
|
||||
call<void>("/sadhna/timezone", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ timezone }),
|
||||
}),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user