From 20203942d21c6e984ab5f21250ffe68604da9f38 Mon Sep 17 00:00:00 2001 From: efrilm Date: Fri, 12 Sep 2025 21:03:38 +0700 Subject: [PATCH] Cash Bank List --- src/views/apps/cash-bank/CashBankList.tsx | 429 ++++++++++------------ 1 file changed, 203 insertions(+), 226 deletions(-) diff --git a/src/views/apps/cash-bank/CashBankList.tsx b/src/views/apps/cash-bank/CashBankList.tsx index 92aa8f5..ffda00a 100644 --- a/src/views/apps/cash-bank/CashBankList.tsx +++ b/src/views/apps/cash-bank/CashBankList.tsx @@ -11,16 +11,18 @@ import FormControl from '@mui/material/FormControl' import InputLabel from '@mui/material/InputLabel' import Select from '@mui/material/Select' import MenuItem from '@mui/material/MenuItem' +import CircularProgress from '@mui/material/CircularProgress' import CashBankCard from './CashBankCard' // Adjust import path as needed import CustomTextField from '@/@core/components/mui/TextField' import { getLocalizedUrl } from '@/utils/i18n' import { Locale } from '@/configs/i18n' import { useParams } from 'next/navigation' -import AccountFormDrawer, { AccountType } from '../account/AccountFormDrawer' -import { accountsData } from '../account/AccountListTable' +import AccountFormDrawer from '../account/AccountFormDrawer' import { Button } from '@mui/material' +import { Account } from '@/types/services/chartOfAccount' +import { useAccounts } from '@/services/queries/account' +import { formatCurrency } from '@/utils/transform' -// Types interface BankAccount { id: string title: string @@ -41,188 +43,28 @@ interface BankAccount { status: 'active' | 'inactive' | 'blocked' } -// Dummy Data -const dummyAccounts: BankAccount[] = [ - { - id: '1', - title: 'Giro', - accountNumber: '1-10003', - balances: [ - { amount: '7.313.321', label: 'Saldo di bank' }, - { amount: '30.631.261', label: 'Saldo di kledo' } - ], - chartData: [ - { - name: 'Saldo', - data: [ - 20000000, 21000000, 20500000, 20800000, 21500000, 22000000, 25000000, 26000000, 28000000, 29000000, 30000000, - 31000000 - ] - } - ], - categories: ['Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des', 'Jan', 'Feb', 'Mar'], - chartColor: '#ff6b9d', - currency: 'IDR', - accountType: 'giro', - bank: 'Bank Mandiri', - status: 'active' - }, - { - id: '2', - title: 'Tabungan Premium', - accountNumber: 'SAV-001234', - balances: [ - { amount: 15420000, label: 'Saldo Tersedia' }, - { amount: 18750000, label: 'Total Saldo' } - ], - chartData: [ - { - name: 'Balance', - data: [ - 12000000, 13500000, 14200000, 15000000, 15800000, 16200000, 17000000, 17500000, 18000000, 18200000, 18500000, - 18750000 - ] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], - chartColor: '#4285f4', - currency: 'IDR', - accountType: 'savings', - bank: 'Bank BCA', - status: 'active' - }, - { - id: '3', - title: 'Investment Portfolio', - accountNumber: 'INV-789012', - balances: [ - { amount: 125000, label: 'Portfolio Value' }, - { amount: 8750, label: 'Total Gains' } - ], - chartData: [ - { - name: 'Portfolio Value', - data: [110000, 115000, 112000, 118000, 122000, 119000, 125000, 128000, 126000, 130000, 127000, 125000] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], - currency: 'USD', - accountType: 'investment', - bank: 'Charles Schwab', - status: 'active' - }, - { - id: '4', - title: 'Kartu Kredit Platinum', - accountNumber: 'CC-456789', - balances: [ - { amount: 2500000, label: 'Saldo Saat Ini' }, - { amount: 47500000, label: 'Limit Tersedia' } - ], - chartData: [ - { - name: 'Spending', - data: [ - 1200000, 1800000, 2200000, 1900000, 2100000, 2400000, 2800000, 2600000, 2300000, 2500000, 2700000, 2500000 - ] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], - currency: 'IDR', - accountType: 'credit', - bank: 'Bank BNI', - status: 'active' - }, - { - id: '5', - title: 'Deposito Berjangka', - accountNumber: 'DEP-334455', - balances: [ - { amount: 50000000, label: 'Pokok Deposito' }, - { amount: 2500000, label: 'Bunga Terkumpul' } - ], - chartData: [ - { - name: 'Deposito Growth', - data: [ - 50000000, 50200000, 50420000, 50650000, 50880000, 51120000, 51360000, 51610000, 51860000, 52120000, 52380000, - 52500000 - ] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], - currency: 'IDR', - accountType: 'savings', - bank: 'Bank BRI', - status: 'active' - }, - { - id: '6', - title: 'Cash Management', - accountNumber: 'CSH-111222', - balances: [{ amount: 5000, label: 'Available Cash' }], - chartData: [ - { - name: 'Cash Flow', - data: [4000, 4500, 4200, 4800, 5200, 4900, 5000, 5300, 5100, 5400, 5200, 5000] - } - ], - categories: ['Q1', 'Q2', 'Q3', 'Q4', 'Q1', 'Q2', 'Q3', 'Q4', 'Q1', 'Q2', 'Q3', 'Q4'], - chartColor: '#00bcd4', - currency: 'USD', - accountType: 'cash', - bank: 'Wells Fargo', - status: 'active' - }, - { - id: '7', - title: 'Rekening Bisnis', - accountNumber: 'BIZ-998877', - balances: [ - { amount: 85000000, label: 'Saldo Operasional' }, - { amount: 15000000, label: 'Dana Cadangan' } - ], - chartData: [ - { - name: 'Business Account', - data: [ - 70000000, 75000000, 80000000, 82000000, 85000000, 88000000, 90000000, 87000000, 85000000, 89000000, 92000000, - 100000000 - ] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], - chartColor: '#ff9800', - currency: 'IDR', - accountType: 'giro', - bank: 'Bank Mandiri', - status: 'active' - }, - { - id: '8', - title: 'Tabungan Pendidikan', - accountNumber: 'EDU-567890', - balances: [ - { amount: 25000000, label: 'Dana Pendidikan' }, - { amount: 3500000, label: 'Bunga Terkumpul' } - ], - chartData: [ - { - name: 'Education Savings', - data: [ - 20000000, 21000000, 22000000, 23000000, 24000000, 24500000, 25000000, 25500000, 26000000, 27000000, 28000000, - 28500000 - ] - } - ], - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], - chartColor: '#3f51b5', - currency: 'IDR', - accountType: 'savings', - bank: 'Bank BCA', - status: 'inactive' +// Static chart data for fallback/demo purposes +const generateChartData = (accountType: string, balance: number) => { + const baseValue = balance || 1000000 + const variation = baseValue * 0.2 + + return Array.from({ length: 12 }, (_, i) => { + const randomVariation = (Math.random() - 0.5) * variation + return Math.max(baseValue + randomVariation, baseValue * 0.5) + }) +} + +const getChartColor = (accountType: string) => { + const colors = { + giro: '#ff6b9d', + savings: '#4285f4', + investment: '#00bcd4', + credit: '#ff9800', + cash: '#4caf50' } -] + return colors[accountType as keyof typeof colors] || '#757575' +} + const DebouncedInput = ({ value: initialValue, onChange, @@ -251,28 +93,122 @@ const DebouncedInput = ({ return setValue(e.target.value)} /> } + const CashBankList = () => { const [searchQuery, setSearchQuery] = useState('') - const [editingAccount, setEditingAccount] = useState(null) + const [editingAccount, setEditingAccount] = useState(null) const [addAccountOpen, setAddAccountOpen] = useState(false) - const [data, setData] = useState(accountsData) + const [data, setData] = useState([]) const { lang: locale } = useParams() + // Use the accounts hook with search parameter + const { data: accountsResponse, isLoading } = useAccounts({ + page: 1, + limit: 10, + search: searchQuery + }) + const handleCloseDrawer = () => { setAddAccountOpen(false) setEditingAccount(null) } - // Filter and search logic + // Transform API data to match our BankAccount interface + const transformedAccounts = useMemo((): BankAccount[] => { + if (!accountsResponse?.data) return [] + + return accountsResponse.data.map((account: Account) => { + const chartData = generateChartData(account.account_type, account.current_balance) + + // Map account type to display type + const typeMapping = { + current_asset: 'giro' as const, + non_current_asset: 'investment' as const, + current_liability: 'credit' as const, + non_current_liability: 'credit' as const, + other_current_asset: 'cash' as const, + other_current_liability: 'credit' as const, + equity: 'savings' as const, + revenue: 'savings' as const, + expense: 'cash' as const + } + const displayAccountType = typeMapping[account.account_type as keyof typeof typeMapping] || 'giro' + + // Get bank name from account + const getBankName = (acc: Account): string => { + if (acc.chart_of_account?.name) { + return acc.chart_of_account.name + } + + const typeToBank = { + current_asset: 'Bank Account', + non_current_asset: 'Investment Account', + current_liability: 'Credit Account', + other_current_asset: 'Cash Account', + equity: 'Equity Account', + revenue: 'Revenue Account', + expense: 'Expense Account' + } + + return typeToBank[acc.account_type as keyof typeof typeToBank] || 'General Account' + } + + // Create balance information + const balances = [] + + if (account.current_balance !== account.opening_balance) { + balances.push({ + amount: formatCurrency(account.current_balance), + label: 'Saldo Saat Ini' + }) + balances.push({ + amount: formatCurrency(account.opening_balance), + label: 'Saldo Awal' + }) + } else { + balances.push({ + amount: formatCurrency(account.current_balance), + label: 'Saldo' + }) + } + + return { + id: account.id, + title: account.name, + accountNumber: account.number, + balances, + chartData: [ + { + name: 'Saldo', + data: chartData + } + ], + categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'], + chartColor: getChartColor(account.account_type), + currency: 'IDR', // Assuming IDR as default, adjust as needed + accountType: displayAccountType, + bank: getBankName(account), + status: account.is_active ? 'active' : 'inactive' + } + }) + }, [accountsResponse]) + + // Filter accounts based on search (if not handled by API) const filteredAccounts = useMemo(() => { - return dummyAccounts.filter(account => { + if (!searchQuery || accountsResponse) { + // If using API search or no search, return transformed accounts as is + return transformedAccounts + } + + // Local filtering fallback + return transformedAccounts.filter(account => { const matchesSearch = account.title.toLowerCase().includes(searchQuery.toLowerCase()) || account.accountNumber.toLowerCase().includes(searchQuery.toLowerCase()) || account.bank.toLowerCase().includes(searchQuery.toLowerCase()) return matchesSearch }) - }, [searchQuery]) + }, [transformedAccounts, searchQuery, accountsResponse]) return ( <> @@ -283,8 +219,16 @@ const CashBankList = () => { setSearchQuery(value as string)} - placeholder='Cari ' + placeholder='Cari akun...' className='max-sm:is-full' + disabled={isLoading} + InputProps={{ + startAdornment: ( + + + + ) + }} /> @@ -302,45 +247,77 @@ const CashBankList = () => { + {/* Loading State */} + {isLoading && ( + + + + )} + {/* Account Cards */} - - {filteredAccounts.length > 0 ? ( - filteredAccounts.map(account => ( - - + {!isLoading && ( + + {filteredAccounts.length > 0 ? ( + filteredAccounts.map(account => ( + + + + )) + ) : ( + + + + {searchQuery ? 'Tidak ada akun yang ditemukan' : 'Belum ada akun'} + + + {searchQuery + ? 'Coba ubah kata kunci pencarian yang digunakan' + : 'Mulai dengan menambahkan akun baru'} + + - )) - ) : ( - - - - Tidak ada akun yang ditemukan - - - Coba ubah kata kunci pencarian atau filter yang digunakan - - - - )} - + )} + + )} + + {/* Error State (if needed) */} + {!isLoading && !accountsResponse && ( + + + + Terjadi kesalahan saat memuat data + + Silakan coba lagi atau hubungi administrator + + + )} +