chore: dependency updates and UI fixes (batch)
This commit is contained in:
parent
3b0f267ab3
commit
6d60eebe1a
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue