Untitled

 avatar
unknown
plain_text
16 days ago
25 kB
3
Indexable
import React, { useState, useRef, useEffect, useCallback } from "react";
import {
  Image,
  SafeAreaView,
  ScrollView,
  StatusBar,
  Text,
  TouchableOpacity,
  View,
  KeyboardAvoidingView,
  Platform,
  Modal,
} from "react-native";
import tw from "twrnc";
import { useFocusEffect } from "@react-navigation/native";
import Config from "../../config";
import { useNavigation } from "@react-navigation/native";
import { Ionicons } from "@expo/vector-icons";
import { TextInput } from "react-native-gesture-handler";
import { useSelector } from "react-redux";
import axios from "axios";

const CheckoutScreen = ({ route, visible }) => {
  const navigation = useNavigation();
  const [modalVisible, setModalVisible] = useState(false); // Controls offer price modal
  const [selectedOption, setSelectedOption] = useState("suggested");
  const [phoneNumber, setPhoneNumber] = useState("");
  const token = useSelector((state) => state?.user?.token);
  const [otp, setOtp] = useState(["", "", "", ""]);
  const [countdown, setCountdown] = useState(59);
  const { checkoutData } = route.params || {};
  const [timerExpired, setTimerExpired] = useState(false);
  const [focusedIndex, setFocusedIndex] = useState(null);
  const [otpRequested, setOtpRequested] = useState(false);

  const inputRefs = useRef([]);
  const [shippingAddress, setShippingAddress] = useState(null);
  const [billingAddress, setBillingAddress] = useState(null);

  const addressesRef = useRef({
    shipping: null,
    billing: null
  });
  const handleOtpRequest = () => {
    if (!otpRequested) {
      // Call your OTP request function
      setModalVisible(true);
      setOtpRequested(true); // Update state to change button text
    } else {
      // Submit the OTP
      handleSubmit();
      setModalVisible(false);
    }
  };

  const handlePhoneNumberChange = (text) => {
    // Remove non-numeric characters and limit to 10 digits
    const formattedText = text.replace(/\D/g, "").slice(0, 10);
    setPhoneNumber(formattedText);
  };

  const handleBack = () => {
    navigation.goBack();
  };
  const handleSubmit = () => {
    // setModalVisible(false); // Close offer price modal
    // setSubmittedModalVisible(true); // Open offer submitted modal
  };

  useFocusEffect(
    useCallback(() => {
      if (route.params?.selectedAddress && route.params?.addressType) {
        const address = route.params.selectedAddress;
        const addressType = route.params.addressType;
        const formattedAddress = formatAddress(address);

        // Update the ref for the specific address type
        addressesRef.current[addressType] = formattedAddress;

        // Update the state
        if (addressType === 'shipping') {
          setShippingAddress(formattedAddress);
        } else if (addressType === 'billing') {
          setBillingAddress(formattedAddress);
        }
      }

      // If addresses are not set yet, try to use the ones from ref
      if (!shippingAddress && addressesRef.current.shipping) {
        setShippingAddress(addressesRef.current.shipping);
      }

      if (!billingAddress && addressesRef.current.billing) {
        setBillingAddress(addressesRef.current.billing);
      }

      // If addresses are still not available, fetch from API
      if (!shippingAddress && !addressesRef.current.shipping) {
        fetchShippingAddress();
      }

      if (!billingAddress && !addressesRef.current.billing) {
        fetchBillingAddress();
      }

      return () => { };
    }, [route.params, shippingAddress, billingAddress])
  );

  // Split the fetch functions
  const fetchShippingAddress = async () => {
    if (!token) return;

    try {
      const response = await axios.get(`${Config.API_BASE_URL}/shippingAddress`, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      if (response.data?.addresses && response.data?.addresses.length > 0) {
        const formattedAddress = formatAddress(response.data.addresses[0]);
        addressesRef.current.shipping = formattedAddress;
        setShippingAddress(formattedAddress);
      }
    } catch (error) {
      console.error("Failed to fetch shipping address:", error);
    }
  };

  const fetchBillingAddress = async () => {
    if (!token) return;

    try {
      const response = await axios.get(`${Config.API_BASE_URL}/billingAddress`, {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      if (response.data?.addresses && response.data?.addresses.length > 0) {
        const formattedAddress = formatAddress(response.data.addresses[0]);
        addressesRef.current.billing = formattedAddress;
        setBillingAddress(formattedAddress);
      }
    } catch (error) {
      console.error("Failed to fetch billing address:", error);
    }
  };


  const formatAddress = (addressData) => {
    return {
      name: addressData.name || "User",
      phone: addressData.phoneNumber,
      address: `${addressData.address1}${addressData.address2 ? `, ${addressData.address2}` : ''}${addressData.landmark ? `, ${addressData.landmark}` : ''}`,
    };
  };

  useEffect(() => {
    if (countdown > 0) {
      const timer = setTimeout(() => {
        setCountdown(countdown - 1);
      }, 1000);
      return () => clearTimeout(timer);
    } else {
      setTimerExpired(true);
    }
  }, [countdown]);

  const handleOtpChange = (value, index) => {
    const newOtp = [...otp];

    if (/^[0-9]?$/.test(value)) {
      newOtp[index] = value;
      setOtp(newOtp);

      if (value && index < 3) {
        inputRefs.current[index + 1].focus();
      } else if (!value && index > 0) {
        inputRefs.current[index - 1].focus();
      }
    }
  };

  const handleResendCode = () => {
    setOtp(["", "", "", ""]);
    setCountdown(59);
    setTimerExpired(false);
    console.log("Resending OTP code");
    inputRefs.current[0].focus();
  };

  const handleKeyPress = (e, index) => {
    if (e.nativeEvent.key === "Backspace" && !otp[index] && index > 0) {
      inputRefs.current[index - 1].focus();
    }
  };

  const handleFocus = (index) => {
    setFocusedIndex(index);
  };

  const handleBlur = () => {
    setFocusedIndex(null);
  };

  const promoCodeApplied = true;
  const promoCode = "SAVE10";
  const promoDescription = "Get 10% off on your order";
  return (
    <SafeAreaView style={tw`flex-1 bg-white`}>
      <StatusBar backgroundColor="#FDE504" />
      <KeyboardAvoidingView
        behavior={Platform.OS === "ios" ? "padding" : "height"}
        style={tw`flex-1`}
      >
        <View style={tw`bg-[#FDE504] h-[48px]`}>
          <View style={tw`flex-row items-center px-4 pt-4 ml-2 `}>
            <TouchableOpacity onPress={handleBack}>
              <Ionicons name="chevron-back" size={24} color="black" />
            </TouchableOpacity>
          </View>
        </View>
        <View style={tw`px-5 py-3`}>
          <Text style={[tw`text-base `, { fontFamily: "Karla-Bold" }]}>
            Order Details
          </Text>
        </View>
        <ScrollView
          style={tw`flex-1`}
          contentContainerStyle={tw`pb-4 flex-grow`}
        >
          <View style={tw`w-full border-b-4 border-[#FFFBE1] mb-2`} />

          <View style={tw`w-full py-[22px]`}>
            {/* Shipping Address Section */}
            <View style={tw`flex-row justify-between px-5`}>
              <Text
                style={[
                  tw`text-center text-neutral-900 text-base leading-tight`,
                  { fontFamily: "Karla-Bold" },
                ]}
              >
                Shipping Address
              </Text>
              {shippingAddress && (
                <TouchableOpacity
                  onPress={() => navigation.navigate("EditAddress", { type: "shipping" })}
                >
                  <Text
                    style={[
                      tw`text-center text-neutral-900 text-[12px] leading-tight`,
                      { fontFamily: "Karla-Bold" },
                    ]}
                  >
                    Change
                  </Text>
                </TouchableOpacity>
              )}
            </View>

            {shippingAddress ? (
              <View
                style={tw`h-20 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex justify-start items-start`}
              >
                <Text
                  style={[
                    tw`text-neutral-900 text-sm  mb-2`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  Phone - {shippingAddress.phone}
                </Text>
                <Text
                  style={[
                    tw`text-neutral-400 text-xs `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  {shippingAddress.address}
                </Text>
              </View>
            ) : (
              <TouchableOpacity
                style={tw`h-20 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex-row justify-start items-center gap-[20px]`}
                onPress={() => navigation.navigate("AddAddress", { type: "shipping" })}
              >
                <Text style={tw`text-2xl text-[#1F2125] mr-4`}>+</Text>
                <Text style={tw`text-base text-black`}>
                  Add Shipping Address
                </Text>
              </TouchableOpacity>
            )}

            {/* Billing Address Section */}
            <View style={tw`flex-row justify-between px-5`}>
              <Text
                style={[
                  tw`text-center text-neutral-900 text-base leading-tight`,
                  { fontFamily: "Karla-Bold" },
                ]}
              >
                Billing Address
              </Text>
              {billingAddress && (
                <TouchableOpacity
                  onPress={() => navigation.navigate("EditAddress", { type: "billing" })}
                >
                  <Text
                    style={[
                      tw`text-center text-neutral-900 text-[12px] leading-tight`,
                      { fontFamily: "Karla-Bold" },
                    ]}
                  >
                    Change
                  </Text>
                </TouchableOpacity>
              )}
            </View>

            {billingAddress ? (
              <View
                style={tw`h-20 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex justify-start items-start`}
              >
                <Text
                  style={[
                    tw`text-neutral-900 text-sm  mb-2`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  Phone - {billingAddress.phone}
                </Text>
                <Text
                  style={[
                    tw`text-neutral-400 text-xs `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  {billingAddress.address}
                </Text>
              </View>
            ) : (
              <TouchableOpacity
                style={tw`h-15 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex-row justify-start items-center gap-[20px]`}
                onPress={() => navigation.navigate("AddAddress", { type: "billing" })}
              >
                <Text style={tw`text-3xl text-[#1F2125] mr-4`}>+</Text>
                <Text
                  style={[
                    tw`text-base text-black`,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Add Billing Address
                </Text>
              </TouchableOpacity>
            )}

            <View style={tw`w-full border-b-4 border-[#FFFBE1] mb-2`} />
          </View>
          <View style={tw`w-full pb-[22px]`}>
            <View style={tw`flex-row justify-between px-5`}>
              <Text
                style={[
                  tw`text-center text-neutral-900 text-base  leading-tight`,
                  { fontFamily: "Karla-Bold" },
                ]}
              >
                Payment Method
              </Text>
              <Text
                style={[
                  tw`text-center text-neutral-900 text-[12px] leading-tight`,
                  { fontFamily: "Karla-Bold" },
                ]}
              >
                See All
              </Text>
            </View>
            <View
              style={tw`h-20 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex-row justify-start items-center gap-[20px]`}
            >
              <View>
                <Image
                  source={require("../../assets/checkout/mastercard.png")}
                  style={tw`h-7 w-10`}
                />
              </View>
              <View>
                <Text
                  style={[
                    tw`text-neutral-900 text-sm mb-1`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  Mastercard
                </Text>
                <Text
                  style={[
                    tw`text-neutral-400 text-xs`,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Checked Automatically
                </Text>
              </View>
            </View>
            <View style={tw`w-full border-b-4 border-[#FFFBE1] mb-2`} />
          </View>
          <View style={tw`w-full pb-[22px]`}>
            <View style={tw`flex-row justify-between px-5`}>
              <Text
                style={[
                  tw`text-center text-neutral-900 text-base  leading-tight`,
                  { fontFamily: "Karla-Bold" },
                ]}
              >
                Voucher
              </Text>
            </View>
            <View style={tw`w-full py-[12px]`}>
              {/* Promo Code Section */}
              {promoCodeApplied ? (
                <View
                  style={tw`h-15 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex-row justify-start items-center gap-[20px]`}
                >
                  <View>
                    <Image
                      source={require("../../assets/checkout/Discount.png")}
                      style={tw`h-5 w-5`}
                    />
                  </View>
                  <View>
                    <Text
                      style={[
                        tw`text-[#1F2125] text-sm  mb-1`,
                        { fontFamily: "Karla-Bold" },
                      ]}
                    >
                      One promo was applied
                    </Text>
                  </View>
                  <View style={tw`flex-row items-center px-4  ml-12`}>
                    <TouchableOpacity onPress={handleBack}>
                      <Ionicons
                        name="chevron-forward"
                        size={24}
                        color="black"
                      />
                    </TouchableOpacity>
                  </View>
                </View>
              ) : (
                <TouchableOpacity
                  style={tw`h-15 border rounded-[12px] border-gray-200 ml-[16px] mr-4 mt-[12px] mb-[22px] p-4 flex-row justify-start items-center gap-[20px]`}
                  onPress={() => navigation.navigate("Coupons")}
                >
                  <Text style={tw`text-3xl text-[#1F2125]`}>+</Text>
                  <Text
                    style={[
                      tw`text-base text-black`,
                      { fontFamily: "Karla-Regular" },
                    ]}
                  >
                    Apply Promo Code
                  </Text>
                </TouchableOpacity>
              )}
            </View>
            <View>
              <View style={tw`flex-row justify-between px-4 mt-[50px]`}>
                <Text
                  style={[
                    tw`text-neutral-900 text-sm `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Unit Cost
                </Text>
                <Text
                  style={[
                    tw`text-right text-neutral-900 text-sm leading-none`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  {checkoutData?.totalAmount || "0"} د.إ
                </Text>
              </View>
              <View style={tw`flex-row justify-between px-4 mt-[11px]`}>
                <Text
                  style={[
                    tw`text-neutral-900 text-sm `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Qty
                </Text>
                <Text
                  style={[
                    tw`text-right text-neutral-900 text-sm leading-none`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  {checkoutData?.totalQuantity || "0"}
                </Text>
              </View>
              <View style={tw`flex-row justify-between px-4 mt-[11px]`}>
                <Text
                  style={[
                    tw`text-neutral-900 text-sm `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Discount
                </Text>
                <Text
                  style={[
                    tw`text-right text-[#30BD75] text-sm  leading-none`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  {checkoutData?.discountAmount || "0"} د.إ -
                </Text>
              </View>
              <View style={tw`flex-row justify-between px-4 mt-[11px]`}>
                <Text
                  style={[
                    tw`text-neutral-900 text-sm `,
                    { fontFamily: "Karla-Regular" },
                  ]}
                >
                  Shipping Cost
                </Text>
                <Text
                  style={[
                    tw`text-right text-neutral-900 text-sm  leading-none`,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  20 د.إ
                </Text>
              </View>
              <View
                style={tw`border-t border-dashed border-gray-300 my-2 ml-4 mr-4 mt-[11px]`}
              />
              <View style={tw`flex-row justify-between px-4 mt-[20px]`}>
                <Text
                  style={[
                    tw`text-neutral-900 text-base `,
                    { fontFamily: "Karla-Bold" },
                  ]}
                >
                  Total
                </Text>
                <Text
                  style={tw`text-right text-neutral-900 text-sm font-bold leading-none`}
                >
                  {checkoutData?.finalTotal || "0"} د.إ
                </Text>
              </View>
            </View>
          </View>
        </ScrollView>
        <View style={tw`p-4`}>
          <TouchableOpacity style={tw`bg-[#FDE504] p-[15px] rounded-xl`}>
            <Text
              style={[
                tw`text-center text-[16px]`,
                { fontFamily: "Karla-Bold" },
              ]}
            >
              Checkout
            </Text>
          </TouchableOpacity>
        </View>
      </KeyboardAvoidingView>
      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => setModalVisible(false)}
      >
        <View style={tw`flex-1 justify-end`}>
          <View style={tw`bg-black bg-opacity-50 absolute inset-0`} />

          <View style={tw`items-center mb-4`}>
            <TouchableOpacity
              style={tw`bg-gray-300 rounded-full p-2 mt-2`}
              onPress={() => setModalVisible(false)}
            >
              <Ionicons name="close" size={20} color="#000" />
            </TouchableOpacity>
          </View>

          <View style={tw`bg-white rounded-t-[20px] p-4 mt-[22px]`}>
            <View style={tw`mb-[12px]`}>
              <Text style={[tw`text-[22px] text-[#070707] mb-1`, { fontFamily: "Karla-Bold" }]}>
                Verify Your Phone Number
              </Text>

              <Text style={[tw`text-[14px] w-[328px] h-[44px]`, { fontFamily: "Karla-Regular" }]}>
                To use KUKU, we need to verify your phone number. We will never
                display this number publicly.
              </Text>
            </View>
            <View
              style={tw`flex-row border border-gray-200 rounded-[12px] px-4 items-center mb-5 bg-[#F7F7F7] h-[56px]`}
            >
              <View
                style={tw`flex-row items-center pr-2 border-r border-r-gray-200`}
              >
                <Image
                  source={require("../../assets/login/uae-flag.png")}
                  style={tw`w-4 h-2.5 mr-1`}
                />
                <Text style={[tw`text-gray-700 text-sm mr-1`, { fontFamily: "Karla-Regular" }]}>+971</Text>
                <Ionicons name="chevron-down" size={12} color="#666" />
              </View>
              <TextInput
                placeholder="Phone Number"
                style={[tw`flex-1 pl-2 text-gray-700 text-base`, { fontFamily: "Karla-Regular" }]}
                keyboardType="phone-pad"
                placeholderTextColor="#999"
                value={phoneNumber}
                onChangeText={handlePhoneNumberChange}
                maxLength={10} // Ensures max length of 10
              />
            </View>
            <View style={tw`flex-row justify-center gap-4 mb-4 mt-[16px]`}>
              {otp.map((digit, index) => (
                <View
                  key={index}
                  style={[
                    tw`w-16 h-16 border-2 rounded-lg justify-center items-center `,
                    {
                      backgroundColor: "#F7F7F7",
                      borderColor:
                        digit || focusedIndex === index ? "#FFEB3B" : "#E0E0E0",
                    },
                  ]}
                >
                  <TextInput
                    ref={(el) => (inputRefs.current[index] = el)}
                    style={[
                      tw`text-xl font-bold w-full h-full`,
                      { textAlign: "center", textAlignVertical: "start" },
                    ]}
                    keyboardType="number-pad"
                    maxLength={1}
                    value={digit}
                    onChangeText={(value) => handleOtpChange(value, index)}
                    onKeyPress={(e) => handleKeyPress(e, index)}
                    onFocus={() => handleFocus(index)}
                    onBlur={handleBlur}
                    selectTextOnFocus
                    placeholder="0"
                    placeholderTextColor="#e5e5e5"
                  />
                </View>
              ))}
            </View>
            {timerExpired ? (
              <View style={tw`flex-row justify-center mb-8`}>
                <Text style={[tw`text-gray-500 text-sm`, { fontFamily: "Karla-Regular" }]}>
                  Didn't received code?{" "}
                </Text>
                <TouchableOpacity onPress={handleResendCode}>
                  <Text style={[tw`text-gray-800 text-sm`, { fontFamily: "Karla-SemiBold" }]}>
                    Resend Code
                  </Text>
                </TouchableOpacity>
              </View>
            ) : (
              <Text
                style={[tw`text-center text-gray-800 w-[328px] h-[52px] mb-8`, { fontFamily: "Karla-Regular" }]}
              >
                You can resend code in {countdown} sec
              </Text>
            )}
            <TouchableOpacity
              style={tw`bg-[#FDE504] rounded-lg py-4 items-center mb-4 h-[56px]`}
              onPress={handleOtpRequest}
            >
              <Text style={tw`text-karla-700 font-medium text-[16px]`}>
                {otpRequested ? "Submit" : "Get OTP"}
              </Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </SafeAreaView>
  );
};

export default CheckoutScreen;
Editor is loading...
Leave a Comment