diff --git a/client/components/CommandPalette.jsx b/client/components/CommandPalette.tsx similarity index 91% rename from client/components/CommandPalette.jsx rename to client/components/CommandPalette.tsx index 22d5201..9dc09e6 100644 --- a/client/components/CommandPalette.jsx +++ b/client/components/CommandPalette.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef, useState, type ComponentType } from 'react'; import { useNavigate } from 'react-router-dom'; import { BarChart2, Calendar, CreditCard, Loader2, Navigation, Plus, @@ -7,20 +7,29 @@ import { } from 'lucide-react'; import { toast } from 'sonner'; import { api } from '@/api'; -import { cn, fmt } from '@/lib/utils'; +import { cn, fmt, errMessage } from '@/lib/utils'; import { scheduleLabel, scheduleValue } from '@/lib/billingSchedule'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; +import type { Bill } from '@/types'; // ─── Navigation commands ────────────────────────────────────────────────────── +interface Command { + id: string; + label: string; + icon: ComponentType<{ className?: string }>; + path: string; + group: string; +} + const MONTHS = [ 'January','February','March','April','May','June', 'July','August','September','October','November','December', ]; -const NAV_COMMANDS = [ +const NAV_COMMANDS: Command[] = [ { id: 'nav-tracker', label: 'Go to Tracker', icon: Receipt, path: '/', group: 'Navigate' }, { id: 'nav-bills', label: 'Go to Bills', icon: CreditCard, path: '/bills', group: 'Navigate' }, { id: 'nav-calendar', label: 'Go to Calendar', icon: Calendar, path: '/calendar', group: 'Navigate' }, @@ -39,10 +48,10 @@ const NAV_COMMANDS = [ ]; // Generate jump-to-month commands for the current year ± 1 -function buildMonthCommands() { +function buildMonthCommands(): Command[] { const now = new Date(); const year = now.getFullYear(); - const commands = []; + const commands: Command[] = []; for (let y = year - 1; y <= year + 1; y++) { for (let m = 1; m <= 12; m++) { commands.push({ @@ -59,7 +68,7 @@ function buildMonthCommands() { // ─── Helpers ────────────────────────────────────────────────────────────────── -function amountSearchText(...values) { +function amountSearchText(...values: unknown[]): string { return values .filter(value => value !== null && value !== undefined && Number.isFinite(Number(value))) .flatMap(value => { @@ -69,7 +78,7 @@ function amountSearchText(...values) { .join(' '); } -function billSearchText(bill) { +function billSearchText(bill: Bill): string { return [ bill.name, bill.category_name, @@ -87,7 +96,7 @@ function billSearchText(bill) { ].filter(Boolean).join(' ').toLowerCase(); } -function shortcutLabel() { +function shortcutLabel(): string { if (typeof navigator !== 'undefined' && /Mac|iPhone|iPad|iPod/i.test(navigator.platform)) { return 'Cmd K'; } @@ -96,7 +105,11 @@ function shortcutLabel() { // ─── Result item components ─────────────────────────────────────────────────── -function BillResult({ bill, onOpenBills, onOpenTracker }) { +function BillResult({ bill, onOpenBills, onOpenTracker }: { + bill: Bill; + onOpenBills: (bill: Bill) => void; + onOpenTracker: (bill: Bill) => void; +}) { return (
{bill.category_name || 'Uncategorized'} Due {bill.due_day} - {fmt(bill.expected_amount || 0)} + {fmt(bill.expected_amount)} @@ -140,7 +153,7 @@ function BillResult({ bill, onOpenBills, onOpenTracker }) { ); } -function CommandResult({ cmd, onRun }) { +function CommandResult({ cmd, onRun }: { cmd: Command; onRun: (cmd: Command) => void }) { const Icon = cmd.icon || Navigation; return (