BuySimView.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import React from "react";
  2. import { ViewMode, SimProduct, SelectedProduct } from "../../services/types";
  3. import ProductCard from "../../components/ProductCard";
  4. import { useMutation, useQuery } from "@tanstack/react-query";
  5. import { startLoading, stopLoading } from "../../features/loading/loadingSlice";
  6. import { useAppDispatch } from "../../hooks/useRedux";
  7. import { productApi } from "../../apis/productApi";
  8. import { Area } from "../../services/product/type";
  9. import { DataCacheKey, staleTime } from "../../global/constants";
  10. import { useNavigate } from "react-router-dom";
  11. import HomeSearch from "../home/components/HomeSearch";
  12. interface BuySimViewProps {
  13. onProductSelect: (product: SelectedProduct) => void;
  14. onViewChange: (view: ViewMode) => void;
  15. }
  16. const BuySimView: React.FC<BuySimViewProps> = ({
  17. onProductSelect,
  18. onViewChange,
  19. }) => {
  20. const dispatch = useAppDispatch();
  21. const navigate = useNavigate();
  22. // load product by country/region or popularity
  23. const { data: loadArea = [] } = useQuery<Area[]>({
  24. queryKey: [DataCacheKey.AREAS],
  25. queryFn: async (): Promise<Area[]> => {
  26. try {
  27. dispatch(startLoading({}));
  28. const res = await productApi.loadArea({
  29. isCountry: "-1",
  30. isPopular: "-1",
  31. });
  32. // save to redux store
  33. console.log("Get area response data:", res);
  34. return res.data as Area[];
  35. } catch (error) {
  36. console.error(error);
  37. return []; // 🔴 bắt buộc
  38. } finally {
  39. dispatch(stopLoading());
  40. }
  41. },
  42. staleTime: staleTime,
  43. });
  44. const handleSelect = (p: Area) => {
  45. // open product detail view
  46. navigate(`/product/${p.id}`, {
  47. state: {
  48. ...p,
  49. },
  50. });
  51. };
  52. return (
  53. <div className="bg-[#fcfdfe] min-h-screen">
  54. <div className="max-w-7xl mx-auto px-4 py-4 md:py-6 border-b border-slate-50">
  55. <nav className="flex items-center space-x-2 text-xs md:text-sm text-slate-500 ">
  56. <button
  57. onClick={() => onViewChange(ViewMode.HOME)}
  58. className="hover:text-[#EE0434] text-[18px]"
  59. >
  60. Home
  61. </button>
  62. <svg
  63. className="w-3 h-3"
  64. fill="none"
  65. stroke="currentColor"
  66. viewBox="0 0 24 24"
  67. >
  68. <path
  69. d="M9 5l7 7-7 7"
  70. strokeWidth={2.5}
  71. strokeLinecap="round"
  72. strokeLinejoin="round"
  73. />
  74. </svg>
  75. <span className="text-slate-900 font-bold text-[18px]">Buy Sim</span>
  76. </nav>
  77. </div>
  78. <div className="max-w-7xl mx-auto px-4">
  79. <div className="mb-12">
  80. <HomeSearch />
  81. </div>
  82. <section className="mb-12">
  83. <h2 className="text-xl md:text-[32px] font-black text-slate-900 mb-6 md:mb-8 tracking-tight">
  84. SIM Popular
  85. </h2>
  86. <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 md:gap-6">
  87. {loadArea.map((p) => (
  88. <ProductCard key={p.id} p={p} onClick={handleSelect} />
  89. ))}
  90. </div>
  91. </section>
  92. </div>
  93. </div>
  94. );
  95. };
  96. export default BuySimView;