101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { apiConfig } from '@/config/api.config';
|
|
import { useCallApi } from '@/hooks';
|
|
import { CreditCard, Wallet } from 'lucide-react';
|
|
import { useEffect, useState } from 'react';
|
|
|
|
type WalletResponse = {
|
|
amount: number;
|
|
id_wallet: string;
|
|
wallet: string;
|
|
credit_limit: number;
|
|
monthly_limit: number;
|
|
};
|
|
|
|
interface BalanceCardProps {
|
|
id: string;
|
|
}
|
|
|
|
const API_URL_WALLET = apiConfig.service_wallet;
|
|
|
|
const BalanceCard = ({ id }: BalanceCardProps) => {
|
|
const { GetData } = useCallApi();
|
|
const [wallets, setWallets] = useState<WalletResponse[]>([]);
|
|
|
|
const formatCurrency = (value: number) => {
|
|
return new Intl.NumberFormat('en-US', {
|
|
style: 'currency',
|
|
currency: 'USD'
|
|
}).format(value);
|
|
};
|
|
|
|
const formatNumberWithDots = (value: number) => {
|
|
return value.toLocaleString('id-ID');
|
|
};
|
|
|
|
const getColorClass = (amount: number) => {
|
|
if (amount > 0) return 'bg-amber-300';
|
|
if (amount > 500) return 'bg-blue-500';
|
|
return 'bg-red-500';
|
|
};
|
|
|
|
useEffect(() => {
|
|
async function fetchAccountBalances() {
|
|
try {
|
|
const response = await GetData(`${API_URL_WALLET}/dashboard/balance/account/${id}`, {
|
|
id: id
|
|
});
|
|
if (response?.status === true) {
|
|
setWallets(response.data);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching account balances', error);
|
|
}
|
|
}
|
|
|
|
fetchAccountBalances();
|
|
}, [id]);
|
|
|
|
return (
|
|
<div className="grid lg:grid-cols-4 md:grid-cols-2 gap-5 items-stretch">
|
|
{wallets.map((wallet) => {
|
|
const colorClass = getColorClass(wallet.amount);
|
|
const isNegative = wallet.amount < 0;
|
|
|
|
return (
|
|
<div
|
|
key={wallet.id_wallet}
|
|
className="rounded-lg overflow-hidden shadow-lg border border-gray-200 hover:shadow-xl transition-shadow duration-300"
|
|
>
|
|
<div className={`${colorClass} h-2`} />
|
|
<div className="p-5">
|
|
<div className="flex items-center justify-between mb-3">
|
|
<h3 className="font-bold text-lg text-gray-800">{wallet.wallet}</h3>
|
|
{wallet.wallet.includes('Credit') ? (
|
|
<CreditCard className="text-gray-600" size={20} />
|
|
) : (
|
|
<Wallet className="text-gray-600" size={20} />
|
|
)}
|
|
</div>
|
|
<p className={`text-xl font-bold ${isNegative ? 'text-red-600' : 'text-gray-800'}`}>
|
|
{formatCurrency(wallet.amount)}
|
|
</p>
|
|
|
|
<div className="mt-3 pt-3 border-t border-gray-200 flex items-center justify-between">
|
|
<div className="text-xs text-gray-500">Credit Limit:</div>
|
|
<div className="text-sm">{formatNumberWithDots(wallet.credit_limit)}</div>
|
|
</div>
|
|
<div className="mt-3 flex items-center justify-between">
|
|
<div className="text-xs text-gray-500">Monthly Limit:</div>
|
|
<div className="text-sm">{formatNumberWithDots(wallet.monthly_limit)}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default BalanceCard;
|