import React, { useState, useEffect } from "react"; import { ViewMode } from "../../services/types"; import { useLocation, useNavigate } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { Area, CheckoutDetailResponse, Package, PaymentChannel, } from "../../services/product/type"; import { DataCacheKey, staleTime } from "../../global/constants"; import { startLoading, startSmallLoading, stopLoading, stopSmallLoading, } from "../../features/loading/loadingSlice"; import { useAppDispatch, useAppSelector } from "../../hooks/useRedux"; import { productApi } from "../../apis/productApi"; import { openPopup } from "../../features/popup/popupSlice"; import { formatNumber } from "../../logic/loigicUtils"; import { useTranslation } from "react-i18next"; const CheckoutView = () => { const navigate = useNavigate(); const dispatch = useAppDispatch(); const { t } = useTranslation(); const loading = useAppSelector((state) => state.loading); const accountInfo = localStorage.getItem("accountInfo"); const [paymentMethod, setPaymentMethod] = useState("card"); const [form, setForm] = useState({ firstName: "", lastName: "", email: accountInfo != null ? JSON.parse(accountInfo).email : "", confirmEmail: accountInfo != null ? JSON.parse(accountInfo).email : "", phone: "", }); const [agreements, setAgreements] = useState({ terms: false, esim: false, vatInvoice: false, }); // get data from previous step const location = useLocation(); const state = location.state as { area: Area; package: Package; quantity: number; simType: "eSIM" | "Physical"; checkoutDetails: CheckoutDetailResponse; }; const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setForm((prev) => ({ ...prev, [name]: value })); }; const handleSubmit = async () => { console.log(form); if (form.email !== form.confirmEmail) { dispatch( openPopup({ isSuccess: false, title: "Error", message: "Email and Confirm Email do not match.", }) ); return; } // proceed to payment dispatch(startSmallLoading()); const res = await productApi.confirmOrder({ surName: form.lastName, lastName: form.firstName, email: form.email, phoneNumber: form.phone, paymentChannelId: paymentMethod, packgId: state.package.id, quantity: state.quantity, }); console.log("Confirm order response:", res); dispatch(stopSmallLoading()); if (res.errorCode === "0") { // open other website to pay window.location.href = res.data.paymentUrl; } else { dispatch( openPopup({ isSuccess: false, title: "Error", message: res.message || "Failed to confirm order.", }) ); } }; const handleCheckboxChange = (e: React.ChangeEvent) => { const { name, checked } = e.target; setAgreements((prev) => ({ ...prev, [name]: checked, })); }; const { data: loadPaymentChannel = [] } = useQuery({ queryKey: [DataCacheKey.PAYMENT_CHANNELS], queryFn: async (): Promise => { try { dispatch(startLoading({})); const res = await productApi.loadPaymentChannel(); // save to redux store return res.data as PaymentChannel[]; } catch (error) { console.error(error); return []; // 🔴 bắt buộc } finally { dispatch(stopLoading()); } }, staleTime: staleTime, }); useEffect(() => { setPaymentMethod(loadPaymentChannel[0]?.id); dispatch(stopSmallLoading()); }, [loadPaymentChannel]); // Styles matching LoginView inputs const inputClass = "w-full bg-slate-50 border-2 border-transparent focus:border-[#EE0434]/20 rounded-2xl py-3 md:py-4 px-5 focus:outline-none focus:bg-white transition-all text-slate-700 font-bold placeholder:text-slate-300"; const labelClass = "block text-slate-400 font-black text-[14px] uppercase tracking-[0.2em] pl-1 mb-2"; if (!state.checkoutDetails) { return null; } return (
{/* Header / Breadcrumb */}
{/* Progress Steps */}
{t("chooseProduct")}
2
{t("orderInformation")}
3
{t("paymentPayment")}
{/* Customer Information */}

{t("customerInformation")}

{/* Order Info */}

{t("orderInformation")}

eSIM {state.area.areaName1}

{/* {state.package.amountData} - */} {state.package.dayDuration} days • x{state.quantity}

{formatNumber(state.checkoutDetails.totalMoney)}{" "} {state.checkoutDetails.curency}

{formatNumber(state.checkoutDetails.paymentMoney)}{" "} {state.checkoutDetails.curency}

{/* Payment Method */}

{t("paymentPayment")}

{loadPaymentChannel.map((method) => ( ))}
{/* Terms */}
{/* Overview Card */}

Overview

{t("subtotal")}: {formatNumber( state.checkoutDetails.totalMoney * state.quantity )}{" "} {state.checkoutDetails.curency}
Discount: -{formatNumber(0 * state.quantity)}{" "} {state.checkoutDetails.curency}
{t("totalTotal")} ({state.quantity}): {formatNumber(state.checkoutDetails.paymentMoney)}{" "} {state.checkoutDetails.curency}
); }; export default CheckoutView;