794 lines
20 KiB
TypeScript
794 lines
20 KiB
TypeScript
import { useLayoutEffect, useMemo, useState, useEffect } from "react";
|
||
import { useNavigation, useRouter } from "expo-router";
|
||
import {
|
||
NativeScrollEvent,
|
||
NativeSyntheticEvent,
|
||
Pressable,
|
||
ScrollView,
|
||
StyleSheet,
|
||
TouchableOpacity,
|
||
} from "react-native";
|
||
import { Text, View } from "react-native";
|
||
import { useSelector } from "react-redux";
|
||
import { RootState } from "@/store";
|
||
import ProfileImage from "@/components/home/Profile";
|
||
import { Overlay } from "@/components/common/Overlay";
|
||
import { useSnackbar } from "@/contexts/Snackbar";
|
||
import CustomerCareIcon from "../../assets/icons/customer-care.svg";
|
||
import api from "@/services/axiosClient";
|
||
import PaymentHistoryCard from "@/components/Payments/PaymentHistoryCard";
|
||
import { BASE_URL } from "@/constants/config";
|
||
import { useDispatch } from "react-redux";
|
||
import { setDueAmount, setMyPlan } from "@/store/paymentSlice";
|
||
|
||
export interface MyPlan {
|
||
no_of_emi: number;
|
||
total_amount: number;
|
||
down_payment: number;
|
||
emi_amount: number;
|
||
total_emi: number;
|
||
installment_paid: number;
|
||
current_amount: number;
|
||
}
|
||
|
||
interface EmiDetails {
|
||
due_amount: number;
|
||
total_amount_paid_in_current_cycle: number;
|
||
due_date: string;
|
||
status: string;
|
||
advance_balance: number;
|
||
pending_cycles: number;
|
||
total_pending_installments: number;
|
||
myPlain: MyPlan;
|
||
}
|
||
|
||
interface EmiResponse {
|
||
success: boolean;
|
||
data: EmiDetails[];
|
||
}
|
||
|
||
interface PaymentHistoryItem {
|
||
id: number;
|
||
amount: string;
|
||
status: string;
|
||
created_at: string;
|
||
payment_mode: string[];
|
||
payment_date: string;
|
||
}
|
||
|
||
interface PaymentHistoryPagination {
|
||
total_records: number;
|
||
page_number: number;
|
||
page_size: number;
|
||
}
|
||
|
||
interface PaymentHistoryResponse {
|
||
success: boolean;
|
||
data: {
|
||
payments: PaymentHistoryItem[];
|
||
pagination: PaymentHistoryPagination;
|
||
};
|
||
}
|
||
|
||
const formatPaymentDate = (dateString: string) => {
|
||
try {
|
||
return dateString.split(",")[0];
|
||
} catch {
|
||
return dateString;
|
||
}
|
||
};
|
||
|
||
// Format time for payment history
|
||
const formatPaymentTime = (dateString: string) => {
|
||
try {
|
||
// Extract time and day info from the formatted date
|
||
const parts = dateString.split(",");
|
||
if (parts.length > 1) {
|
||
const timePart = parts[1].trim(); // "5:23:58 pm"
|
||
const date = new Date(dateString);
|
||
const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
|
||
return `${timePart} | ${dayName}`;
|
||
}
|
||
return dateString;
|
||
} catch {
|
||
return dateString;
|
||
}
|
||
};
|
||
|
||
export default function PaymentsTabScreen() {
|
||
const navigation = useNavigation();
|
||
const { data } = useSelector((state: RootState) => state.user);
|
||
const router = useRouter();
|
||
const { showSnackbar } = useSnackbar();
|
||
|
||
const [emiDetails, setEmiDetails] = useState<EmiDetails | null>(null);
|
||
const [isLoading, setIsLoading] = useState(true);
|
||
const [isSupportModalVisible, setIsSupportModalVisible] = useState(false);
|
||
const [isEndReached, setIsEndReached] = useState(false);
|
||
const dispatch = useDispatch();
|
||
//payment history states
|
||
const [paymentHistory, setPaymentHistory] = useState<PaymentHistoryItem[]>(
|
||
[]
|
||
);
|
||
const [isHistoryLoading, setIsHistoryLoading] = useState(false);
|
||
const [showFullHistory, setShowFullHistory] = useState(false);
|
||
const [currentPage, setCurrentPage] = useState(1);
|
||
const [hasMorePages, setHasMorePages] = useState(true);
|
||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||
|
||
const vehicle =
|
||
Array.isArray(data?.vehicles) && data.vehicles.length > 0
|
||
? data.vehicles[0]
|
||
: null;
|
||
const battery =
|
||
Array.isArray(data?.batteries) && data.batteries.length > 0
|
||
? data.batteries[0]
|
||
: null;
|
||
|
||
const model = vehicle?.model ?? "---";
|
||
const chasisNumber = vehicle?.chasis_number ?? "---";
|
||
|
||
// Fetch EMI details
|
||
useEffect(() => {
|
||
const fetchEmiDetails = async () => {
|
||
try {
|
||
setIsLoading(true);
|
||
|
||
const response = await api.get(`/api/v1/emi-details`);
|
||
const result: EmiResponse = response.data;
|
||
|
||
if (result.success && result.data.length > 0) {
|
||
const details = result.data[0];
|
||
|
||
setEmiDetails(details);
|
||
|
||
dispatch(setDueAmount(details.due_amount));
|
||
dispatch(setMyPlan(details.myPlain));
|
||
} else {
|
||
showSnackbar("No EMI details found", "error");
|
||
}
|
||
} catch (err) {
|
||
console.error("Error fetching EMI details:", err);
|
||
const errorMessage =
|
||
err instanceof Error ? err.message : "Something went wrong";
|
||
showSnackbar(errorMessage, "error");
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
|
||
fetchEmiDetails();
|
||
}, []);
|
||
|
||
useLayoutEffect(() => {
|
||
navigation.setOptions({
|
||
headerStyle: {
|
||
backgroundColor: "#F3F5F8",
|
||
},
|
||
headerTitle: () => (
|
||
<View style={styles.headerTitleContainer}>
|
||
<Text style={styles.title}>{model}</Text>
|
||
<Text style={styles.subtitle}>{chasisNumber}</Text>
|
||
</View>
|
||
),
|
||
headerRight: () => (
|
||
<View style={styles.rightContainer}>
|
||
<Pressable
|
||
style={styles.supportButton}
|
||
onPress={() => {
|
||
console.log("Support Pressed");
|
||
setIsSupportModalVisible(true);
|
||
}}
|
||
>
|
||
<CustomerCareIcon />
|
||
</Pressable>
|
||
<Pressable
|
||
onPress={() => {
|
||
router.push("/user/profile");
|
||
}}
|
||
>
|
||
<ProfileImage
|
||
username={data?.name || "User"}
|
||
onClick={() => router.push("/user/profile")}
|
||
textSize={20}
|
||
boxSize={40}
|
||
/>
|
||
</Pressable>
|
||
</View>
|
||
),
|
||
});
|
||
}, [navigation, data, model, chasisNumber]);
|
||
|
||
// Format currency
|
||
const formatCurrency = (amount: number) => {
|
||
return `₹${amount.toLocaleString()}`;
|
||
};
|
||
|
||
const handleViewAll = () => {
|
||
setShowFullHistory(true);
|
||
};
|
||
|
||
// Format date
|
||
const formatDate = (dateString: string) => {
|
||
try {
|
||
const date = new Date(dateString);
|
||
return date.toLocaleDateString("en-IN", {
|
||
day: "2-digit",
|
||
month: "short",
|
||
year: "numeric",
|
||
});
|
||
} catch {
|
||
return dateString;
|
||
}
|
||
};
|
||
|
||
// Get current month/year for header
|
||
const getCurrentMonthYear = () => {
|
||
const date = new Date();
|
||
return date.toLocaleDateString("en-US", {
|
||
month: "long",
|
||
year: "numeric",
|
||
});
|
||
};
|
||
|
||
const fetchPaymentHistory = async (
|
||
pageNumber: number = 1,
|
||
isLoadMore: boolean = false
|
||
) => {
|
||
try {
|
||
if (isLoadMore) {
|
||
setIsLoadingMore(true);
|
||
} else {
|
||
setIsHistoryLoading(true);
|
||
}
|
||
|
||
const response = await api.get(
|
||
`${BASE_URL}/api/v1/payment-history?page_number=${pageNumber}&page_size=10`
|
||
);
|
||
const result: PaymentHistoryResponse = response.data;
|
||
|
||
console.log("Payment History Response:", result);
|
||
if (result.success) {
|
||
const newPayments = result.data.payments;
|
||
|
||
if (isLoadMore) {
|
||
setPaymentHistory((prev) => [...prev, ...newPayments]);
|
||
} else {
|
||
setPaymentHistory(newPayments);
|
||
}
|
||
|
||
// Check if there are more pages
|
||
const totalPages = Math.ceil(
|
||
result.data.pagination.total_records /
|
||
result.data.pagination.page_size
|
||
);
|
||
setHasMorePages(pageNumber < totalPages);
|
||
setCurrentPage(pageNumber);
|
||
} else {
|
||
showSnackbar("No payment history found", "error");
|
||
}
|
||
} catch (err) {
|
||
console.error("Error fetching payment history:", err);
|
||
const errorMessage =
|
||
err instanceof Error ? err.message : "Something went wrong";
|
||
showSnackbar(errorMessage, "error");
|
||
} finally {
|
||
if (isLoadMore) {
|
||
setIsLoadingMore(false);
|
||
} else {
|
||
setIsHistoryLoading(false);
|
||
}
|
||
}
|
||
};
|
||
|
||
const handleLoadMore = () => {
|
||
if (hasMorePages && !isLoadingMore) {
|
||
fetchPaymentHistory(currentPage + 1, true);
|
||
}
|
||
};
|
||
|
||
useEffect(() => {
|
||
if (isEndReached && showFullHistory && hasMorePages && !isLoadingMore) {
|
||
handleLoadMore();
|
||
}
|
||
}, [isEndReached]);
|
||
|
||
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||
const { layoutMeasurement, contentOffset, contentSize } = event.nativeEvent;
|
||
const paddingToBottom = 20;
|
||
const isAtBottom =
|
||
layoutMeasurement.height + contentOffset.y >=
|
||
contentSize.height - paddingToBottom;
|
||
|
||
setIsEndReached(isAtBottom);
|
||
};
|
||
|
||
useEffect(() => {
|
||
fetchPaymentHistory(1, false);
|
||
}, []);
|
||
|
||
return (
|
||
<ScrollView
|
||
style={styles.scrollContainer}
|
||
showsVerticalScrollIndicator={false}
|
||
onScroll={handleScroll}
|
||
scrollEventThrottle={16}
|
||
>
|
||
{/* Last EMI Details Card */}
|
||
<View style={styles.emiCard}>
|
||
{/* Header */}
|
||
<View style={styles.cardHeader}>
|
||
<Text style={styles.headerTitle}>Last EMI Details</Text>
|
||
<Text style={styles.headerDate}>{getCurrentMonthYear()}</Text>
|
||
</View>
|
||
|
||
{/* Divider */}
|
||
<View style={styles.divider} />
|
||
|
||
{/* EMI Details Content */}
|
||
{true && (
|
||
<View style={styles.cardContent}>
|
||
<View style={styles.detailRow}>
|
||
<Text style={styles.detailLabel}>Amount Due</Text>
|
||
<Text style={styles.detailValue}>
|
||
{emiDetails?.due_amount
|
||
? formatCurrency(emiDetails.due_amount)
|
||
: "---"}
|
||
</Text>
|
||
</View>
|
||
|
||
<View style={styles.detailRow}>
|
||
<Text style={styles.detailLabel}>Amount Paid</Text>
|
||
<Text style={styles.detailValue}>
|
||
{emiDetails?.total_amount_paid_in_current_cycle &&
|
||
formatCurrency(emiDetails.total_amount_paid_in_current_cycle)}
|
||
</Text>
|
||
</View>
|
||
|
||
<View style={styles.detailRow}>
|
||
<Text style={styles.detailLabel}>Due Date</Text>
|
||
<Text style={styles.detailValue}>
|
||
{emiDetails?.due_date && emiDetails.due_date}
|
||
</Text>
|
||
</View>
|
||
|
||
<View style={styles.detailRow}>
|
||
<Text style={styles.detailLabel}>Payment Status</Text>
|
||
<StatusBadge
|
||
label={emiDetails?.status && emiDetails.status}
|
||
type={emiDetails?.status && emiDetails.status.toLowerCase()}
|
||
/>
|
||
</View>
|
||
</View>
|
||
)}
|
||
|
||
<View style={styles.divider} />
|
||
|
||
<View style={styles.buttonContainer}>
|
||
<TouchableOpacity
|
||
style={styles.primaryButton}
|
||
onPress={() => router.push("/payments/selectAmount")}
|
||
>
|
||
<Text style={styles.primaryButtonText}>Pay EMI</Text>
|
||
</TouchableOpacity>
|
||
|
||
<TouchableOpacity
|
||
style={styles.tertiaryButton}
|
||
onPress={() => router.push("/payments/myPlan")}
|
||
>
|
||
<Text style={styles.tertiaryButtonText}>View Plan</Text>
|
||
</TouchableOpacity>
|
||
</View>
|
||
</View>
|
||
|
||
<View style={styles.paymentHistorySection}>
|
||
<Text style={styles.sectionTitle}>Payment History</Text>
|
||
|
||
<View style={styles.paymentHistoryContainer}>
|
||
{isHistoryLoading ? (
|
||
<View style={styles.historyLoadingContainer}>
|
||
<Text style={styles.loadingText}>Loading payment history...</Text>
|
||
</View>
|
||
) : (
|
||
<>
|
||
{/* Show initial payments or all payments based on showFullHistory */}
|
||
{(showFullHistory
|
||
? paymentHistory
|
||
: paymentHistory.slice(0, 2)
|
||
).map((payment) => (
|
||
<PaymentHistoryCard
|
||
key={payment.id}
|
||
date={formatPaymentDate(payment.payment_date)}
|
||
amount={formatCurrency(parseFloat(payment.amount))}
|
||
time={formatPaymentTime(payment.payment_date)}
|
||
method={payment.payment_mode.join(", ")}
|
||
status={payment.status}
|
||
/>
|
||
))}
|
||
|
||
{/* View All button */}
|
||
{!showFullHistory && paymentHistory.length > 2 && (
|
||
<TouchableOpacity
|
||
style={styles.viewAllButton}
|
||
onPress={handleViewAll}
|
||
>
|
||
<Text style={styles.viewAllText}>View all</Text>
|
||
<Text style={styles.chevron}>›</Text>
|
||
</TouchableOpacity>
|
||
)}
|
||
|
||
{/* Loading indicator when fetching more */}
|
||
{isLoadingMore && (
|
||
<View style={styles.loadingContainer}>
|
||
<Text style={styles.loadingText}>
|
||
Loading more payments...
|
||
</Text>
|
||
</View>
|
||
)}
|
||
|
||
{/* No more data message */}
|
||
{showFullHistory &&
|
||
!hasMorePages &&
|
||
paymentHistory.length > 0 && (
|
||
<View style={styles.noMoreDataContainer}>
|
||
<Text style={styles.noMoreDataText}>
|
||
No more payments to show
|
||
</Text>
|
||
</View>
|
||
)}
|
||
|
||
{/* Empty state */}
|
||
{paymentHistory.length === 0 && !isHistoryLoading && (
|
||
<View style={styles.noDataContainer}>
|
||
<Text style={styles.noDataText}>
|
||
No payment history found
|
||
</Text>
|
||
</View>
|
||
)}
|
||
</>
|
||
)}
|
||
</View>
|
||
</View>
|
||
<Overlay isUploading={isLoading} />
|
||
</ScrollView>
|
||
);
|
||
}
|
||
|
||
const StatusBadge = ({
|
||
label,
|
||
type,
|
||
}: {
|
||
label: string | undefined;
|
||
type: string | undefined;
|
||
}) => {
|
||
if (!label || !type) return "--";
|
||
const getBadgeStyle = (type: string) => {
|
||
switch (type) {
|
||
case "pending":
|
||
return {
|
||
backgroundColor: "#FFF0E3",
|
||
color: "#8E4400",
|
||
};
|
||
case "failed":
|
||
return {
|
||
backgroundColor: "#FDE8E7",
|
||
color: "#D51C10",
|
||
};
|
||
case "completed":
|
||
case "paid":
|
||
return {
|
||
backgroundColor: "#E8F5E8",
|
||
color: "#2D7D32",
|
||
};
|
||
default:
|
||
return {
|
||
backgroundColor: "#E8F5E8",
|
||
color: "#2D7D32",
|
||
};
|
||
}
|
||
};
|
||
|
||
const badgeStyle = getBadgeStyle(type);
|
||
|
||
return (
|
||
<View
|
||
style={[styles.badge, { backgroundColor: badgeStyle.backgroundColor }]}
|
||
>
|
||
<Text style={[styles.badgeText, { color: badgeStyle.color }]}>
|
||
{label.charAt(0).toUpperCase() + label.slice(1)}
|
||
</Text>
|
||
</View>
|
||
);
|
||
};
|
||
|
||
const styles = StyleSheet.create({
|
||
loadingContainer: {
|
||
padding: 16,
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
},
|
||
container: {
|
||
flex: 1,
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
},
|
||
title: {
|
||
fontSize: 14,
|
||
color: "#6B7280",
|
||
fontWeight: "500",
|
||
},
|
||
separator: {
|
||
marginVertical: 30,
|
||
height: 1,
|
||
width: "80%",
|
||
},
|
||
headerTitleContainer: {
|
||
flexDirection: "column",
|
||
backgroundColor: "#F3F5F8",
|
||
},
|
||
subtitle: {
|
||
fontSize: 18,
|
||
color: "#111827",
|
||
fontWeight: "700",
|
||
},
|
||
rightContainer: {
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
paddingRight: 16,
|
||
gap: 8,
|
||
backgroundColor: "#F3F5F8",
|
||
},
|
||
supportButton: {
|
||
backgroundColor: "#F3F5F8",
|
||
},
|
||
scrollContainer: {
|
||
flex: 1,
|
||
paddingHorizontal: 16,
|
||
paddingBottom: 16,
|
||
width: "100%",
|
||
},
|
||
|
||
// EMI Card Styles
|
||
emiCard: {
|
||
backgroundColor: "#FCFCFC",
|
||
borderRadius: 8,
|
||
padding: 12,
|
||
marginBottom: 36,
|
||
},
|
||
cardHeader: {
|
||
flexDirection: "row",
|
||
justifyContent: "space-between",
|
||
alignItems: "flex-end",
|
||
marginBottom: 12,
|
||
},
|
||
headerTitle: {
|
||
fontSize: 14,
|
||
fontWeight: "600",
|
||
color: "#252A34",
|
||
},
|
||
headerDate: {
|
||
fontSize: 14,
|
||
fontWeight: "500",
|
||
color: "#565C70",
|
||
},
|
||
divider: {
|
||
height: 1,
|
||
backgroundColor: "#E5E9F0",
|
||
marginBottom: 12,
|
||
},
|
||
cardContent: {
|
||
gap: 8,
|
||
marginBottom: 12,
|
||
},
|
||
detailRow: {
|
||
flexDirection: "row",
|
||
justifyContent: "space-between",
|
||
alignItems: "center",
|
||
minHeight: 20,
|
||
},
|
||
detailLabel: {
|
||
fontSize: 14,
|
||
color: "#252A34",
|
||
flex: 1,
|
||
},
|
||
detailValue: {
|
||
fontSize: 14,
|
||
fontWeight: "600",
|
||
color: "#252A34",
|
||
},
|
||
|
||
// Badge Styles
|
||
badge: {
|
||
paddingHorizontal: 8,
|
||
paddingVertical: 2,
|
||
borderRadius: 4,
|
||
},
|
||
badgeText: {
|
||
fontSize: 12,
|
||
fontWeight: "500",
|
||
},
|
||
|
||
// Button Styles
|
||
buttonContainer: {
|
||
gap: 8,
|
||
},
|
||
primaryButton: {
|
||
backgroundColor: "#008761",
|
||
borderRadius: 4,
|
||
paddingVertical: 8,
|
||
paddingHorizontal: 16,
|
||
alignItems: "center",
|
||
minHeight: 40,
|
||
justifyContent: "center",
|
||
},
|
||
primaryButtonText: {
|
||
color: "#FCFCFC",
|
||
fontSize: 14,
|
||
fontWeight: "500",
|
||
},
|
||
tertiaryButton: {
|
||
borderRadius: 4,
|
||
paddingVertical: 8,
|
||
alignItems: "center",
|
||
minHeight: 36,
|
||
justifyContent: "center",
|
||
},
|
||
tertiaryButtonText: {
|
||
color: "#006C4D",
|
||
fontSize: 14,
|
||
fontWeight: "500",
|
||
},
|
||
|
||
// Plan Details Styles
|
||
planDetailsSection: {
|
||
gap: 8,
|
||
marginBottom: 20,
|
||
},
|
||
planCard: {
|
||
backgroundColor: "#FCFCFC",
|
||
borderRadius: 8,
|
||
padding: 12,
|
||
},
|
||
paymentHistorySection: {
|
||
width: 328,
|
||
marginLeft: 16,
|
||
marginTop: 20,
|
||
// No height fixed here, flexible container
|
||
},
|
||
sectionTitle: {
|
||
fontFamily: "Inter-SemiBold",
|
||
fontSize: 14,
|
||
lineHeight: 20,
|
||
color: "#252A33", // rgb(37,42,51) from design
|
||
marginBottom: 8,
|
||
},
|
||
paymentHistoryContainer: {
|
||
width: 328,
|
||
flexDirection: "column",
|
||
gap: 16, // for spacing between cards, might need polyfill or use margin
|
||
},
|
||
historyLoadingContainer: {
|
||
height: 312,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
},
|
||
loadingText: {
|
||
fontFamily: "Inter-Regular",
|
||
fontSize: 14,
|
||
color: "#252A33",
|
||
},
|
||
noDataContainer: {
|
||
height: 312,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
},
|
||
noDataText: {
|
||
fontFamily: "Inter-Regular",
|
||
fontSize: 14,
|
||
color: "#252A33",
|
||
},
|
||
noMoreDataContainer: {
|
||
marginTop: 16,
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
},
|
||
noMoreDataText: {
|
||
fontFamily: "Inter-Regular",
|
||
fontSize: 12,
|
||
color: "#5B6478", // rgb(91,100,120) muted text
|
||
},
|
||
paymentCard: {
|
||
width: 328,
|
||
height: 76,
|
||
backgroundColor: "#FCFCFC", // #FCFCFC or #FBFBFB as in design (near white)
|
||
borderRadius: 8,
|
||
paddingVertical: 12,
|
||
paddingHorizontal: 12,
|
||
marginBottom: 16,
|
||
justifyContent: "space-between",
|
||
// flexDirection: "column" by default
|
||
},
|
||
paymentCardTopRow: {
|
||
flexDirection: "row",
|
||
justifyContent: "space-between",
|
||
alignItems: "center",
|
||
height: 20,
|
||
},
|
||
paymentDate: {
|
||
fontFamily: "Inter-Regular",
|
||
fontSize: 14,
|
||
color: "#252A33",
|
||
},
|
||
paymentAmount: {
|
||
fontFamily: "Inter-SemiBold",
|
||
fontSize: 14,
|
||
color: "#252A33",
|
||
},
|
||
paymentCardBottomRow: {
|
||
flexDirection: "row",
|
||
justifyContent: "space-between",
|
||
alignItems: "center",
|
||
height: 20,
|
||
},
|
||
paymentTimeMethod: {
|
||
fontFamily: "Inter-Regular",
|
||
fontSize: 12,
|
||
color: "#56607A", // rgb(86,96,122)
|
||
},
|
||
paymentStatusBadge: {
|
||
borderRadius: 4,
|
||
paddingVertical: 2,
|
||
paddingHorizontal: 8,
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
},
|
||
paymentStatusLabel: {
|
||
fontFamily: "Inter-Medium",
|
||
fontSize: 12,
|
||
textAlign: "center",
|
||
},
|
||
// Status colors — you can override backgroundColor and color dynamically based on status
|
||
statusPending: {
|
||
backgroundColor: "#FFF0E5", // approx. (1, 0.941, 0.89)
|
||
color: "#803F0C", // approx. (0.5, 0.27, 0.047)
|
||
},
|
||
statusFailed: {
|
||
backgroundColor: "#FDDDD7", // approx. (0.99, 0.91, 0.9)
|
||
color: "#D6290A", // approx. (0.83, 0.11, 0.06)
|
||
},
|
||
statusSuccess: {
|
||
backgroundColor: "#E6F4EA", // light green example
|
||
color: "#0B8235",
|
||
},
|
||
viewAllButton: {
|
||
flexDirection: "row",
|
||
alignItems: "center",
|
||
paddingVertical: 8,
|
||
paddingHorizontal: 16,
|
||
borderRadius: 4,
|
||
},
|
||
viewAllText: {
|
||
fontFamily: "Inter-Medium",
|
||
fontSize: 14,
|
||
color: "#007958", // greenish text color
|
||
},
|
||
chevron: {
|
||
fontSize: 18,
|
||
color: "#007958",
|
||
marginLeft: 4,
|
||
},
|
||
loadMoreButton: {
|
||
paddingVertical: 8,
|
||
paddingHorizontal: 16,
|
||
borderRadius: 4,
|
||
backgroundColor: "#007958",
|
||
alignSelf: "center",
|
||
},
|
||
loadMoreText: {
|
||
fontFamily: "Inter-Medium",
|
||
fontSize: 14,
|
||
color: "#FFFFFF",
|
||
},
|
||
});
|