import { index, store, } from '@/actions/App/Http/Controllers/AccountBalanceController'; import { AmountInput } from '@/components/ui/amount-input'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import type { Account, AccountBalance } from '@/types/account'; import { __ } from '@/utils/i18n'; import { useEffect, useRef, useState } from 'react'; interface UpdateBalanceDialogProps { account: Account; open: boolean; onOpenChange: (open: boolean) => void; onSuccess?: () => void; } function getTodayDate(): string { const today = new Date(); return today.toISOString().split('T')[0]; } interface PaginatedBalanceResponse { data: AccountBalance[]; } export function UpdateBalanceDialog({ account, open, onOpenChange, onSuccess, }: UpdateBalanceDialogProps) { const [date, setDate] = useState(getTodayDate()); const [balance, setBalance] = useState(0); const [isSubmitting, setIsSubmitting] = useState(false); const [error, setError] = useState(null); const [isLoadingLastBalance, setIsLoadingLastBalance] = useState(false); const inputRef = useRef(null); useEffect(() => { async function fetchLastBalance() { if (!open) return; setIsLoadingLastBalance(true); try { const response = await fetch( index.url(account.id, { query: { page: '1' } }), { headers: { Accept: 'application/json', }, }, ); if (!response.ok) { throw new Error('Failed to fetch last balance'); } const data: PaginatedBalanceResponse = await response.json(); if (data.data.length > 0) { setBalance(data.data[0].balance); } else { setBalance(0); } } catch (err) { console.error('Failed to fetch last balance:', err); setBalance(0); } finally { setIsLoadingLastBalance(false); } } if (open) { setDate(getTodayDate()); setError(null); fetchLastBalance(); } }, [open, account.id]); useEffect(() => { if (open && !isLoadingLastBalance && inputRef.current) { setTimeout(() => { const input = inputRef.current; if (input) { input.focus(); // Use requestAnimationFrame to ensure selection happens after focus events requestAnimationFrame(() => { input.setSelectionRange(0, input.value.length); }); } }, 100); } }, [open, isLoadingLastBalance]); function handleOpenChange(newOpen: boolean) { onOpenChange(newOpen); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setIsSubmitting(true); setError(null); try { const response = await fetch(store.url(account.id), { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-XSRF-TOKEN': decodeURIComponent( document.cookie .split('; ') .find((row) => row.startsWith('XSRF-TOKEN=')) ?.split('=')[1] || '', ), Accept: 'application/json', }, body: JSON.stringify({ balance_date: date, balance: balance, }), }); if (!response.ok) { const data = await response.json(); throw new Error(data.message || 'Failed to update balance'); } handleOpenChange(false); onSuccess?.(); } catch (err) { setError( err instanceof Error ? err.message : 'Failed to update balance', ); } finally { setIsSubmitting(false); } } return ( {__('Update balance')} {__( 'Set the balance for this account on a specific date.', )}
{isLoadingLastBalance ? (
{__('Loading last balance...')}
) : ( )}
setDate(e.target.value)} required />
{error && (

{error}

)}
); }