Commit b7457249 by G

refactor: navigations flow. planning for screens to take the full object instead…

refactor: navigations flow. planning for screens to take the full object instead of selective properties. This is to avoid basic crashes that may happen when one piece of data is missing through the navigation. and some biome formatting. refactor: navigations flow. planning for screens to take the full object instead of selective properties. This is to avoid basic crashes that may happen when one piece of data is missing through the navigation. Some files where impacted so changes where applied there too.
parent 18e1098c
import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/Types";
import {
type IorangePaymentStarter,
getTransactionStatus,
getTransactionsData,
} from "@/utils/requests/orangePayment";
import ErrorModal from "@components/modals/ErrorModal";
import LoadingModal from "@components/modals/LoadingModal";
import { LOG } from "@logger";
import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { AxiosError } from "axios";
import * as WebBrowser from "expo-web-browser";
import { useRef, useState } from "react";
import { AppState, Platform } from "react-native";
import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/types";
import {
getTransactionStatus,
getTransactionsData,
type IorangePaymentStarter,
} from "@/utils/requests/orangePayment";
const log = LOG.extend("useOrangeMoney");
......@@ -40,7 +38,7 @@ const useOrangeMoney = (
const [isBrowserOpen, setIsBrowserOpen] = useState(false);
const { showModal, closeModal } = useModalsManagerContext();
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);
const [_appStateVisible, _setAppStateVisiblee] = useState(appState.current);
const handlePaymentUsingBrowser = async (url: string) => {
setIsBrowserOpen(true);
......@@ -56,7 +54,7 @@ const useOrangeMoney = (
...paymentObjectDefault,
montant: amount,
}),
onSuccess: (data) => {
onSuccess: (_data) => {
// return data.payment_url
log.debug("orangeTransactionInitializerMutation request success, opening browser...");
queryClient.invalidateQueries({ queryKey: ["transactionsHistory"] });
......@@ -69,8 +67,8 @@ const useOrangeMoney = (
},
});
const maxRetry = 3;
const retryDelay = 5000;
const _maxRetry = 3;
const _retryDelay = 5000;
const transactionsStatusMutation = useMutation({
mutationFn: (orderId: string) => getTransactionStatus(orderId),
......
import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/Types";
import {
type IwavePaymentStarter,
getTransactionStatus,
initTransaction,
} from "@/utils/requests/wavePayment";
import ErrorModal from "@components/modals/ErrorModal";
import LoadingModal from "@components/modals/LoadingModal";
import { LOG } from "@logger";
......@@ -12,6 +5,13 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import * as WebBrowser from "expo-web-browser";
import { useState } from "react";
import { useModalsManagerContext } from "@/contexts/ModalsManagerContext";
import type { IpaymentStackNavigator } from "@/navigations/types";
import {
getTransactionStatus,
type IwavePaymentStarter,
initTransaction,
} from "@/utils/requests/wavePayment";
const log = LOG.extend("useWave");
......@@ -31,9 +31,9 @@ const useWave = (
>,
) => {
const { showModal, closeModal } = useModalsManagerContext();
const [isBrowserOpen, setIsBrowserOpen] = useState(false);
const [_isBrowserOpen, setIsBrowserOpen] = useState(false);
const queryClient = useQueryClient();
const _queryClient = useQueryClient();
// Mutations
......@@ -43,7 +43,7 @@ const useWave = (
...paymentObjectDefault,
montant: amount,
}),
onSuccess: (data) => {},
onSuccess: (_data) => {},
onError: (err) => {
log.error("waveTransactionInitializerMutation |", err);
},
......@@ -51,7 +51,7 @@ const useWave = (
const waveTransactionStatusMutation = useMutation({
mutationFn: (orderId: string) => getTransactionStatus(orderId),
onSuccess: (data) => {
onSuccess: (_data) => {
log.debug("waveTransactionStatusMutation request success");
},
onError: (err) => {
......@@ -71,7 +71,7 @@ const useWave = (
setIsBrowserOpen(false);
};
const openBrowserThenCheckStatus = async (paymentUrl: string, orderId: string) => {
const _openBrowserThenCheckStatus = async (paymentUrl: string, orderId: string) => {
try {
await handlePaymentUsingBrowser(paymentUrl);
log.info("openBrowserThenCheckStatus | Verifying transaction status...");
......@@ -128,7 +128,7 @@ const useWave = (
log.info("handlePaymentVerification |", id);
try {
showModal(<LoadingModal message="Vérification du statut de la transaction..." />);
const response = await waveTransactionStatusMutation.mutateAsync(id);
const _response = await waveTransactionStatusMutation.mutateAsync(id);
closeModal();
} catch (error) {
log.error("handlePaymentVerification |", error);
......
......@@ -8,7 +8,7 @@ import { memo } from "react";
import { useSelector } from "react-redux";
import type { RootState } from "@/redux";
import { AppBottomTabsNavigator } from "./AppBottomTabsNavigator";
import type { ImainStackNavigator } from "./Types";
import type { ImainStackNavigator } from "./types";
const Stack = createNativeStackNavigator<ImainStackNavigator>();
......
......@@ -2,7 +2,7 @@ import { createNativeStackNavigator } from "@react-navigation/native-stack";
import HomePageWithPaymentOptions from "@screens/HomePageWithPaymentOptions";
import NumberAndOtpForPaymentScreen from "@screens/NumberAndOtpForPaymentScreen";
import PaymentAmountInputScreen from "@screens/PaymentAmountInputScreen";
import type { IpaymentStackNavigator } from "./Types";
import type { IpaymentStackNavigator } from "./types";
const Stack = createNativeStackNavigator<IpaymentStackNavigator>();
......
import type { PaymentCode } from "@/utils/requests/types";
import type { IwaveStarterRespone } from "@/utils/requests/wavePayment";
import type { NativeStackScreenProps } from "@react-navigation/native-stack";
import type { PaymentType } from "@/features/pay/types";
import type { IwaveStarterRespone } from "@/utils/requests/wavePayment";
export type IpaymentStackNavigator = {
homePageWithPaymentOptions: undefined;
numberAndOtpForPaymentScreen: undefined;
numberAndOtpForPaymentScreen: {
paymentType: PaymentType;
amount: number;
};
paymentAmountInputScreen: {
paymentType: PaymentCode;
paymentType: PaymentType;
};
};
......
import type { PaymentStackScreenComponentProps } from "@/navigations/Types";
import getPaymentTypes from "@/utils/requests/getPaymentTypes";
import BalanceContainer from "@components/BalanceContainer";
import BarWithBeasyAndNotificationsIcon from "@components/BarWithBeasyAndNotificationsIcon";
import PaymentOption from "@components/PaymentOption";
import Box from "@components/bases/Box";
import WrapperWithDefaultBeasyBackgroundAndSafeAreaTopLeftRight from "@components/wrappers/WrapperWithDefaultBeasyBackgroundAndSafeAreaTopLeftRight";
import { asp as g } from "@asp/asp";
import { Balance } from "@components/Balance";
import { BarnoinPayBackground } from "@components/BarnoinPayBackground";
import BeasyLogoIcon from "@components/BeasyLogoIcon";
import { LOG } from "@logger";
import Card from "@re-card";
import Text from "@re-text";
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
import { Dimensions } from "react-native";
import { Text, View } from "react-native";
import { getPaymentTypes } from "@/features/pay/api";
import PaymentType from "@/features/pay/components/PaymentType";
import type { PaymentStackScreenComponentProps } from "@/navigations/types";
const log = LOG.extend("HomePageWithPaymentOptions");
const HomePageWithPaymentOptions: PaymentStackScreenComponentProps<"homePageWithPaymentOptions"> =
({ navigation }) => {
const HomePageWithPaymentOptions: PaymentStackScreenComponentProps<
"homePageWithPaymentOptions"
> = ({ navigation }) => {
log.debug("HomePageWithPaymentOptions");
const { data, isLoading, error } = useQuery({
const paymentTypesQuery = useQuery({
queryKey: ["paymentTypes"],
queryFn: getPaymentTypes,
enabled: true,
});
// getting valid payments supported
const paymentTypesWithActiveStatus = useMemo(() => {
log.info("Filtering payment types");
const paymentTypes = data?.results || [];
return paymentTypes.filter((paymentType) => paymentType.etat === true);
}, [data]);
log.info(
"payment types to render",
paymentTypesWithActiveStatus.map((paymentType) => paymentType.code),
);
const paymentTypes = paymentTypesQuery.isSuccess
? Object.keys(paymentTypesQuery.data.data.results)
.map((key) => paymentTypesQuery.data.data.results[key])
.filter((item) => item.etat === true)
: [];
return (
<WrapperWithDefaultBeasyBackgroundAndSafeAreaTopLeftRight>
<Box style={{ height: "100%" }} flexDirection={"column"}>
<BarWithBeasyAndNotificationsIcon />
<Card
variant={"curvedTopContainer"}
height={Dimensions.get("window").height / 2 + 150}
style={{ marginTop: "auto" }}
padding={"l"}
>
<Box position={"relative"} top={-120}>
<Box alignSelf={"center"}>
<BalanceContainer balance={78000} label="Total des ventes" />
</Box>
<Box marginVertical={"l"}>
<Text fontSize={20} fontWeight={"bold"}>
Types de paiement
</Text>
</Box>
<BarnoinPayBackground style={[g.flex_col, g.relative]}>
<View style={[g.px_lg]}>
<BeasyLogoIcon />
</View>
<Box
flex={1}
flexDirection={"row"}
justifyContent={"space-between"}
flexWrap={"wrap"}
rowGap={"m"}
<View
style={[
g.absolute,
g.z_10,
g.align_center,
g.justify_center,
g.w_full,
{ top: 120 },
]}
>
{isLoading && (
<Box flex={1}>
<Text textAlign={"center"}>
Chargement des méthodes de paiement...
</Text>
</Box>
)}
{!isLoading &&
!error &&
paymentTypesWithActiveStatus.map((paymentType) => (
<PaymentOptionContainer key={paymentType.id}>
<PaymentOption
// key={paymentType.id}
onPress={() =>
navigation.navigate(
"paymentAmountInputScreen",
<Balance />
</View>
<View
style={[
g.px_lg,
g.pb_lg,
g.gap_lg,
{
paymentType: paymentType.code,
backgroundColor: "white",
height: "80%",
marginTop: "auto",
borderTopRightRadius: 30,
borderTopLeftRadius: 30,
paddingTop: 150,
},
)
}
paymentMethod={paymentType.code}
]}
>
<Text style={[g.text_2xl, g.font_bold]}>Types de paiement</Text>
<View style={[g.flex_1, g.flex_wrap, g.flex_row, g.gap_lg, g.justify_between]}>
{paymentTypes.map((paymentType) => {
return (
<PaymentType
onPress={() => {
navigation.navigate("paymentAmountInputScreen", {
paymentType,
});
}}
key={paymentType.reference}
style={[{ width: "47%" }]}
type={paymentType.code}
/>
</PaymentOptionContainer>
))}
</Box>
</Box>
</Card>
</Box>
</WrapperWithDefaultBeasyBackgroundAndSafeAreaTopLeftRight>
);
};
export default HomePageWithPaymentOptions;
const screenWidth = Dimensions.get("window").width;
const paymentOptionCardWidth = screenWidth / 2 - 30;
const paymentOptionCardHeight = paymentOptionCardWidth * 0.65;
const PaymentOptionContainer = ({ children }: { children: React.ReactNode }) => {
return (
<Box
width={paymentOptionCardWidth}
height={paymentOptionCardHeight}
borderRadius={30}
overflow={"hidden"}
>
{children}
</Box>
})}
</View>
</View>
</BarnoinPayBackground>
);
};
export default HomePageWithPaymentOptions;
......@@ -2,7 +2,7 @@ import { asp as g } from "@asp/asp";
import * as Button from "@components/ButtonNew";
import { Image } from "expo-image";
import { Text, View } from "react-native";
import type { MainStackScreenComponentProps } from "@/navigations/Types";
import type { MainStackScreenComponentProps } from "@/navigations/types";
const HomeUserNotLoggedIn: MainStackScreenComponentProps<"homeUserNotLoggedIn"> = ({
navigation,
......
import type { PaymentStackScreenComponentProps } from "@/navigations/Types";
import { asp as g } from "@asp/asp";
import { BarnoinPayBackground } from "@components/BarnoinPayBackground";
import BeasyLogoIcon from "@components/BeasyLogoIcon";
import Button from "@components/Button";
import GoBackIconButton from "@components/GoBackIconButton";
import InputWithTopLabel from "@components/InputWithTopLabel";
import PaymentOption from "@components/PaymentOption";
import BackgroundGreenWhiteContentArea from "@components/backgrounds/BackgroundGreenWhiteContentArea";
import Box from "@components/bases/Box";
import Text from "@components/bases/Text";
import * as Button from "@components/ButtonNew";
import * as Input from "@components/InputNew";
import AntDesign from "@expo/vector-icons/AntDesign";
import { LOG } from "@logger";
import { SafeAreaView } from "react-native-safe-area-context";
import { Text, View } from "react-native";
import PaymentType from "@/features/pay/components/PaymentType";
import type { PaymentStackScreenComponentProps } from "@/navigations/types";
const log = LOG.extend("NumberAndOtpForPaymentScreen");
const _log = LOG.extend("NumberAndOtpForPaymentScreen");
const NumberAndOtpForPaymentScreen: PaymentStackScreenComponentProps<
"numberAndOtpForPaymentScreen"
> = ({ navigation }) => {
console.debug("NumberAndOtpForPaymentScreen");
> = ({ navigation, route }) => {
return (
<BackgroundGreenWhiteContentArea>
<SafeAreaView>
<Box style={{ height: "100%", width: "100%" }}>
<Box
px={"l"}
flexDirection={"row"}
justifyContent={"space-between"}
alignItems={"center"}
>
<BarnoinPayBackground style={[g.flex_col, g.gap_lg, g.relative]}>
<View style={[g.px_lg, g.flex_row, g.align_center, g.justify_between]}>
<BeasyLogoIcon />
<GoBackIconButton onPress={() => navigation.goBack()} />
</Box>
<Box height={122} alignItems={"center"} justifyContent={"center"}>
<Text color={"white"}>Montant à payer</Text>
<Text color={"white"} fontSize={30}>
78000
</Text>
</Box>
<Box p={"l"}>
<Box width={100} height={70} mb={"l"}>
<PaymentOption onPress={() => {}} paymentMethod={"OM"} />
</Box>
<Box mb={"l"}>
<InputWithTopLabel
label="Entrez le numero"
keyboardType="numeric"
textVariants={"black"}
/>
<InputWithTopLabel
label="Code OTP"
keyboardType="numeric"
textVariants={"black"}
<AntDesign
name="arrowleft"
size={24}
color="black"
onPress={() => navigation.goBack()}
/>
</Box>
<Button
onPress={() => {}}
variant={"full"}
textVariants={"primary"}
label="Confirmer"
/>
</Box>
</Box>
</SafeAreaView>
</BackgroundGreenWhiteContentArea>
</View>
<View style={[g.px_lg, g.align_center, g.justify_center]}>
<Text style={[g.font_bold, g.text_2xl, { color: "white" }]}>Montant à payé </Text>
<Text style={[g.font_bold, g.text_2xl, { color: "white" }]}>
{route.params.amount}
</Text>
</View>
<View
style={[
g.flex_1,
g.p_5xl,
g.gap_5xl,
{ backgroundColor: "white", borderTopLeftRadius: 20, borderTopRightRadius: 20 },
]}
>
<PaymentType type={route.params.paymentType.code} />
<Input.Container>
<Input.Header>Entrer le numéro</Input.Header>
<Input.FieldContainer>
<Input.Field keyboardType="number-pad" />
</Input.FieldContainer>
</Input.Container>
<Input.Container>
<Input.Header>Code OTP</Input.Header>
<Input.FieldContainer>
<Input.Field keyboardType="number-pad" />
</Input.FieldContainer>
</Input.Container>
<Button.Container>
<Button.Label>Confirmer</Button.Label>
</Button.Container>
</View>
</BarnoinPayBackground>
);
};
......
import type { MainStackScreenComponentProps } from "@/navigations/Types";
import BeasyLogoIcon from "@components/BeasyLogoIcon";
import Button from "@components/Button";
import GoBackIconButton from "@components/GoBackIconButton";
import BeasyDefaultBackgroundWrapper from "@components/backgrounds/BeasyDefaultBackground";
import Box from "@components/bases/Box";
import Text from "@components/bases/Text";
import GoBackIconButton from "@components/GoBackIconButton";
import CheckIcon from "@components/icons/CheckIcon";
import { LOG } from "@logger";
import { CommonActions } from "@react-navigation/native";
// import { Text } from "react-native";
import { SafeAreaView, useSafeAreaInsets } from "react-native-safe-area-context";
import type { MainStackScreenComponentProps } from "@/navigations/types";
const log = LOG.extend("PaymentResultScreen");
......
......@@ -2,7 +2,7 @@ import { asp as g } from "@asp/asp";
import { LOG } from "@logger";
import { ImageBackground, View } from "react-native";
import { LoginForm } from "@/features/auth/components/LoginForm";
import type { MainStackScreenComponentProps } from "@/navigations/Types";
import type { MainStackScreenComponentProps } from "@/navigations/types";
const log = LOG.extend("UserLoginScreen");
const UserLoginScreen: MainStackScreenComponentProps<"userLoginScreen"> = ({ navigation }) => {
......
import type { MainStackScreenComponentProps } from "@/navigations/Types";
import Button from "@components/Button";
import BackgroundWithBeasyIconAndWhiteContentArea from "@components/backgrounds/BackgroundWithBeasyIconAndWhiteContentArea";
import Box from "@components/bases/Box";
......@@ -8,6 +7,7 @@ import { LOG } from "@logger";
import { Dimensions } from "react-native";
// biome-ignore lint/style/useNamingConvention: <explanation>
import QRCode from "react-native-qrcode-svg";
import type { MainStackScreenComponentProps } from "@/navigations/types";
const log = LOG.extend("WaveQrCodePaymentScreen");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment