card balance on homepage
This commit is contained in:
@@ -19,6 +19,14 @@ const HomeScreen = () => {
|
||||
const { user, logout } = useAuth();
|
||||
const [metrics, setMetrics] = useState(null);
|
||||
const [loadingMetrics, setLoadingMetrics] = useState(true);
|
||||
const [cardBalance, setCardBalance] = useState(null);
|
||||
const [loadingCardBalance, setLoadingCardBalance] = useState(true);
|
||||
const [cardBalanceError, setCardBalanceError] = useState(null);
|
||||
const [isBalanceVisible, setIsBalanceVisible] = useState(true);
|
||||
|
||||
const showBalanceCard = !loadingCardBalance && cardBalanceError === null && cardBalance !== null;
|
||||
|
||||
// (Optional) Add helpers here if needed in the future
|
||||
|
||||
useEffect(() => {
|
||||
const fetchMetrics = async () => {
|
||||
@@ -39,6 +47,38 @@ const HomeScreen = () => {
|
||||
fetchMetrics();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchCardBalance = async () => {
|
||||
// Ensure user has filled all required card & passport fields
|
||||
if (!user?.passport_serie || !user?.passport_id || !user?.card_number || !user?.card_month || !user?.card_year) {
|
||||
setLoadingCardBalance(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await apiService.getCardBalanceQuickCheck();
|
||||
if (res.success) {
|
||||
// Try common balance keys else fallback to raw
|
||||
const raw = res.data;
|
||||
let balanceValue = null;
|
||||
if (raw && typeof raw === 'object') {
|
||||
balanceValue = raw.balance ?? raw.card_balance ?? raw.amount ?? null;
|
||||
}
|
||||
setCardBalance(balanceValue);
|
||||
setCardBalanceError(null);
|
||||
} else {
|
||||
console.warn('Failed to fetch card balance:', res.error);
|
||||
setCardBalanceError(res.error || 'Error');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Error fetching card balance:', e);
|
||||
} finally {
|
||||
setLoadingCardBalance(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchCardBalance();
|
||||
}, [user]);
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar style="dark" />
|
||||
@@ -67,19 +107,25 @@ const HomeScreen = () => {
|
||||
</View>
|
||||
|
||||
{/* Balance Card */}
|
||||
<View style={styles.balanceCard}>
|
||||
<View style={styles.balanceHeader}>
|
||||
<Text style={styles.balanceLabel}>Jemi balans</Text>
|
||||
<TouchableOpacity>
|
||||
<Ionicons name="eye" size={20} color={COLORS.white} />
|
||||
</TouchableOpacity>
|
||||
{showBalanceCard && (
|
||||
<View style={styles.balanceCard}>
|
||||
<View style={styles.balanceHeader}>
|
||||
<Text style={styles.balanceLabel}>Jemi balans</Text>
|
||||
<TouchableOpacity onPress={() => setIsBalanceVisible((prev) => !prev)}>
|
||||
<Ionicons name={isBalanceVisible ? 'eye' : 'eye-off'} size={20} color={COLORS.white} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Text style={styles.balanceAmount}>
|
||||
{isBalanceVisible ? `${cardBalance} TMT` : '•••••'}
|
||||
</Text>
|
||||
<View style={styles.balanceFooter}>
|
||||
<Text style={styles.accountNumber}>
|
||||
{user?.card_number ? `Hasap: ****${String(user.card_number).replace(/[^0-9]/g, '').slice(-4)}` : 'Hasap: ----'}
|
||||
</Text>
|
||||
<View style={styles.cardChip} />
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.balanceAmount}>1,250.00 TMT</Text>
|
||||
<View style={styles.balanceFooter}>
|
||||
<Text style={styles.accountNumber}>Hasap: ****1234</Text>
|
||||
<View style={styles.cardChip} />
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
@@ -165,6 +165,29 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
// Quick card balance check
|
||||
async getCardBalanceQuickCheck(cardNumber = null, cardMonth = null, cardYear = null, passportSerie = null, passportId = null) {
|
||||
try {
|
||||
let raw = await authService.getCardBalanceQuickCheck(cardNumber, cardMonth, cardYear, passportSerie, passportId);
|
||||
|
||||
// Handle text response that is JSON-stringified
|
||||
if (typeof raw === 'string') {
|
||||
try { raw = JSON.parse(raw); } catch (_) {}
|
||||
}
|
||||
|
||||
// When API returns { status: false, message: '...' }
|
||||
if (raw && raw.status === false) {
|
||||
return { success: false, error: raw.message || 'Failed', data: raw };
|
||||
}
|
||||
|
||||
// On success, data may be inside raw.data or raw itself
|
||||
const data = raw?.data ?? raw;
|
||||
return { success: true, data };
|
||||
} catch (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
// ================================
|
||||
// Loan Paid-Off Letter Orders
|
||||
// ================================
|
||||
|
||||
@@ -370,6 +370,47 @@ class AuthService {
|
||||
const query = `start_date=${encodeURIComponent(startDate)}&end_date=${encodeURIComponent(endDate)}`;
|
||||
return this.makeRequest(`/card-transactions-download/${orderId}?${query}`, null, true, 'GET');
|
||||
}
|
||||
|
||||
// ================================
|
||||
// Card balance quick check (Kart galyndysy)
|
||||
// ================================
|
||||
|
||||
async getCardBalanceQuickCheck(cardNumber = null, cardMonth = null, cardYear = null, passportSerie = null, passportId = null) {
|
||||
// Fallback to stored user profile for missing fields
|
||||
let serie = passportSerie;
|
||||
let pid = passportId;
|
||||
let cNumber = cardNumber;
|
||||
let cMonth = cardMonth;
|
||||
let cYear = cardYear;
|
||||
|
||||
if (!serie || !pid || !cNumber || !cMonth || !cYear) {
|
||||
const user = await this.getStoredUser();
|
||||
serie = serie || user?.passport_serie;
|
||||
pid = pid || user?.passport_id;
|
||||
cNumber = cNumber || user?.card_number;
|
||||
cMonth = cMonth || user?.card_month;
|
||||
cYear = cYear || user?.card_year;
|
||||
}
|
||||
|
||||
if (!serie || !pid || !cNumber || !cMonth || !cYear) {
|
||||
throw new Error('Card or passport details are missing');
|
||||
}
|
||||
|
||||
// Ensure values are properly formatted
|
||||
const plainCardNumber = String(cNumber).replace(/[^0-9]/g, '').slice(0, 16);
|
||||
const monthStr = String(cMonth).padStart(2, '0');
|
||||
|
||||
const payload = {
|
||||
passport_serie: serie,
|
||||
passport_id: pid,
|
||||
card_number: plainCardNumber,
|
||||
card_month: monthStr,
|
||||
card_year: String(cYear),
|
||||
};
|
||||
|
||||
// POST request – authenticated (token header will be included if available)
|
||||
return this.makeRequest('/card-balance-quick-check', payload, true, 'POST');
|
||||
}
|
||||
}
|
||||
|
||||
export default new AuthService();
|
||||
Reference in New Issue
Block a user