Get Account

This commit is contained in:
efrilm 2025-09-12 19:51:35 +07:00
parent 27fe48e99e
commit 2d69a024c1
3 changed files with 92 additions and 181 deletions

View File

@ -0,0 +1,36 @@
import { useQuery } from '@tanstack/react-query'
import { api } from '../api'
import { Accounts } from '@/types/services/chartOfAccount'
interface AccountQueryParams {
page?: number
limit?: number
search?: string
}
export function useAccounts(params: AccountQueryParams = {}) {
const { page = 1, limit = 10, search = '', ...filters } = params
return useQuery<Accounts>({
queryKey: ['accounts', { page, limit, search, ...filters }],
queryFn: async () => {
const queryParams = new URLSearchParams()
queryParams.append('page', page.toString())
queryParams.append('limit', limit.toString())
if (search) {
queryParams.append('search', search)
}
Object.entries(filters).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
queryParams.append(key, value.toString())
}
})
const res = await api.get(`/accounts?${queryParams.toString()}`)
return res.data.data
}
})
}

View File

@ -37,3 +37,28 @@ export interface ChartOfAccounts {
page: number
total: number
}
export interface Account {
id: string
organization_id: string
outlet_id: string
chart_of_account_id: string
name: string
number: string
account_type: string
opening_balance: number
current_balance: number
description: string
is_active: true
is_system: false
created_at: string
updated_at: string
chart_of_account: ChartOfAccount
}
export interface Accounts {
data: Account[]
limit: number
page: number
total: number
}

View File

@ -41,6 +41,11 @@ import TablePaginationComponent from '@/components/TablePaginationComponent'
import Loading from '@/components/layout/shared/Loading'
import { getLocalizedUrl } from '@/utils/i18n'
import AccountFormDrawer from './AccountFormDrawer'
import { useChartOfAccount } from '@/services/queries/chartOfAccount'
import { Account, ChartOfAccount } from '@/types/services/chartOfAccount'
import { useAccounts } from '@/services/queries/account'
import { formatCurrency } from '@/utils/transform'
import { useChartOfAccountTypes } from '@/services/queries/chartOfAccountType'
// Account Type
export type AccountType = {
@ -60,119 +65,10 @@ declare module '@tanstack/table-core' {
}
}
type AccountTypeWithAction = AccountType & {
type AccountTypeWithAction = Account & {
actions?: string
}
// Dummy Account Data
export const accountsData: AccountType[] = [
{
id: 1,
code: '1-10001',
name: 'Kas',
category: 'Kas & Bank',
balance: '20000000'
},
{
id: 2,
code: '1-10002',
name: 'Bank BCA',
category: 'Kas & Bank',
balance: '150000000'
},
{
id: 3,
code: '1-10003',
name: 'Bank Mandiri',
category: 'Kas & Bank',
balance: '75000000'
},
{
id: 4,
code: '1-10101',
name: 'Piutang Usaha',
category: 'Piutang',
balance: '50000000'
},
{
id: 5,
code: '1-10102',
name: 'Piutang Karyawan',
category: 'Piutang',
balance: '5000000'
},
{
id: 6,
code: '1-10201',
name: 'Persediaan Barang',
category: 'Persediaan',
balance: '100000000'
},
{
id: 7,
code: '1-10301',
name: 'Peralatan Kantor',
category: 'Aset Tetap',
balance: '25000000'
},
{
id: 8,
code: '1-10302',
name: 'Kendaraan',
category: 'Aset Tetap',
balance: '200000000'
},
{
id: 9,
code: '2-20001',
name: 'Hutang Usaha',
category: 'Hutang',
balance: '-30000000'
},
{
id: 10,
code: '2-20002',
name: 'Hutang Gaji',
category: 'Hutang',
balance: '-15000000'
},
{
id: 11,
code: '3-30001',
name: 'Modal Pemilik',
category: 'Ekuitas',
balance: '500000000'
},
{
id: 12,
code: '4-40001',
name: 'Penjualan',
category: 'Pendapatan',
balance: '250000000'
},
{
id: 13,
code: '5-50001',
name: 'Beban Gaji',
category: 'Beban',
balance: '-80000000'
},
{
id: 14,
code: '5-50002',
name: 'Beban Listrik',
category: 'Beban',
balance: '-5000000'
},
{
id: 15,
code: '5-50003',
name: 'Beban Telepon',
category: 'Beban',
balance: '-2000000'
}
]
// Styled Components
const Icon = styled('i')({})
@ -242,16 +138,6 @@ const getCategoryColor = (category: string) => {
}
}
// Format currency
const formatCurrency = (amount: string) => {
const numAmount = parseInt(amount)
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0
}).format(Math.abs(numAmount))
}
// Column Definitions
const columnHelper = createColumnHelper<AccountTypeWithAction>()
@ -261,53 +147,25 @@ const AccountListTable = () => {
// States
const [addAccountOpen, setAddAccountOpen] = useState(false)
const [rowSelection, setRowSelection] = useState({})
const [currentPage, setCurrentPage] = useState(0)
const [currentPage, setCurrentPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
const [openConfirm, setOpenConfirm] = useState(false)
const [accountId, setAccountId] = useState('')
const [search, setSearch] = useState('')
const [categoryFilter, setCategoryFilter] = useState<string>('Semua')
const [filteredData, setFilteredData] = useState<AccountType[]>(accountsData)
const [data, setData] = useState<AccountType[]>(accountsData)
const [editingAccount, setEditingAccount] = useState<AccountType | null>(null)
const [editingAccount, setEditingAccount] = useState<Account | null>(null)
const { data, isLoading } = useAccounts({
page: currentPage,
limit: pageSize,
search
})
// Hooks
const { lang: locale } = useParams()
// Get unique categories for filter
const categories = useMemo(() => {
const uniqueCategories = [...new Set(data.map(account => account.category))]
return ['Semua', ...uniqueCategories]
}, [data])
// Filter data based on search and category
useEffect(() => {
let filtered = data
// Filter by search
if (search) {
filtered = filtered.filter(
account =>
account.code.toLowerCase().includes(search.toLowerCase()) ||
account.name.toLowerCase().includes(search.toLowerCase()) ||
account.category.toLowerCase().includes(search.toLowerCase())
)
}
// Filter by category
if (categoryFilter !== 'Semua') {
filtered = filtered.filter(account => account.category === categoryFilter)
}
setFilteredData(filtered)
setCurrentPage(0)
}, [search, categoryFilter, data])
const totalCount = filteredData.length
const paginatedData = useMemo(() => {
const startIndex = currentPage * pageSize
return filteredData.slice(startIndex, startIndex + pageSize)
}, [filteredData, currentPage, pageSize])
const accounts = data?.data ?? []
const totalCount = data?.total ?? 0
const handlePageChange = useCallback((event: unknown, newPage: number) => {
setCurrentPage(newPage)
@ -319,12 +177,8 @@ const AccountListTable = () => {
setCurrentPage(0)
}, [])
const handleDelete = () => {
setOpenConfirm(false)
}
// Handle row click for edit
const handleRowClick = (account: AccountType, event: React.MouseEvent) => {
const handleRowClick = (account: Account, event: React.MouseEvent) => {
// Don't trigger row click if clicking on checkbox or link
const target = event.target as HTMLElement
if (target.closest('input[type="checkbox"]') || target.closest('a') || target.closest('button')) {
@ -365,7 +219,7 @@ const AccountListTable = () => {
/>
)
},
columnHelper.accessor('code', {
columnHelper.accessor('number', {
header: 'Kode Akun',
cell: ({ row }) => (
<Button
@ -381,7 +235,7 @@ const AccountListTable = () => {
}
}}
>
{row.original.code}
{row.original.number}
</Button>
)
}),
@ -393,26 +247,21 @@ const AccountListTable = () => {
</Typography>
)
}),
columnHelper.accessor('category', {
columnHelper.accessor('chart_of_account.name', {
header: 'Kategori',
cell: ({ row }) => (
<Chip
variant='tonal'
label={row.original.category}
size='small'
color={getCategoryColor(row.original.category) as any}
className='capitalize'
/>
<Typography color='text.primary' className='font-medium'>
{row.original.chart_of_account.name}
</Typography>
)
}),
columnHelper.accessor('balance', {
columnHelper.accessor('current_balance', {
header: 'Saldo',
cell: ({ row }) => {
const balance = parseInt(row.original.balance)
return (
<Typography className='font-medium text-right text-primary'>
{balance < 0 ? '-' : ''}
{formatCurrency(row.original.balance)}
{row.original.current_balance < 0 ? '-' : ''}
{formatCurrency(row.original.current_balance)}
</Typography>
)
}
@ -422,7 +271,7 @@ const AccountListTable = () => {
)
const table = useReactTable({
data: paginatedData as AccountType[],
data: accounts as Account[],
columns,
filterFns: {
fuzzy: fuzzyFilter
@ -512,7 +361,7 @@ const AccountListTable = () => {
</tr>
))}
</thead>
{filteredData.length === 0 ? (
{accounts.length === 0 ? (
<tbody>
<tr>
<td colSpan={table.getVisibleFlatColumns().length} className='text-center'>
@ -558,15 +407,16 @@ const AccountListTable = () => {
onPageChange={handlePageChange}
onRowsPerPageChange={handlePageSizeChange}
rowsPerPageOptions={[10, 25, 50]}
disabled={isLoading}
/>
</Card>
<AccountFormDrawer
{/* <AccountFormDrawer
open={addAccountOpen}
handleClose={handleCloseDrawer}
accountData={data}
setData={setData}
editingAccount={editingAccount}
/>
/> */}
</>
)
}