import React, { useState, useMemo, useEffect } from "react"; import { useLocation, useNavigate, Link, useParams } from "react-router-dom"; import { SelectedProduct } from "../../services/types"; import { Area, Package } from "../../services/product/type"; import { useMutation, useQuery } from "@tanstack/react-query"; import { DataCacheKey, staleTime } from "../../global/constants"; import { useAppDispatch, useAppSelector } from "../../hooks/useRedux"; import { startLoading, stopLoading } from "../../features/loading/loadingSlice"; import { productApi } from "../../apis/productApi"; import { openPopup } from "../../features/popup/popupSlice"; import { formatCurrency, formatNumber, getWithExpiry, } from "../../logic/loigicUtils"; import ProductInfoModal from "../../components/ProductInfoModal"; import PackageOverview from "./components/PackageOverview"; import ProductCard from "../../components/ProductCard"; import { useTranslation } from "react-i18next"; import { get } from "http"; const ProductDetailView: React.FC = () => { const location = useLocation(); const navigate = useNavigate(); const dispatch = useAppDispatch(); const { t } = useTranslation(); // let area = location.state as Area; const areas = getWithExpiry("areas"); const { id } = useParams<{ id: string }>(); const loading = useAppSelector((state) => state.loading); const [selectedDays, setSelectedDays] = useState(null); const [selectedData, setSelectedData] = useState("Unlimited"); const [daysOptions, setDaysOptions] = useState([]); const [dataOptions, setDataOptions] = useState([]); const [daysActiveOptions, setDaysActiveOptions] = useState([]); const [dataActiveOptions, setDataActiveOptions] = useState([]); const [relatedAreas, setRelatedAreas] = useState([]); const [prices, setPrices] = useState<{ original: string; final: string; discountPercent: string; }>({ original: "0.00", final: "0.00", discountPercent: "0", }); const [simType, setSimType] = useState<"eSIM" | "Physical">("eSIM"); const [quantity, setQuantity] = useState(1); const [packages, setPackages] = useState([]); const [area, setArea] = useState(null); const [selectedPackage, setSelectedPackage] = useState(null); useEffect(() => { console.log("ProductDetailView loaded with id:", id); if (areas && areas.length > 0) { const areaTmp = areas.find((a) => a.id.toString() === id.toString()); setArea(areaTmp); getProductMutation.mutate(); getRelatedAreaMutation.mutate(); console.log("Set area from cache:", areaTmp); } }, [id]); const getProductMutation = useMutation({ mutationFn: async () => { dispatch(startLoading({})); const res = await productApi.loadPackage({ areaId: area?.id, dataType: "-1", }); return res; }, onSuccess: (data) => { dispatch(stopLoading()); console.log("Get package response data:", data); if (data && data.errorCode === "0") { const packages = data.data as Package[]; setPackages(packages); } else { console.error("Get package failed, no token received"); } }, onError: (error: any) => { dispatch(stopLoading()); console.error("Get package error:", error.response.data); }, }); const getRelatedAreaMutation = useMutation({ mutationFn: async () => { dispatch(startLoading({})); const res = await productApi.loadRelatedArea({ areaId: id, }); return res; }, onSuccess: (data) => { dispatch(stopLoading()); console.log("Get package response data:", data); if (data && data.errorCode === "0") { const areas = data.data as Area[]; setRelatedAreas(areas); } else { console.error("Get package failed, no token received"); } }, onError: (error: any) => { dispatch(stopLoading()); console.error("Get package error:", error.response.data); }, }); const convertPackageToSelectedProduct = (packg: Package) => { return packg.title; }; const options = useMemo(() => { console.log("Calculating options from loadPackage"); const daysSet = new Set(); const dataSet = new Set(); packages.forEach((p) => { daysSet.add(p.dayDuration); dataSet.add(convertPackageToSelectedProduct(p)); }); const daysArray = Array.from(daysSet).sort((a, b) => a - b); // const dataArray = Array.from(dataSet).sort((a, b) => { // if (a === "Unlimited") return 1; // if (b === "Unlimited") return -1; // return parseInt(a) - parseInt(b); // }); return { daysArray, dataArray: Array.from(dataSet), }; }, [packages]); useEffect(() => { setDaysOptions(options.daysArray); setDataOptions(options.dataArray); handleSelectDay(options.daysArray[0]); handleSelectData(options.dataArray[0]); // setSelectedPackage(packages.length > 0 ? packages[0] : null); // console.log("Set package successful", packages.length, selectedPackage); }, [options]); useEffect(() => { getPrices(); }, [selectedDays, selectedData]); const handleSelectDay = (day: number) => { // filter data options based on selected day if needed const dataSet = new Set(); packages.forEach((p) => { if (p.dayDuration === day) { dataSet.add(convertPackageToSelectedProduct(p)); } }); setSelectedDays(day); setSelectedData( dataSet.has(selectedData) ? selectedData : Array.from(dataSet)[0], ); setDataActiveOptions(Array.from(dataSet)); setSelectedPackage( packages.find( (p) => p.dayDuration === selectedDays && convertPackageToSelectedProduct(p) === selectedData, ), ); }; const handleSelectData = (data: string) => { // filter day options based on selected data if needed const daysSet = new Set(); packages.forEach((p) => { if (convertPackageToSelectedProduct(p) === data) { daysSet.add(p.dayDuration); } }); setSelectedData(data); setSelectedDays( daysSet.has(selectedDays) ? selectedDays : Array.from(daysSet)[0], ); setDaysActiveOptions(Array.from(daysSet)); setSelectedPackage( packages.find( (p) => p.dayDuration === selectedDays && convertPackageToSelectedProduct(p) === selectedData, ), ); }; const getPrices = (quantityParam?: number) => { const quantityToUse = quantityParam !== undefined ? quantityParam : quantity; // find package based on selectedDays and selectedData let selectedPackageTmp = packages.find( (p) => p.dayDuration === selectedDays && convertPackageToSelectedProduct(p) === selectedData, ); if (!selectedPackageTmp) { // console.log( // "No package found for the selected options " + // selectedDays + // " days and " + // selectedData + // " data" // ); return { original: "0.00", final: "0.00", discountPercent: "0", }; } console.log( "Selected package: ", selectedPackageTmp + " quantity " + quantityToUse, ); setPrices({ original: quantityToUse * selectedPackageTmp.displayPrice, final: quantityToUse * selectedPackageTmp.sellPrice, discountPercent: selectedPackageTmp.discountPercent, }); setSelectedPackage(selectedPackageTmp); }; const handleQuantityChange = (change: number) => { const newQuantity = Math.max(1, quantity + change); setQuantity(newQuantity); console.log("Selected quantity: ", newQuantity); getPrices(newQuantity); }; const handleBuyNow = async () => { // Logic for custom order or standard buy console.log("Buy now clicked"); const selectedPackage = packages.find( (p) => p.dayDuration === selectedDays && convertPackageToSelectedProduct(p) === selectedData, ); if (!selectedPackage) { alert("Please select a valid package"); return; } // call logic to proceed to checkout const res = await productApi.checkout({ packgId: selectedPackage.id, quantity: quantity, }); if (res && res.errorCode === "0") { console.log("Checkout details loaded:", res.data); // navigate to checkout with selected options navigate("/checkout", { state: { area: area, package: selectedPackage, quantity: quantity, simType: simType, checkoutDetails: res.data, }, }); } else { console.error("Failed to load checkout details:", res.message); dispatch( openPopup({ isSuccess: false, title: "Checkout Error", message: res.message || "Failed to proceed to checkout.", buttonText: "Close", }), ); } }; if (!id || !area) { return (

{t("productDetailsMissing")}

{t("goToShop")}
); } return (
{area?.areaName1}
{area?.areaName1}

SIM {area?.areaName1}

{t("verified")}:{" "} {t("highSpeed")}

{/* Product Information Card */}

{t("numberOfDays")}

{daysOptions.map((day) => ( ))}

Data

{dataOptions.map((data) => ( ))}

{t("simType")}

{/* */}

{t("quantity")}

{quantity}
{prices.discountPercent}% {formatCurrency(prices.original, area?.curency)}
{formatCurrency(prices.final, area?.curency)}
{/* Suggestions Section */}

{t("suggestionsEsim")} {area.areaName1}:

{relatedAreas.map((item) => ( { navigate(`/product-detail/${item.id}`, { state: { ...item, }, }); window.scrollTo({ top: 0, behavior: "smooth" }); }} /> ))}
); }; export default ProductDetailView;