Amba-Agent-App/app/(root)/(screens)/selectacc.tsx
2026-01-16 00:22:35 +03:00

261 lines
8.2 KiB
TypeScript

import React, { useEffect, useRef, useState } from "react";
import {
View,
Text,
ScrollView,
TouchableOpacity,
FlatList,
} from "react-native";
import { Input } from "~/components/ui/input";
import { Button } from "~/components/ui/button";
import { Filter, LucideX, LucideCreditCard } from "lucide-react-native";
import AccountCard from "~/components/ui/accCard";
import BackButton from "~/components/ui/backButton";
import { useLocalSearchParams, router } from "expo-router";
import { useAuthWithProfile } from "~/lib/hooks/useAuthWithProfile";
import { useUserWallet } from "~/lib/hooks/useUserWallet";
import { CreditCard, WalletService } from "~/lib/services/walletService";
import { ROUTES } from "~/lib/routes";
import { showAlert } from "~/lib/utils/alertUtils";
import ScreenWrapper from "~/components/ui/ScreenWrapper";
import ModalToast from "~/components/ui/toast";
import { useTranslation } from "react-i18next";
export default function SelectAccount() {
const { t } = useTranslation();
const { amount } = useLocalSearchParams<{ amount: string }>();
const { user } = useAuthWithProfile();
const { wallet, loading, error, refreshWallet } = useUserWallet(user);
const [selectedCardId, setSelectedCardId] = React.useState<string | null>(
null
);
const [isProcessing, setIsProcessing] = useState(false);
const [toastVisible, setToastVisible] = useState(false);
const [toastTitle, setToastTitle] = useState("");
const [toastDescription, setToastDescription] = useState<string | undefined>(
undefined
);
const [toastVariant, setToastVariant] = useState<
"success" | "error" | "warning" | "info"
>("info");
const toastTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const showToast = (
title: string,
description?: string,
variant: "success" | "error" | "warning" | "info" = "info"
) => {
if (toastTimeoutRef.current) {
clearTimeout(toastTimeoutRef.current);
}
setToastTitle(title);
setToastDescription(description);
setToastVariant(variant);
setToastVisible(true);
toastTimeoutRef.current = setTimeout(() => {
setToastVisible(false);
toastTimeoutRef.current = null;
}, 2500);
};
useEffect(() => {
return () => {
if (toastTimeoutRef.current) {
clearTimeout(toastTimeoutRef.current);
}
};
}, []);
const handleCardSelect = (card: CreditCard) => {
setSelectedCardId(card.id);
console.log("Selected card:", card.id);
};
const renderCards = () => {
if (loading) {
return (
<View className="flex items-center justify-center py-10">
<Text className="text-gray-500 font-dmsans">
{t("selectacc.loadingCards")}
</Text>
</View>
);
}
if (error) {
return (
<View className="flex items-center justify-center py-10">
<Text className="text-red-500 font-dmsans">
{t("selectacc.errorTitle")}
</Text>
<Text className="text-gray-400 font-dmsans-medium text-sm mt-1">
{t("selectacc.errorWithMessage", { error })}
</Text>
</View>
);
}
if (!wallet?.cards || wallet.cards.length === 0) {
return (
<View className="flex items-center justify-center py-10">
<LucideCreditCard color="#D1D5DB" size={48} />
<Text className="text-gray-500 font-dmsans mt-4">
{t("selectacc.emptyTitle")}
</Text>
<Text className="text-gray-400 font-dmsans-medium text-sm mt-1 text-center px-4">
{t("selectacc.emptySubtitle")}
</Text>
</View>
);
}
return (
<FlatList
data={wallet.cards}
keyExtractor={(item) => item.id}
scrollEnabled={false}
ItemSeparatorComponent={() => <View className="h-2" />}
renderItem={({ item: card }) => (
<TouchableOpacity
onPress={() => handleCardSelect(card)}
className="w-full"
>
<AccountCard
cardType={card.cardType}
cardNumber={card.cardNumber}
expiryDate={card.expiryDate}
selected={selectedCardId === card.id}
/>
</TouchableOpacity>
)}
/>
);
};
return (
<ScreenWrapper edges={[]}>
<BackButton />
<View className=" px-5 pt-10">
<Text className="text-xl font-dmsans-medium text-center">
{t("selectacc.title")}
</Text>
{amount && (
<Text className="text-lg font-dmsans text-primary mt-8">
{t("selectacc.addingAmount", {
amount: (parseInt(amount) / 100).toFixed(2),
})}
</Text>
)}
</View>
<ScrollView className="flex px-5 space-y-3 w-full ">
<View className="flex flex-col space-y-1 py-5 items-left">
<Text className="text-xl font-dmsans text-primary">
{t("selectacc.accountsTitle")}
</Text>
<Text className="text-base font-dmsans text-gray-400">
{selectedCardId
? t("selectacc.accountsDescriptionSelected")
: t("selectacc.accountsDescriptionUnselected")}
</Text>
</View>
<View className="flex flex-col items-left ">
<View className="flex flex-col items-center space-y-2 mt-3">
{renderCards()}
</View>
</View>
</ScrollView>
{selectedCardId && (
<View className="flex flex-row items-center space-x-2 w-full px-5 pb-6">
<Button
className="flex flex-row items-center space-x-2 bg-primary rounded-3xl p-3 w-full"
onPress={async () => {
if (!user?.uid || !amount || !selectedCardId) {
showToast(
t("selectacc.toastErrorTitle"),
t("selectacc.toastMissingInfo"),
"error"
);
return;
}
setIsProcessing(true);
try {
const selectedCard = wallet?.cards?.find(
(card) => card.id === selectedCardId
);
const amountInCents = parseInt(amount);
const currentBalance = wallet?.balance || 0;
const newBalance = currentBalance + amountInCents;
console.log(
"Processing transaction with card:",
selectedCard?.id,
"Amount:",
amountInCents,
"cents"
);
console.log(
"Current balance:",
currentBalance,
"Adding:",
amountInCents,
"New balance:",
newBalance
);
const result = await WalletService.updateWalletBalance(
user.uid,
newBalance
);
if (result.success) {
await refreshWallet();
router.replace({
pathname: ROUTES.ADDCASH_COMPLETION,
params: {
amount: (amountInCents / 100).toFixed(2),
},
});
} else {
showToast(
t("selectacc.toastErrorTitle"),
result.error || t("selectacc.toastAddCashFailed"),
"error"
);
}
} catch (error) {
console.error("Error adding cash:", error);
showToast(
t("selectacc.toastErrorTitle"),
t("selectacc.toastAddCashFailedWithRetry"),
"error"
);
} finally {
setIsProcessing(false);
}
}}
disabled={isProcessing}
>
<Text className="text-white text-base font-dmsans-medium">
{isProcessing
? t("selectacc.buttonProcessing")
: t("selectacc.buttonProceed")}
</Text>
</Button>
</View>
)}
<ModalToast
visible={toastVisible}
title={toastTitle}
description={toastDescription}
variant={toastVariant}
/>
</ScreenWrapper>
);
}