chore: dependency updates and UI fixes (batch)

This commit is contained in:
null 2026-06-07 14:23:19 -05:00
parent 3b0f267ab3
commit 6d60eebe1a
5 changed files with 857 additions and 114 deletions

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useActionState, useEffect, useState } from 'react';
import { ChevronDown, Copy, Layers, Link2, Link2Off, Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
@ -172,7 +172,6 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
);
const [saveTemplate, setSaveTemplate] = useState(false);
const [templateName, setTemplateName] = useState('');
const [busy, setBusy] = useState(false);
const [errors, setErrors] = useState({});
const [payments, setPayments] = useState([]);
const [paymentsLoading, setPaymentsLoading] = useState(false);
@ -508,9 +507,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
}
}
async function handleSubmit(e) {
e.preventDefault();
const [, submitAction, isPending] = useActionState(async () => {
if (!validateForm()) {
toast.error('Please fix the form errors before saving.');
return;
@ -560,7 +557,6 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
snowball_include: snowballInclude,
snowball_exempt: snowballExempt,
};
setBusy(true);
try {
let savedBill;
if (isNew) {
@ -583,10 +579,8 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
onClose();
} catch (err) {
toast.error(err.message);
} finally {
setBusy(false);
}
}
}, null);
const inp = 'bg-background/50 border-border/60 h-9 text-sm w-full';
@ -599,7 +593,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
</DialogTitle>
</DialogHeader>
<form id="bill-modal-form" onSubmit={handleSubmit}>
<form id="bill-modal-form" action={submitAction}>
<div className="grid gap-x-5 gap-y-4 py-2 sm:grid-cols-2">
{/* Name */}
@ -1325,7 +1319,7 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
<Button
type="button"
variant="outline"
disabled={busy}
disabled={isPending}
onClick={() => onDuplicate(bill)}
className="gap-2 text-xs"
>
@ -1334,10 +1328,11 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
</Button>
)}
<div className="flex gap-2">
<Button type="button" variant="ghost" disabled={busy} onClick={onClose} className="text-xs">
<Button type="button" variant="ghost" disabled={isPending} onClick={onClose} className="text-xs">
Cancel
</Button>
<Button type="submit" form="bill-modal-form" disabled={busy} className="text-xs">
<Button type="submit" form="bill-modal-form" disabled={isPending} className="gap-1.5 text-xs">
{isPending && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
{isNew ? 'Add Bill' : 'Save Changes'}
</Button>
</div>

View File

@ -1,21 +0,0 @@
import { useCallback, useEffect, useState } from 'react';
/**
* Polyfill for React 19's useOptimistic.
* Shows optimistic state immediately; reconciles when passthrough changes.
*/
export function useOptimistic(passthrough, reducer) {
const [optimistic, setOptimistic] = useState(passthrough);
// Whenever the server-confirmed state lands, sync it in.
useEffect(() => {
setOptimistic(passthrough);
}, [passthrough]);
const dispatch = useCallback(
action => setOptimistic(current => reducer(current, action)),
[reducer],
);
return [optimistic, dispatch];
}

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useOptimistic, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import { toast } from 'sonner';
import {
@ -48,7 +48,6 @@ import BillModal from '@/components/BillModal';
import BillHistoricalImportDialog from '@/components/BillHistoricalImportDialog';
import { getLinkImportPref } from '@/pages/SettingsPage';
import { useSearchPanelPreference } from '@/hooks/useSearchPanelPreference';
import { useOptimistic } from '@/hooks/useOptimistic';
import { useVirtualizer } from '@tanstack/react-virtual';
import { moveInArray, movedItemId, reorderPayload } from '@/lib/reorder';

922
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -45,8 +45,8 @@
"openid-client": "^5.7.1",
"otplib": "^13.4.1",
"qrcode": "^1.5.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-markdown": "^10.1.0",
"react-router-dom": "^6.26.2",
"rehype-sanitize": "^6.0.0",