added habits to work in db

This commit is contained in:
masongga
2026-05-23 19:46:33 -06:00
parent 9641b120e4
commit 1ce4d0d68f
4 changed files with 358 additions and 135 deletions

View File

@@ -154,18 +154,34 @@ export function HabitTracker({ mode = "daily" }: HabitTrackerProps) {
const [newHabitLabel, setNewHabitLabel] = useState("");
const [focusTopics, setFocusTopics] = useState<string[]>([]);
const [quizCompletedToday, setQuizCompletedToday] = useState(false);
const [error, setError] = useState<string | null>(null);
const [isReady, setIsReady] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const refresh = useCallback(() => {
setDailyTasks(getDailyTasks());
setCustomHabits(getCustomHabits());
setFocusTopics(getProfilePreferences().focusTopics);
setQuizCompletedToday(hasCompletedDailyQuizToday());
setIsReady(true);
const refresh = useCallback(async () => {
try {
setError(null);
const [tasks, customs] = await Promise.all([
getDailyTasks(),
getCustomHabits(),
]);
setDailyTasks(tasks);
setCustomHabits(customs);
setFocusTopics(getProfilePreferences().focusTopics);
setQuizCompletedToday(hasCompletedDailyQuizToday());
setIsReady(true);
} catch (refreshError) {
setError(
refreshError instanceof Error
? refreshError.message
: "Could not load habits.",
);
setIsReady(true);
}
}, []);
useEffect(() => {
refresh();
void refresh();
window.addEventListener(HABIT_PET_DATA_UPDATED_EVENT, refresh);
return () => {
@@ -173,17 +189,51 @@ export function HabitTracker({ mode = "daily" }: HabitTrackerProps) {
};
}, [refresh]);
const handleToggle = (habitId: string) => {
toggleHabitCompletion(habitId);
const handleToggle = async (habitId: string) => {
try {
setIsSaving(true);
setError(null);
await toggleHabitCompletion(habitId);
} catch (toggleError) {
setError(
toggleError instanceof Error
? toggleError.message
: "Could not update habit.",
);
} finally {
setIsSaving(false);
}
};
const handleAddHabit = () => {
addHabit(newHabitLabel);
setNewHabitLabel("");
const handleAddHabit = async () => {
try {
setIsSaving(true);
setError(null);
await addHabit(newHabitLabel);
setNewHabitLabel("");
} catch (addError) {
setError(
addError instanceof Error ? addError.message : "Could not add habit.",
);
} finally {
setIsSaving(false);
}
};
const handleRemoveHabit = (habitId: string) => {
removeHabit(habitId);
const handleRemoveHabit = async (habitId: string) => {
try {
setIsSaving(true);
setError(null);
await removeHabit(habitId);
} catch (removeError) {
setError(
removeError instanceof Error
? removeError.message
: "Could not remove habit.",
);
} finally {
setIsSaving(false);
}
};
if (!isReady) {
@@ -199,6 +249,8 @@ export function HabitTracker({ mode = "daily" }: HabitTrackerProps) {
if (mode === "manage") {
return (
<div className="flex flex-col gap-6">
{error ? <p className="text-sm text-red-500">{error}</p> : null}
<Card>
<CardHeader>
<CardTitle className="text-base">Custom habits</CardTitle>
@@ -213,15 +265,20 @@ export function HabitTracker({ mode = "daily" }: HabitTrackerProps) {
<Input
value={newHabitLabel}
placeholder="Add a custom habit"
disabled={isSaving}
onChange={(event) => setNewHabitLabel(event.target.value)}
onKeyDown={(event) => {
if (event.key === "Enter") {
event.preventDefault();
handleAddHabit();
void handleAddHabit();
}
}}
/>
<Button type="button" onClick={handleAddHabit}>
<Button
type="button"
disabled={isSaving || newHabitLabel.trim().length === 0}
onClick={() => void handleAddHabit()}
>
Add
</Button>
</div>
@@ -265,6 +322,7 @@ export function HabitTracker({ mode = "daily" }: HabitTrackerProps) {
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{error ? <p className="text-sm text-red-500">{error}</p> : null}
<DailyTaskList tasks={dailyTasks} onToggle={handleToggle} />
</CardContent>
</Card>