diff --git a/src/lib/components/shell/PeriodPicker.svelte b/src/lib/components/shell/PeriodPicker.svelte index 515aac7..b21c42e 100644 --- a/src/lib/components/shell/PeriodPicker.svelte +++ b/src/lib/components/shell/PeriodPicker.svelte @@ -4,13 +4,13 @@ import ChevronRight from "@lucide/svelte/icons/chevron-right"; import { Popover } from "bits-ui"; import { period } from "#lib/period.svelte.js"; + import { ui } from "#lib/ui.svelte.js"; - let open = $state(false); let start = $state(period.start); let end = $state(period.end); $effect(() => { - if (open) { + if (ui.periodOpen) { ({ start, end } = period); } }); @@ -19,7 +19,7 @@ event.preventDefault(); if (start && end && start <= end) { period.set({ end, start }); - open = false; + ui.periodOpen = false; } } @@ -34,7 +34,7 @@ > - + { period.set(preset.range); - open = false; + ui.periodOpen = false; }} type="button" > {preset.label} + {#if preset.key || preset.hint} + {preset.key ? `p ${preset.key}` : preset.hint} + {/if} {/each} @@ -76,6 +81,7 @@ Start diff --git a/src/lib/components/shell/Shell.svelte b/src/lib/components/shell/Shell.svelte index 2a42e84..5e2e22c 100644 --- a/src/lib/components/shell/Shell.svelte +++ b/src/lib/components/shell/Shell.svelte @@ -36,6 +36,18 @@ } }); + function setPreset(key: string | undefined) { + const preset = period.presets().find((item) => item.key === key); + if (preset) { + period.set(preset.range); + } + } + + function openCustomPeriod() { + ui.periodOpen = true; + setTimeout(() => document.getElementById("period-start")?.focus(), 50); + } + function openOld(sticky = false) { location.assign(oldUiUrl(page.url.href, sticky)); } @@ -148,6 +160,27 @@ label: "Current period", run: () => period.reset(), }, + { + group: "Period", + keys: "p p", + label: "Choose a period", + run: () => (ui.periodOpen = true), + }, + { + group: "Period", + keys: "p c", + label: "Custom period: type the dates", + run: openCustomPeriod, + }, + ...period + .presets() + .filter((preset) => preset.key) + .map((preset) => ({ + group: "Period", + keys: `p ${preset.key}`, + label: `Period: ${preset.label}`, + run: () => setPreset(preset.key), + })), { group: "Global", hidden: true, diff --git a/src/lib/components/subscriptions/Runway.svelte b/src/lib/components/subscriptions/Runway.svelte index 0694a2e..85b9e18 100644 --- a/src/lib/components/subscriptions/Runway.svelte +++ b/src/lib/components/subscriptions/Runway.svelte @@ -122,7 +122,7 @@ onclick={() => byCurrency || onmode()} type="button" > - By currencyp + By currencyv diff --git a/src/lib/period.svelte.ts b/src/lib/period.svelte.ts index ece5428..b9bb780 100644 --- a/src/lib/period.svelte.ts +++ b/src/lib/period.svelte.ts @@ -15,6 +15,8 @@ const STORAGE_KEY = "ffui.period"; const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/; export interface Preset { + hint?: string; + key?: string; label: string; range: Range; } @@ -113,31 +115,44 @@ class Period { if (!isDynamic(view)) { const prev = shiftPeriod(this.range, view, -1); const next = shiftPeriod(this.range, view, 1); - presets.push({ label: periodLabel(prev, view), range: prev }); - presets.push({ label: periodLabel(next, view), range: next }); + presets.push({ hint: "[", label: periodLabel(prev, view), range: prev }); + presets.push({ hint: "]", label: periodLabel(next, view), range: next }); } const current = periodOf(now, view); presets.push({ + key: "t", label: `Today (${periodLabel(current, view)})`, range: current, }); presets.push({ + key: "7", label: "Last seven days", range: { end: now, start: addDays(now, -7) }, }); presets.push({ + key: "3", label: "Last thirty days", range: { end: now, start: addDays(now, -30) }, }); - presets.push({ label: "Month to date", range: periodOf(now, "MTD") }); - presets.push({ label: "Year to date", range: periodOf(now, "YTD") }); + presets.push({ + key: "m", + label: "Month to date", + range: periodOf(now, "MTD"), + }); + presets.push({ + key: "y", + label: "Year to date", + range: periodOf(now, "YTD"), + }); const year = Number(now.slice(0, 4)) - 1; presets.push({ + key: "l", label: `Previous year (${year})`, range: { end: `${year}-12-31`, start: `${year}-01-01` }, }); if (this.first) { presets.push({ + key: "a", label: "Everything", range: { end: now, start: this.first }, }); diff --git a/src/lib/ui.svelte.ts b/src/lib/ui.svelte.ts index 6d0723a..3d88390 100644 --- a/src/lib/ui.svelte.ts +++ b/src/lib/ui.svelte.ts @@ -11,6 +11,7 @@ class Ui { palette = $state(false); paletteQuery = $state(""); quickEntry = $state(false); + periodOpen = $state(false); mobileNav = $state(false); collapsed = $state(stored(SIDEBAR_KEY)); notes = $state(stored(NOTES_KEY)); diff --git a/src/routes/currencies/+page.svelte b/src/routes/currencies/+page.svelte index c3748a4..2ffe890 100644 --- a/src/routes/currencies/+page.svelte +++ b/src/routes/currencies/+page.svelte @@ -78,7 +78,7 @@ }, { group: "Currencies", - keys: "p", + keys: "P", label: "Make primary currency", run: () => nav.current && makePrimary(nav.current), }, @@ -203,7 +203,7 @@ makePrimary(item)}> Make primary - p + P remove(item)} /> {/if} diff --git a/src/routes/subscriptions/+page.svelte b/src/routes/subscriptions/+page.svelte index 2dddd3c..8136a76 100644 --- a/src/routes/subscriptions/+page.svelte +++ b/src/routes/subscriptions/+page.svelte @@ -296,7 +296,7 @@ })), { group: "Runway", - keys: "p", + keys: "v", label: perCurrency ? "Group by card" : "Group by currency", run: toggleMode, },