3b9c179643
\ - Add HabitGrid component with a responsive calendar-style layout\\ - Support variable habit durations with period-based cell rendering\ - Add skeleton loading states for better UX during data fetching - Add CounterHabitButton component for cells with increment/decrement interactions\ - Create HabitCellContextMenu for period-based actions (reset, set values, fail) - Add HabitCreationForm for creating new habits\ - Add HabitActionMenu component for additional operations on habits (archive, delete, edit)\ - Add SetValueDialog component for editing the value of a cell
76 lines
1.9 KiB
Svelte
76 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
import * as ContextMenu from '$lib/components/ui/context-menu';
|
|
import { RotateCcw, SquarePen, CircleX } from '@lucide/svelte';
|
|
import SetValueDialog from './SetValueDialog.svelte';
|
|
import type { HabitWithCompletions } from '$lib/context/habits.svelte';
|
|
|
|
let {
|
|
habit,
|
|
cell,
|
|
children,
|
|
onResetPeriod,
|
|
onSetValue,
|
|
onToggleFailed
|
|
}: {
|
|
habit: HabitWithCompletions;
|
|
cell: {
|
|
value: number;
|
|
date: string;
|
|
span: number;
|
|
gridColumn: number;
|
|
isFailed: boolean;
|
|
isEmpty: boolean;
|
|
periodDates: string[];
|
|
};
|
|
children: import('svelte').Snippet;
|
|
onResetPeriod: () => Promise<void>;
|
|
onSetValue: (totalValue: number, dailyValues?: Record<string, number>) => Promise<void>;
|
|
onToggleFailed: () => Promise<void>;
|
|
} = $props();
|
|
|
|
let showSetValueDialog = $state(false);
|
|
|
|
async function handleResetPeriod() {
|
|
await onResetPeriod();
|
|
}
|
|
|
|
async function handleSetValue(totalValue: number, dailyValues?: Record<string, number>) {
|
|
await onSetValue(totalValue, dailyValues);
|
|
showSetValueDialog = false;
|
|
}
|
|
|
|
async function handleToggleFailed() {
|
|
await onToggleFailed();
|
|
}
|
|
</script>
|
|
|
|
<ContextMenu.Root>
|
|
<ContextMenu.Trigger class="w-full">
|
|
{@render children()}
|
|
</ContextMenu.Trigger>
|
|
<ContextMenu.Content class="w-48">
|
|
<ContextMenu.Item onclick={handleResetPeriod} class="gap-2">
|
|
<RotateCcw class="h-4 w-4" />
|
|
Reset period
|
|
</ContextMenu.Item>
|
|
|
|
<ContextMenu.Item onclick={() => showSetValueDialog = true} class="gap-2">
|
|
<SquarePen class="h-4 w-4" />
|
|
Set value...
|
|
</ContextMenu.Item>
|
|
|
|
<ContextMenu.Separator />
|
|
|
|
<ContextMenu.Item onclick={handleToggleFailed} class="gap-2">
|
|
<CircleX class="h-4 w-4" />
|
|
{cell.isFailed ? 'Mark as unfailed' : 'Mark as failed'}
|
|
</ContextMenu.Item>
|
|
</ContextMenu.Content>
|
|
</ContextMenu.Root>
|
|
|
|
<SetValueDialog
|
|
bind:open={showSetValueDialog}
|
|
{habit}
|
|
{cell}
|
|
onSetValue={handleSetValue}
|
|
/> |