diff --git a/src/routes/(app)/habits/+page.svelte b/src/routes/(app)/habits/+page.svelte new file mode 100644 index 0000000..b11a300 --- /dev/null +++ b/src/routes/(app)/habits/+page.svelte @@ -0,0 +1,192 @@ + + +
+ +
+
+

Habits

+

Track your daily habits and build better routines

+
+ +
+ + + + + + + showCalendar = false} + class="rounded-md border shadow-sm" + /> + + + + + + + + + + { + showCreateDialog = false; + }} + /> + + +
+
+ + + + + {#if loading} + + + + + Habit Progress + + + Track your habits day by day. Click to mark as complete or update values. + + + + + + + + {:else if error} + + + + {error} + + + + {:else if habitService.habits.length === 0} + + +
+ +
+

No habits yet

+

+ Start building better routines by creating your first habit. Track daily activities and watch your progress grow. +

+ +
+
+ {:else} + + + +
+
+ + + Habit Progress + + + Track your habits day by day. Click to mark as complete or update values. + +
+ +
+
+ + + +
+ {/if} +
diff --git a/src/routes/(app)/habits/CounterHabitButton.svelte b/src/routes/(app)/habits/CounterHabitButton.svelte new file mode 100644 index 0000000..1d82548 --- /dev/null +++ b/src/routes/(app)/habits/CounterHabitButton.svelte @@ -0,0 +1,200 @@ + + + + diff --git a/src/routes/(app)/habits/HabitActionMenu.svelte b/src/routes/(app)/habits/HabitActionMenu.svelte new file mode 100644 index 0000000..1786356 --- /dev/null +++ b/src/routes/(app)/habits/HabitActionMenu.svelte @@ -0,0 +1,91 @@ + + + + + + + + Habit options + + currentHabit && habitService.updateHabit(currentHabit.id, { active: !currentHabit.active })}> + Active + + (editHabitDialog = true)}> + + Edit + + (deleteHabitDialog = true)}> +
+ +

Delete

+
+
+
+
+
+ + + + + + Edit profile + + Make changes to your profile here. Click save when you're done. + + +
+
+ + +
+
+ + +
+
+ + + +
+
+ + + + + + Are you sure? + + This action cannot be undone. This will permanently delete the habit "{currentHabit?.name || 'Unknown'}" + + + + Cancel + + + + + + diff --git a/src/routes/(app)/habits/HabitCellContextMenu.svelte b/src/routes/(app)/habits/HabitCellContextMenu.svelte new file mode 100644 index 0000000..be21ae3 --- /dev/null +++ b/src/routes/(app)/habits/HabitCellContextMenu.svelte @@ -0,0 +1,76 @@ + + + + + {@render children()} + + + + + Reset period + + + showSetValueDialog = true} class="gap-2"> + + Set value... + + + + + + + {cell.isFailed ? 'Mark as unfailed' : 'Mark as failed'} + + + + + \ No newline at end of file diff --git a/src/routes/(app)/habits/HabitCreationForm.svelte b/src/routes/(app)/habits/HabitCreationForm.svelte new file mode 100644 index 0000000..173af77 --- /dev/null +++ b/src/routes/(app)/habits/HabitCreationForm.svelte @@ -0,0 +1,231 @@ + + + + Create a new habit + + Add a new habit to track. Set your target and customize the tracking period. + + + +
+ +
+ + +

+ Give your habit a clear, specific name +

+
+ + +
+
+ + +

+ Daily goal to reach +

+
+ +
+ + +

+ How many days per period +

+
+
+ + +
+ + + {#if showAdvancedOptions} + + {:else} + + {/if} + Advanced Settings + + + + +
+
+ + +

+ Step size for tracking +

+
+ +
+ + +

+ Unit of measurement +

+
+
+ + +
+
+ + +

+ When to begin tracking +

+
+ +
+ +
+ + +
+

+ Enable habit tracking +

+
+
+
+
+
+
+ + + + + + + diff --git a/src/routes/(app)/habits/HabitGrid.svelte b/src/routes/(app)/habits/HabitGrid.svelte new file mode 100644 index 0000000..393462d --- /dev/null +++ b/src/routes/(app)/habits/HabitGrid.svelte @@ -0,0 +1,366 @@ + + + + +
+
+ {#if skeleton && containerWidth === 0} + +
+ {:else} +
+ + {#if skeleton} + +
+ + +
+ + {#each Array(numCellsInRow) as _, index (index)} +
+ +
+ {/each} + +
+ + +
+ {:else} + +
+ navigate(-(numCellsInRow - 1))} /> + navigate(-1)} /> +
+ + {#each displayedDates as date (date.toString())} +
+ {/each} + +
+ navigate(1)} /> + navigate(numCellsInRow - 1)} /> +
+ {/if} + + + {#if skeleton} + + {#each Array(3) as _, habitIndex (habitIndex)} + +
+ +
+ + + {#if habitIndex === 0} + + {#each Array(numCellsInRow) as _, cellIndex (cellIndex)} +
+ +
+ {/each} + {:else if habitIndex === 1} + + {#each Array(Math.floor(numCellsInRow / 3)) as _, periodIndex (periodIndex)} +
+ +
+ {/each} + + {#if numCellsInRow % 3 !== 0} +
+ +
+ {/if} + {:else} + + {#each Array(Math.floor(numCellsInRow / 2)) as _, periodIndex (periodIndex)} +
+ +
+ {/each} + + {#if numCellsInRow % 2 !== 0} +
+ +
+ {/if} + {/if} + + +
+ {/each} + {:else} + + {#each displayedHabits as habit (habit.id)} +
+ +
+ +
+ + + {habit.name} + +
+ + {#each createHabitCells(habit, displayedDates, numCellsInRow) as cell (`${habit.id}-${cell.date}-${cell.gridColumn}`)} +
+ {#if cell.isEmpty} +
+ {:else} + { await habitService.resetPeriodByDates(habit.id, cell.periodDates); }} + onSetValue={(totalValue, dailyValues) => habitService.setPeriodValue(habit.id, cell.periodDates, totalValue, dailyValues)} + onToggleFailed={() => habitService.togglePeriodFailed(habit.id, cell.periodDates, cell.isFailed)} + > + + + {/if} +
+ {/each} + + +
+ {/each} + {/if} +
+ {/if} +
+
\ No newline at end of file diff --git a/src/routes/(app)/habits/SetValueDialog.svelte b/src/routes/(app)/habits/SetValueDialog.svelte new file mode 100644 index 0000000..ade237a --- /dev/null +++ b/src/routes/(app)/habits/SetValueDialog.svelte @@ -0,0 +1,182 @@ + + + + + + Set Completion Value + + Set the total value for this period ({cell.periodDates.length} day{cell.periodDates.length !== 1 ? 's' : ''}) + + + +
+ +
+ + +
+ + + {#if cell.periodDates.length > 1} + + + {#if showAdvanced} + + {:else} + + {/if} + Advanced (set individual days) + + + +
+ {#each cell.periodDates as date (date)} +
+ + +
+ {/each} +
+ +

+ Individual day values will override the total above +

+
+
+ {/if} +
+ + + + + + + +
+
\ No newline at end of file