Amba-Agent-App/components/ui/transactionCard.tsx
2026-01-16 00:22:35 +03:00

218 lines
6.2 KiB
TypeScript

import {
LucideSend,
LucideUploadCloud,
LucideArrowUpRight,
LucideArrowDownLeft,
} from "lucide-react-native";
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { useTranslation } from "react-i18next";
import { Transaction } from "~/lib/services/transactionService";
interface TransactionCardProps {
transaction: Transaction;
onPress?: () => void;
}
export default function TransactionCard({
transaction,
onPress,
}: TransactionCardProps) {
const { t } = useTranslation();
const formatDate = (date: Date) => {
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
});
};
const formatAmount = (amountInCents: number) => {
return `$${(amountInCents / 100).toFixed(2)}`;
};
const getTransactionIcon = (transaction: Transaction) => {
switch (transaction.type) {
case "send":
return <LucideArrowUpRight className="text-white" size={16} />;
case "receive":
return <LucideArrowDownLeft className="text-white" size={16} />;
case "add_cash":
return <LucideUploadCloud className="text-white" size={16} />;
case "cash_out":
return <LucideArrowUpRight className="text-white" size={16} />;
default:
return <LucideSend className="text-white" size={16} />;
}
};
const getTransactionColor = (transaction: Transaction) => {
switch (transaction.type) {
case "send":
return "bg-red-500";
case "receive":
return "bg-green-500";
case "add_cash":
return "bg-blue-500";
case "cash_out":
return "bg-orange-500";
default:
return "bg-secondary";
}
};
const getAmountColor = (transaction: Transaction) => {
switch (transaction.type) {
case "send":
return "text-red-600";
case "receive":
return "text-green-600";
case "add_cash":
return "text-blue-600";
case "cash_out":
return "text-orange-600";
default:
return "text-primary";
}
};
const getTransactionDescription = (transaction: Transaction) => {
switch (transaction.type) {
case "send":
return t("components.transactioncard.descriptionSend", {
recipientName: transaction.recipientName,
});
case "receive":
return t("components.transactioncard.descriptionReceive", {
senderName: transaction.senderName,
});
case "add_cash":
return t("components.transactioncard.descriptionAddCash", {
lastFourDigits: transaction.lastFourDigits,
});
case "cash_out":
return t("components.transactioncard.descriptionCashOut", {
bankProvider:
transaction.bankProvider.charAt(0).toUpperCase() +
transaction.bankProvider.slice(1),
});
default:
return t("components.transactioncard.descriptionDefault");
}
};
const getTransactionDetails = (transaction: Transaction) => {
const details = [];
//@ts-ignore
if (transaction.note && transaction.note.trim()) {
//@ts-ignore
details.push(transaction.note);
}
switch (transaction.type) {
case "send":
if (transaction.recipientName) {
details.push(`Client: ${transaction.recipientName}`);
}
if (transaction.recipientPhoneNumber) {
details.push(
t("components.transactioncard.detailPhone", {
phoneNumber: transaction.recipientPhoneNumber,
})
);
}
break;
case "receive":
if (transaction.senderName) {
details.push(`Client: ${transaction.senderName}`);
}
if (transaction.senderPhoneNumber) {
details.push(
t("components.transactioncard.detailPhone", {
phoneNumber: transaction.senderPhoneNumber,
})
);
}
break;
case "add_cash":
if (transaction.cardId) {
details.push(
t("components.transactioncard.detailCard", {
lastFourDigits: transaction.lastFourDigits,
})
);
}
break;
case "cash_out":
if (transaction.accountNumber) {
details.push(
t("components.transactioncard.detailAccount", {
accountNumber: transaction.accountNumber,
})
);
}
details.push(
t("components.transactioncard.detailBankProvider", {
bankProvider:
transaction.bankProvider.charAt(0).toUpperCase() +
transaction.bankProvider.slice(1),
})
);
break;
}
return details;
};
return (
<TouchableOpacity
className="flex flex-row w-full justify-between items-center py-4 bg-green-50 rounded-md px-3 mb-2"
onPress={onPress}
>
<View className="flex flex-row space-x-3 items-center flex-1">
<View className={`${getTransactionColor(transaction)} p-2 rounded`}>
{getTransactionIcon(transaction)}
</View>
<View className="w-4" />
<View className="flex gap-[2px] flex-1">
<Text className="font-dmsans-bold text-primary" numberOfLines={1}>
{getTransactionDescription(transaction)}
</Text>
<Text
className="font-dmsans-medium text-secondary text-sm"
numberOfLines={1}
>
{formatDate(transaction.createdAt)}
</Text>
{getTransactionDetails(transaction).map((detail, index) => (
<Text
key={index}
className="font-dmsans-medium text-gray-500 text-xs"
numberOfLines={1}
>
{detail}
</Text>
))}
</View>
</View>
<View className="flex items-center space-y-1">
<Text
className={`font-dmsans-bold text-lg ${getAmountColor(transaction)}`}
>
{transaction.type === "send" || transaction.type === "cash_out"
? "-"
: "+"}
{formatAmount(transaction.amount)}
</Text>
<Text className="font-dmsans-medium text-xs text-gray-500">
{transaction.status}
</Text>
</View>
</TouchableOpacity>
);
}