278 lines
8.4 KiB
TypeScript
278 lines
8.4 KiB
TypeScript
import React, { useState, useRef } from "react";
|
|
import { View, Text, TouchableOpacity, ScrollView } from "react-native";
|
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
import BackButton from "~/components/ui/backButton";
|
|
import { router, useLocalSearchParams } from "expo-router";
|
|
import { SMSIcon, WhatsappIcon } from "~/components/ui/icons";
|
|
import { RequestService } from "~/lib/services/requestService";
|
|
import { useAuthStore } from "~/lib/stores";
|
|
import { ROUTES } from "~/lib/routes";
|
|
import ModalToast from "~/components/ui/toast";
|
|
import { useTranslation } from "react-i18next";
|
|
import ScreenWrapper from "~/components/ui/ScreenWrapper";
|
|
import PermissionAlertModal from "~/components/ui/permissionAlertModal";
|
|
|
|
export default function NotificationOption() {
|
|
const params = useLocalSearchParams<{
|
|
amount: string;
|
|
recipientName: string;
|
|
recipientPhoneNumber: string;
|
|
recipientType: string;
|
|
recipientId: string;
|
|
note: string;
|
|
requestorName: string;
|
|
requestorPhoneNumber: string;
|
|
requestorType: string;
|
|
type: string;
|
|
provider?: string;
|
|
}>();
|
|
|
|
const [selectedMethod, setSelectedMethod] = useState<
|
|
"SMS" | "WhatsApp" | null
|
|
>(null);
|
|
const { user } = useAuthStore();
|
|
const isMoneyRequest = params.type === "request";
|
|
const { t } = useTranslation();
|
|
|
|
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 = React.useRef<ReturnType<typeof setTimeout> | null>(
|
|
null
|
|
);
|
|
|
|
const [confirmVisible, setConfirmVisible] = useState(false);
|
|
const [confirmTitle, setConfirmTitle] = useState("");
|
|
const [confirmMessage, setConfirmMessage] = useState("");
|
|
const confirmActionRef = useRef<() => void>(() => {});
|
|
|
|
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);
|
|
};
|
|
|
|
const handleMoneyRequest = async (notificationMethod: "SMS" | "WhatsApp") => {
|
|
if (!user?.uid) {
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
t("notificationOption.toastAuthRequired"),
|
|
"error"
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (!params.amount || !params.recipientName || !params.requestorName) {
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
t("notificationOption.toastMissingInfo"),
|
|
"error"
|
|
);
|
|
return;
|
|
}
|
|
|
|
const amountInCents = parseInt(params.amount);
|
|
if (isNaN(amountInCents) || amountInCents <= 0) {
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
t("notificationOption.toastInvalidAmount"),
|
|
"error"
|
|
);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const result = await RequestService.createRequest(user.uid, {
|
|
requestorName: params.requestorName,
|
|
requesteeName: params.recipientName,
|
|
requestorPhoneNumber: params.requestorPhoneNumber || "",
|
|
requesteePhoneNumber: params.recipientPhoneNumber,
|
|
requestorType: params.requestorType as "saved" | "contact",
|
|
amount: amountInCents,
|
|
note: params.note || "",
|
|
status: "pending" as const,
|
|
notificationMethod,
|
|
});
|
|
|
|
if (result.success) {
|
|
// Navigate to success screen
|
|
router.replace({
|
|
pathname: ROUTES.MONEY_REQUESTED,
|
|
params: {
|
|
fullName: params.recipientName,
|
|
requesteePhoneNumber: params.recipientPhoneNumber,
|
|
},
|
|
});
|
|
} else {
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
result.error || t("notificationOption.toastCreateFailed"),
|
|
"error"
|
|
);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error requesting money:", error);
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
t("notificationOption.toastRequestFailed"),
|
|
"error"
|
|
);
|
|
}
|
|
};
|
|
|
|
const handleMethodSelection = (method: "SMS" | "WhatsApp") => {
|
|
setSelectedMethod(method);
|
|
};
|
|
|
|
const handleProceed = () => {
|
|
if (!selectedMethod) {
|
|
showToast(
|
|
t("notificationOption.toastErrorTitle"),
|
|
t("notificationOption.toastSelectMethod"),
|
|
"error"
|
|
);
|
|
return;
|
|
}
|
|
|
|
const description = `Your money request will be sent to the selected donor and will be notified via ${selectedMethod}.`;
|
|
const title = `${selectedMethod} Notification`;
|
|
|
|
setConfirmTitle(title);
|
|
setConfirmMessage(description);
|
|
|
|
if (isMoneyRequest) {
|
|
confirmActionRef.current = () => handleMoneyRequest(selectedMethod);
|
|
} else {
|
|
confirmActionRef.current = () => {
|
|
console.log(`${selectedMethod} notification selected`);
|
|
router.back();
|
|
};
|
|
}
|
|
|
|
setConfirmVisible(true);
|
|
};
|
|
|
|
return (
|
|
<ScreenWrapper edges={["top"]}>
|
|
{/* Header with close button */}
|
|
<View className="flex-row items-center justify-between">
|
|
<BackButton />
|
|
</View>
|
|
|
|
{/* Main content */}
|
|
<ScrollView className="flex-1 px-5 pt-10">
|
|
{/* Title */}
|
|
<View className="items-center mb-8">
|
|
<Text className="text-3xl font-dmsans-bold text-black">
|
|
{t("notificationOption.title")}
|
|
</Text>
|
|
</View>
|
|
<View className="h-8" />
|
|
|
|
{/* Notification Options Section */}
|
|
<View className="mb-8">
|
|
<Text className="text-lg font-dmsans-bold text-primary mb-2">
|
|
{t("notificationOption.sectionTitle")}
|
|
</Text>
|
|
<Text className="text-gray-600 font-dmsans text-base">
|
|
{t("notificationOption.sectionSubtitle")}
|
|
</Text>
|
|
</View>
|
|
|
|
{/* SMS Notification Option */}
|
|
<TouchableOpacity
|
|
onPress={() => handleMethodSelection("SMS")}
|
|
className={`rounded-lg p-4 mb-4 flex-row items-center ${
|
|
selectedMethod === "SMS"
|
|
? "bg-green-50 border-2 border-primary"
|
|
: "bg-green-50 border border-gray-200"
|
|
}`}
|
|
>
|
|
<View className="p-3 mr-4">
|
|
<SMSIcon />
|
|
</View>
|
|
<View className="flex-1">
|
|
<Text className="font-dmsans-bold text-lg text-black">
|
|
{t("notificationOption.smsLabel")}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
|
|
{/* WhatsApp Notification Option */}
|
|
<TouchableOpacity
|
|
onPress={() => handleMethodSelection("WhatsApp")}
|
|
className={`rounded-lg p-4 flex-row items-center ${
|
|
selectedMethod === "WhatsApp"
|
|
? "bg-green-50 border-2 border-primary"
|
|
: "bg-green-50 border border-gray-200"
|
|
}`}
|
|
>
|
|
<View className="p-3 mr-4">
|
|
<WhatsappIcon />
|
|
</View>
|
|
<View className="flex-1">
|
|
<Text className="font-dmsans-bold text-lg text-black">
|
|
{t("notificationOption.whatsappLabel")}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
</ScrollView>
|
|
|
|
{/* Proceed Button - Only visible when a method is selected */}
|
|
{selectedMethod && (
|
|
<View className="px-5">
|
|
<TouchableOpacity
|
|
onPress={handleProceed}
|
|
className="bg-primary rounded-3xl items-center py-3"
|
|
>
|
|
<Text className="text-white font-dmsans-bold text-lg">
|
|
{t("notificationOption.continueButton")}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
<View className="h-4" />
|
|
<ModalToast
|
|
visible={toastVisible}
|
|
title={toastTitle}
|
|
description={toastDescription}
|
|
variant={toastVariant}
|
|
/>
|
|
|
|
<PermissionAlertModal
|
|
visible={confirmVisible}
|
|
title={confirmTitle}
|
|
message={confirmMessage}
|
|
primaryText="OK"
|
|
secondaryText="Don't Allow"
|
|
onPrimary={() => {
|
|
setConfirmVisible(false);
|
|
confirmActionRef.current && confirmActionRef.current();
|
|
}}
|
|
onSecondary={() => {
|
|
setConfirmVisible(false);
|
|
}}
|
|
/>
|
|
</ScreenWrapper>
|
|
);
|
|
}
|