Complete UI foundation and app layout implementation, stabilize container health checks, and archive both OpenSpec changes after verification.
62 lines
1.9 KiB
Svelte
62 lines
1.9 KiB
Svelte
<script context="module" lang="ts">
|
|
export function formatMonth(period: string): string {
|
|
const [year, month] = period.split('-').map(Number);
|
|
const date = new Date(year, month - 1, 1);
|
|
return date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
|
|
}
|
|
|
|
export function generateMonthOptions(baseDate = new Date()): string[] {
|
|
const options: string[] = [];
|
|
for (let i = -6; i <= 6; i += 1) {
|
|
const date = new Date(baseDate.getFullYear(), baseDate.getMonth() + i, 1);
|
|
options.push(`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`);
|
|
}
|
|
return options;
|
|
}
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-svelte';
|
|
import {
|
|
currentMonth,
|
|
nextMonth,
|
|
previousMonth,
|
|
selectedPeriod,
|
|
setPeriod
|
|
} from '$lib/stores/period';
|
|
|
|
const monthOptions = generateMonthOptions();
|
|
$: displayMonth = formatMonth($selectedPeriod);
|
|
</script>
|
|
|
|
<div class="dropdown dropdown-end" data-testid="month-selector">
|
|
<button class="btn btn-sm btn-ghost gap-1" aria-label="Select month">
|
|
<span class="font-medium">{displayMonth}</span>
|
|
<ChevronDown size={16} />
|
|
</button>
|
|
|
|
<ul class="menu menu-sm dropdown-content mt-2 z-30 w-48 rounded-box bg-base-100 p-2 shadow-lg border border-base-300">
|
|
<li>
|
|
<button class="justify-between" on:click={previousMonth}>
|
|
<span>Previous</span>
|
|
<ChevronLeft size={16} />
|
|
</button>
|
|
</li>
|
|
<li><button on:click={currentMonth}>Today</button></li>
|
|
<li>
|
|
<button class="justify-between" on:click={nextMonth}>
|
|
<span>Next</span>
|
|
<ChevronRight size={16} />
|
|
</button>
|
|
</li>
|
|
<li><hr class="my-1 border-base-300" /></li>
|
|
{#each monthOptions as option}
|
|
<li>
|
|
<button class:active={option === $selectedPeriod} on:click={() => setPeriod(option)}>
|
|
{formatMonth(option)}
|
|
</button>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
</div>
|