import { store } from '@/actions/App/Http/Controllers/Settings/AccountController'; import { store as storeBank } from '@/actions/App/Http/Controllers/Settings/BankController'; import { IntegrationRequestsDrawer } from '@/components/integration-requests/integration-requests-drawer'; import { ConnectAccountDialog } from '@/components/open-banking/connect-account-dialog'; import { UpgradeDialog } from '@/components/subscription/upgrade-dialog'; import { Button } from '@/components/ui/button'; import { CreateButton } from '@/components/ui/create-button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { getCsrfToken } from '@/lib/csrf'; import { SharedData } from '@/types'; import { Account } from '@/types/account'; import type { BankingConnection } from '@/types/banking'; import { __ } from '@/utils/i18n'; import { router, usePage } from '@inertiajs/react'; import { Link2, PenLine } from 'lucide-react'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { AccountForm, AccountFormData } from './account-form'; type Mode = 'choice' | 'manual'; export function CreateAccountDialog({ onSuccess, trigger, }: { onSuccess?: () => void; trigger?: React.ReactNode; }) { const { auth, subscriptionsEnabled, accounts: sharedAccounts, bankingConnections: sharedConnections, } = usePage().props; const isFreePlan = subscriptionsEnabled && !auth?.hasProPlan; const sharedAccountsList = useMemo( () => (sharedAccounts as Account[]) || [], [sharedAccounts], ); const connections = useMemo( () => (sharedConnections as BankingConnection[]) || [], [sharedConnections], ); const availableLoanAccounts = useMemo( () => sharedAccountsList.filter((a) => a.type === 'loan'), [sharedAccountsList], ); const isFirstAccount = sharedAccountsList.length === 0; const [open, setOpen] = useState(false); const [mode, setMode] = useState('choice'); const [isSubmitting, setIsSubmitting] = useState(false); const [connectDialogOpen, setConnectDialogOpen] = useState(false); const [upgradeDialogOpen, setUpgradeDialogOpen] = useState(false); const [integrationDrawerOpen, setIntegrationDrawerOpen] = useState(false); const formDataRef = useRef({ displayName: '', bankId: null, type: null, currencyCode: null, customBank: null, balance: null, realEstate: null, loan: null, }); const handleFormChange = useCallback((data: AccountFormData) => { formDataRef.current = data; }, []); function handleOpenChange(newOpen: boolean) { setOpen(newOpen); if (!newOpen) { setMode('choice'); } } async function createBankAndGetId(): Promise { const customBank = formDataRef.current.customBank; if (!customBank) return null; const formData = new FormData(); formData.append('name', customBank.name); if (customBank.logo) { formData.append('logo', customBank.logo); } try { const response = await fetch(storeBank.url(), { method: 'POST', body: formData, headers: { 'X-XSRF-TOKEN': getCsrfToken(), Accept: 'application/json', }, }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'Failed to create bank'); } const data = await response.json(); return data.id; } catch (err) { console.error('Failed to create bank:', err); throw err; } } async function handleSubmit(event: React.FormEvent) { event.preventDefault(); const { displayName, bankId, type, currencyCode, customBank } = formDataRef.current; if (!type || !currencyCode) { alert('Please fill in all required fields.'); return; } const isRealEstate = type === 'real_estate'; setIsSubmitting(true); try { let finalBankId: string | null = null; if (!isRealEstate) { if (customBank) { if (!customBank.name.trim()) { alert('Please enter a bank name.'); setIsSubmitting(false); return; } const createdBankId = await createBankAndGetId(); if (!createdBankId) { throw new Error('Failed to create bank'); } finalBankId = createdBankId; } else { if (!bankId) { alert('Please select a bank.'); setIsSubmitting(false); return; } finalBankId = String(bankId); } } router.post( store.url(), { name: displayName, ...(finalBankId ? { bank_id: finalBankId } : {}), type: type, currency_code: currencyCode, ...(formDataRef.current.balance ? { balance: formDataRef.current.balance } : {}), ...(formDataRef.current.realEstate ? { property_type: formDataRef.current.realEstate.propertyType, address: formDataRef.current.realEstate.address || null, purchase_price: formDataRef.current.realEstate .purchasePrice || null, purchase_date: formDataRef.current.realEstate.purchaseDate || null, area_value: formDataRef.current.realEstate.areaValue || null, area_unit: formDataRef.current.realEstate.areaUnit, linked_loan_account_id: formDataRef.current.realEstate .linkedLoanAccountId, notes: formDataRef.current.realEstate.notes || null, revaluation_percentage: formDataRef.current.realEstate .revaluationPercentage || null, } : {}), ...(formDataRef.current.loan ? { annual_interest_rate: formDataRef.current.loan.annualInterestRate || null, loan_term_months: formDataRef.current.loan.loanTermMonths || null, loan_start_date: formDataRef.current.loan.startDate || null, original_amount: formDataRef.current.loan.originalAmount || null, linked_real_estate_account_id: formDataRef.current.loan .linkedRealEstateAccountId, } : {}), }, { onSuccess: () => { handleOpenChange(false); onSuccess?.(); }, onFinish: () => { setIsSubmitting(false); }, }, ); } catch (err) { console.error('Submission failed:', err); alert( err instanceof Error ? err.message : 'Failed to create account. Please try again.', ); setIsSubmitting(false); } } return ( <> {trigger ?? ( {__('Create Account')} )} {__('Create Account')} {mode === 'choice' ? __( 'Add a bank account, loan, or property to your workspace.', ) : __( 'Create a bank account, loan, or property to track it manually.', )} {mode === 'choice' && (
)} {mode === 'manual' && (
)}
); }