Forráskód Böngészése

Enhance UI, update contact info, and improve FAQ logic

This update refines UI/UX across multiple components, including responsive improvements for product detail and package overview views, adds new favicon and logo assets, and updates partner logos. It also updates contact information and support details, improves FAQ and area loading logic, and enhances navigation and scrolling behavior. Several translation strings and constants are updated, and some redundant or unused code is removed or commented out.
trunghieubui 1 hete
szülő
commit
5a8d642746
26 módosított fájl, 831 hozzáadás és 172 törlés
  1. 3 3
      EsimLao/Esim.Apis/Business/Content/ContentBusinessImpl.cs
  2. 1 1
      EsimLao/Esim.Apis/appsettings.json
  3. BIN
      EsimLao/esim-vite/favicon-48.png
  4. BIN
      EsimLao/esim-vite/favicon-96.png
  5. BIN
      EsimLao/esim-vite/favicon.ico
  6. 16 1
      EsimLao/esim-vite/index.html
  7. 14 19
      EsimLao/esim-vite/src/apis/contentApi.ts
  8. BIN
      EsimLao/esim-vite/src/assets/img/logo.png
  9. BIN
      EsimLao/esim-vite/src/assets/img/logo2.png
  10. 6 6
      EsimLao/esim-vite/src/components/CompatibilityModal.tsx
  11. 54 7
      EsimLao/esim-vite/src/components/Footer.tsx
  12. 40 9
      EsimLao/esim-vite/src/components/Header.tsx
  13. 5 3
      EsimLao/esim-vite/src/components/ProductCard.tsx
  14. 2 0
      EsimLao/esim-vite/src/global/constants.ts
  15. 2 2
      EsimLao/esim-vite/src/i18n/locales/en.json
  16. 3 3
      EsimLao/esim-vite/src/i18n/locales/vi.json
  17. 79 19
      EsimLao/esim-vite/src/pages/buy-sim/BuySimView.tsx
  18. 9 9
      EsimLao/esim-vite/src/pages/checkout/CheckoutView.tsx
  19. 2 2
      EsimLao/esim-vite/src/pages/contact/ContactView.tsx
  20. 28 4
      EsimLao/esim-vite/src/pages/home/HomeView.tsx
  21. 3 1
      EsimLao/esim-vite/src/pages/home/components/HomeFaq.tsx
  22. 8 2
      EsimLao/esim-vite/src/pages/home/components/HomeProduct.tsx
  23. 29 19
      EsimLao/esim-vite/src/pages/order-detail/OrderDetailView.tsx
  24. 40 18
      EsimLao/esim-vite/src/pages/product-detail/ProductDetailView.tsx
  25. 23 1
      EsimLao/esim-vite/src/pages/product-detail/components/PackageOverview.tsx
  26. 464 43
      EsimLao/esim-vite/src/pages/support/SupportView.tsx

+ 3 - 3
EsimLao/Esim.Apis/Business/Content/ContentBusinessImpl.cs

@@ -266,16 +266,16 @@ namespace Esim.Apis.Business
                 int pageSize = request.pageSize <= 0 ? 10 : request.pageSize;
 
                 var query = dbContext.Faqs
-                    .Where(f => f.Status.HasValue && f.Status.Value);
+                    .Where(f => f.Status == true);
 
                 if (request.categoryId.HasValue)
                 {
                     query = query.Where(f => f.CategoryId == request.categoryId);
                 }
 
-                if (request.isFeatured.HasValue && request.isFeatured.Value)
+                if (request.isFeatured != null)
                 {
-                    query = query.Where(f => f.IsFeatured.HasValue && f.IsFeatured.Value);
+                    query = query.Where(f => f.IsFeatured == request.isFeatured);
                 }
 
                 int totalCount = query.Count();

+ 1 - 1
EsimLao/Esim.Apis/appsettings.json

@@ -1,5 +1,5 @@
 {
-  "Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))(CONNECT_DATA=(SERVICE_NAME=ORA12C)));User Id=laos_esim;Password=laos_esim;Connection Timeout=120;",
+  "Connection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))(CONNECT_DATA=(SERVICE_NAME=ORCL.viettech.local)));User Id=laos_esim;Password=laos_esim;Connection Timeout=120;",
   "Logging": {
     "LogLevel": {
       "Default": "Information",

BIN
EsimLao/esim-vite/favicon-48.png


BIN
EsimLao/esim-vite/favicon-96.png


BIN
EsimLao/esim-vite/favicon.ico


+ 16 - 1
EsimLao/esim-vite/index.html

@@ -4,8 +4,14 @@
 <head>
   <meta charset="UTF-8" />
   <link rel="icon" type="image/svg+xml" href="./publish/assets/img/logo.png" />
+  <link rel="icon" href="/favicon.ico" sizes="any">
+  <link rel="icon" type="image/png" href="/favicon-48.png" sizes="48x48">
+  <link rel="icon" type="image/png" href="/favicon-96.png" sizes="96x96">
+  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  <title>SkySimHub | Stay Connected Everywhere</title>
+  <title>SkySimHub – Global eSIM & International SIM | Stay Connected Everywhere</title>
+  <meta name="description"
+    content="SkySimHub eSIM provides global eSIM and international SIM solutions. Receive QR via email, activate in 2 minutes, and stay connected worldwide without physical SIM." />
   <link rel="preconnect" href="https://fonts.googleapis.com">
   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
   <link
@@ -43,6 +49,15 @@
         0 2px 4px -1px rgba(0, 0, 0, 0.03);
     }
   </style>
+  <script type="application/ld+json">
+  {
+    "@context": "https://schema.org",
+    "@type": "Organization",
+    "name": "SkySimHub",
+    "url": "https://skysimhub.vn",
+    "logo": "https://skysimhub.vn/assets/img/logo.png"
+  }
+  </script>
   <script type="importmap">
       {
         "imports": {

+ 14 - 19
EsimLao/esim-vite/src/apis/contentApi.ts

@@ -40,12 +40,7 @@ class ContentApi extends BaseApi {
     });
   }
 
-  async LoadFaq({
-    pageNumber,
-    pageSize,
-    categoryId = null,
-    isFeatured = true,
-  }) {
+  async LoadFaq({ pageNumber, pageSize, categoryId = null, isFeatured }) {
     return this.authPost<LoadFaqResponse>("/faq", {
       pageNumber,
       pageSize,
@@ -54,19 +49,19 @@ class ContentApi extends BaseApi {
     });
   }
 
-  async LoadFaqGuide({
-    pageNumber,
-    pageSize,
-    categoryId = 1,
-    isFeatured = false,
-  }) {
-    return this.authPost<LoadFaqResponse>("/faq", {
-      pageNumber,
-      pageSize,
-      categoryId,
-      isFeatured,
-    });
-  }
+  // async LoadFaqGuide({
+  //   pageNumber,
+  //   pageSize,
+  //   categoryId = 1,
+  //   isFeatured = false,
+  // }) {
+  //   return this.authPost<LoadFaqResponse>("/faq", {
+  //     pageNumber,
+  //     pageSize,
+  //     categoryId,
+  //     isFeatured,
+  //   });
+  // }
 
   async LoadDeviceMetaData() {
     return this.authGet<LoadDeviceMetaResponse>("/device-metadata");

BIN
EsimLao/esim-vite/src/assets/img/logo.png


BIN
EsimLao/esim-vite/src/assets/img/logo2.png


+ 6 - 6
EsimLao/esim-vite/src/components/CompatibilityModal.tsx

@@ -34,14 +34,14 @@ const CompatibilityModal = () => {
         let deviceMap: Record<string, string[]> = {};
         data.data.brands.forEach((element) => {
           deviceMap[element.brand] = element.devices.map(
-            (device) => device.modelName
+            (device) => device.modelName,
           );
         });
 
         setDeviceList(deviceMap);
 
         setSelectedBrand(
-          data.data.brands.length > 0 ? data.data.brands[0].brand : ""
+          data.data.brands.length > 0 ? data.data.brands[0].brand : "",
         );
       } else {
         console.error("Get device metadata failed, no token received");
@@ -208,7 +208,7 @@ const CompatibilityModal = () => {
               <li>{t("someDualPhysicalSimModelsDoNotSupportEsim")}</li>
               <li>
                 {t(
-                  "allIphonesPurchasedFromChinaHongKongAndMacauDoNotSupportEsim"
+                  "allIphonesPurchasedFromChinaHongKongAndMacauDoNotSupportEsim",
                 )}
               </li>
             </ul>
@@ -224,12 +224,12 @@ const CompatibilityModal = () => {
             </h3>
             <p className="text-slate-600 text-xs md:text-lg lg:text-xl">
               {t(
-                "checkIfYourDeviceSupportsEsimAndWhetherItIsCarrierLockedByFollowing"
+                "checkIfYourDeviceSupportsEsimAndWhetherItIsCarrierLockedByFollowing",
               )}
-              <button className="text-[#EE0434] font-bold hover:underline">
+              {/* <button className="text-[#EE0434] font-bold hover:underline">
                 {" "}
                 {t("theStepsBelow")}
-              </button>
+              </button> */}
             </p>
           </div>
 

+ 54 - 7
EsimLao/esim-vite/src/components/Footer.tsx

@@ -4,15 +4,45 @@ import { useTranslation } from "react-i18next";
 import { getWithExpiry } from "../logic/loigicUtils";
 import { Area } from "../services/product/type";
 import { useNavigate } from "react-router-dom";
+import { DataCacheKey, staleTime } from "../global/constants";
+import { startLoading, stopLoading } from "../features/loading/loadingSlice";
+import { useAppDispatch } from "../hooks/useRedux";
+import { useQuery } from "@tanstack/react-query";
+import { productApi } from "../apis/productApi";
 const Footer: React.FC = () => {
   const { t } = useTranslation();
   const navigate = useNavigate();
+  const dispatch = useAppDispatch();
+
+  const { data: loadArea = [] } = useQuery<Area[]>({
+    queryKey: [DataCacheKey.AREAS_FOOTER],
+    queryFn: async (): Promise<Area[]> => {
+      try {
+        dispatch(startLoading({}));
+        const res = await productApi.loadArea({
+          isCountry: "1",
+          isPopular: "1",
+        });
+        // save to redux store
+        console.log("Get area response data:", res);
+        return res.data as Area[];
+      } catch (error) {
+        console.error(error);
+        return []; // 🔴 bắt buộc
+      } finally {
+        dispatch(stopLoading());
+      }
+    },
+    staleTime: staleTime,
+  });
+
+  const popularAreas = React.useMemo(() => loadArea.slice(0, 3), [loadArea]);
 
   return (
     <footer className="bg-white border-t border-slate-100 pt-16 pb-8">
       <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
         {/* Info Columns */}
-        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12 mb-16">
+        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-12 mb-16">
           <div className="space-y-6">
             <div className="flex items-center space-x-2">
               {/* <svg
@@ -74,7 +104,7 @@ const Footer: React.FC = () => {
                     d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
                   />
                 </svg>{" "}
-                sale.admin@viettech.asia
+                klinhnguyen@viettech.asia
               </p>
               <p className="flex items-center">
                 <svg
@@ -90,7 +120,7 @@ const Footer: React.FC = () => {
                     d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
                   />
                 </svg>{" "}
-                Zalo/Whatsapp: +84972.978.296
+                Zalo/Whatsapp: +84336548007
               </p>
             </div>
           </div>
@@ -125,7 +155,24 @@ const Footer: React.FC = () => {
               Travel {t("sim")}
             </h3>
             <ul className="space-y-4 text-sm text-slate-500">
-              <li>
+              {popularAreas.map((area) => (
+                <li>
+                  <a
+                    href="#"
+                    className="hover:text-[#EE0434] transition-colors"
+                    onClick={() =>
+                      navigate(`/product-detail/${area.id}`, {
+                        state: {
+                          ...area,
+                        },
+                      })
+                    }
+                  >
+                    {area.areaName1}
+                  </a>
+                </li>
+              ))}
+              {/* <li>
                 <a
                   href="#"
                   className="hover:text-[#EE0434] transition-colors"
@@ -151,10 +198,10 @@ const Footer: React.FC = () => {
                 >
                   {t("japanSim")}
                 </a>
-              </li>
+              </li> */}
             </ul>
           </div>
-          <div>
+          {/* <div>
             <h3 className="text-base font-bold text-slate-900 mb-6">Guide</h3>
             <ul className="space-y-4 text-sm text-slate-500">
               <li>
@@ -168,7 +215,7 @@ const Footer: React.FC = () => {
                 </a>
               </li>
             </ul>
-          </div>
+          </div> */}
         </div>
 
         {/* Bottom */}

+ 40 - 9
EsimLao/esim-vite/src/components/Header.tsx

@@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from "react";
 import { useNavigate, useLocation, Link } from "react-router-dom";
 import logo from "../assets/img/getgo.svg";
 import { useAppDispatch, useAppSelector } from "../hooks/useRedux";
-import { useMutation } from "@tanstack/react-query";
+import { useMutation, useQuery } from "@tanstack/react-query";
 import {
   startLoading,
   startSmallLoading,
@@ -21,6 +21,9 @@ import {
   getWithExpiry,
   setWithExpiry,
 } from "../logic/loigicUtils";
+import { Faq } from "../services/content/types";
+import { DataCacheKey, staleTime } from "../global/constants";
+import { contentApi } from "../apis/contentApi";
 
 const Header: React.FC = () => {
   const navigate = useNavigate();
@@ -49,10 +52,13 @@ const Header: React.FC = () => {
   const account = localStorage.getItem("accountInfo");
 
   const guideItems = [
-    { label: t("whatEsim"), path: "/support" },
-    { label: t("installationInstructions"), path: "/support" },
-    { label: t("supportSupport"), path: "/support" },
-    { label: t("orderSearch"), path: "/support" },
+    { label: "GIỚI THIỆU CƠ BẢN VỀ ESIM", path: "/support" },
+    { label: "HƯỚNG DẪN CÀI ĐẶT eSIM TRÊN CÁC THIẾT BỊ", path: "/support" },
+    { label: "HƯỚNG DẪN BẬT CHUYỂN VÙNG DỮ LIỆU (Roaming)", path: "/support" },
+    { label: "CÁCH KIỂM TRA DUNG LƯỢNG ĐÃ DÙNG", path: "/support" },
+    { label: "CÁCH KIỂM TRA ESIM ĐANG SỬ DỤNG DỮ LIỆU", path: "/support" },
+    { label: "CÁCH ƯỚC TÍNH DUNG LƯỢNG", path: "/support" },
+    { label: "CÁC SỰ CỐ ESIM PHỔ BIẾN", path: "/support" },
   ];
   const dropdownRef = useRef<HTMLDivElement>(null);
   const [areasList, setAreasList] = useState<Area[]>([]);
@@ -70,8 +76,8 @@ const Header: React.FC = () => {
       dispatch(startLoading({}));
       const res = await productApi.loadArea(
         activeDesktopTab === "popular"
-          ? { isCountry: "-1", isPopular: "1" }
-          : { isCountry: "0", isPopular: "-1" }
+          ? { isCountry: "1", isPopular: "1" }
+          : { isCountry: "0", isPopular: "1" },
       );
       return res;
     },
@@ -187,7 +193,7 @@ const Header: React.FC = () => {
       setAreasList(areas);
     } else {
       const filtered = areas.filter((area: Area) =>
-        area.coverageArea.toLowerCase().includes(query.toLowerCase())
+        area.coverageArea.toLowerCase().includes(query.toLowerCase()),
       );
       setAreasList(filtered);
     }
@@ -208,6 +214,31 @@ const Header: React.FC = () => {
     };
   }, []);
 
+  // const { data: loadFaqCateData = [] } = useQuery<Faq[]>({
+  //   queryKey: [DataCacheKey.FAQS_HEADER],
+  //   queryFn: async (): Promise<Faq[]> => {
+  //     try {
+  //       dispatch(startLoading({}));
+  //       const res = await contentApi.LoadFaq({
+  //         pageNumber: 0,
+  //         pageSize: 10,
+  //         isFeatured: false,
+  //       });
+  //       const data = res.data.faqs as Faq[];
+  //       setWithExpiry(DataCacheKey.FAQS_HEADER, data);
+  //       return data;
+  //     } catch (error) {
+  //       console.error(error);
+  //       return []; // 🔴 bắt buộc
+  //     } finally {
+  //       dispatch(stopLoading());
+  //     }
+  //   },
+  //   staleTime: staleTime,
+  // });
+
+  // const guideItems = React.useMemo(() => loadFaqCateData, [loadFaqCateData]);
+
   return (
     <>
       <header className="sticky top-0 z-[60] w-full bg-white border-b border-slate-100 shadow-sm transition-all duration-300">
@@ -472,7 +503,7 @@ const Header: React.FC = () => {
                         <button
                           key={item.label}
                           onClick={() => {
-                            navigate(item.path);
+                            navigate("/support");
                             setIsGuideMegaVisible(false);
                           }}
                           className={`w-full text-left px-6 py-4 rounded-2xl text-base font-medium transition-all text-slate-600 hover:bg-slate-50 hover:text-[#EE0434]`}

+ 5 - 3
EsimLao/esim-vite/src/components/ProductCard.tsx

@@ -15,9 +15,11 @@ const ProductCard: React.FC<{
       onClick={() => onClick(p)}
       className="bg-white border border-slate-100 rounded-[20px] p-3 md:p-6 shadow-sm hover:shadow-lg transition-all relative flex flex-col md:flex-row items-center md:space-x-4 space-y-2 md:space-y-0 group cursor-pointer text-center md:text-left"
     >
-      <div className="absolute top-0 right-0 bg-[#EE0434] text-white text-[10px] font-black px-2 py-1 md:px-3 md:py-1.5 rounded-tr-[19px] rounded-bl-[14px] absolute-right-18">
-        {p.promotionPercent}%
-      </div>
+      {p.promotionPercent !== 0 && (
+        <div className="absolute top-0 right-0 bg-[#EE0434] text-white text-[10px] font-black px-2 py-1 md:px-3 md:py-1.5 rounded-tr-[19px] rounded-bl-[14px] absolute-right-18">
+          {p.promotionPercent}%
+        </div>
+      )}
       <div className="w-10 h-10 md:w-12 md:h-12 rounded-full overflow-hidden shrink-0 border border-slate-50 bg-slate-50">
         <img
           src={`${p.iconUrl}`}

+ 2 - 0
EsimLao/esim-vite/src/global/constants.ts

@@ -13,7 +13,9 @@ export const DataCacheKey = {
   BANNERS: "banners",
   REVIEWS: "reviews",
   FAQS: "faqs",
+  FAQS_HEADER: "faqs_header",
   PACKAGES: "packages",
   PAYMENT_CHANNELS: "payment_channels",
   FAQ_GUIDES: "faq_guides",
+  AREAS_FOOTER: "areas_footer",
 };

+ 2 - 2
EsimLao/esim-vite/src/i18n/locales/en.json

@@ -38,8 +38,8 @@
   "chinaSim": "China SIM",
   "thailandSim": "Thailand SIM",
   "japanSim": "Japan SIM",
-  "emailAsia": "Email: sale.admin@viettech.asia",
-  "zaloWhatsapp": "Zalo/WhatsApp: +84 972 978 296",
+  "emailAsia": "Email: klinhnguyen@viettech.asia",
+  "zaloWhatsapp": "Zalo/WhatsApp: +84336548007",
   "verifiedSpeed": "Verified: High Speed",
   "numberDays": "Number of days",
   "dataData": "Data",

+ 3 - 3
EsimLao/esim-vite/src/i18n/locales/vi.json

@@ -38,8 +38,8 @@
   "chinaSim": "SIM Trung Quốc",
   "thailandSim": "SIM Thái Lan",
   "japanSim": "SIM Nhật Bản",
-  "emailAsia": "Email: sale.admin@viettech.asia",
-  "zaloWhatsapp": "Zalo/Whatsapp: +84972.978.296",
+  "emailAsia": "Email: klinhnguyen@viettech.asia",
+  "zaloWhatsapp": "Zalo/Whatsapp: +84336548007",
   "verifiedSpeed": "Đã xác thực: Tốc độ cao",
   "numberDays": "Số ngày",
   "dataData": "Dữ liệu",
@@ -133,7 +133,7 @@
   "noteTheFollowingAppleDevicesDoNotSupportEsim": "*Lưu ý: Các thiết bị Apple sau KHÔNG hỗ trợ eSIM:",
   "allIphonesPurchasedFromChinaHongKongAndMacauDoNotSupportEsim": "Tất cả iPhone mua từ Trung Quốc, Hồng Kông và Ma Cao KHÔNG hỗ trợ eSIM.",
   "method2CheckDirectlyOnYourDevice": "Phương pháp 2: Kiểm tra trực tiếp trên thiết bị của bạn",
-  "checkIfYourDeviceSupportsEsimAndWhetherItIsCarrierLockedByFollowing": "Kiểm tra xem thiết bị của bạn có hỗ trợ eSIM và liệu nó có bị khóa nhà mạng hay không bằng cách làm theo",
+  "checkIfYourDeviceSupportsEsimAndWhetherItIsCarrierLockedByFollowing": "Kiểm tra bằng cách quay số *#06# và gọi, nếu hiển thị dòng EID (eSIM ID) là máy dùng được eSIM.",
   "theStepsBelow": "các bước dưới đây",
   "yourDeviceDoesNotSupportEsim": "Thiết bị của bạn không hỗ trợ eSIM?",
   "tryFindingAPhysicalSimThatIsCompatibleWithYourDevice": "Hãy thử tìm một SIM vật lý tương thích với thiết bị của bạn",

+ 79 - 19
EsimLao/esim-vite/src/pages/buy-sim/BuySimView.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useEffect } from "react";
 import { ViewMode, SimProduct, SelectedProduct } from "../../services/types";
 import ProductCard from "../../components/ProductCard";
 import { useMutation, useQuery } from "@tanstack/react-query";
@@ -7,9 +7,10 @@ import { useAppDispatch } from "../../hooks/useRedux";
 import { productApi } from "../../apis/productApi";
 import { Area } from "../../services/product/type";
 import { DataCacheKey, staleTime } from "../../global/constants";
-import { useNavigate } from "react-router-dom";
+import { useLocation, useNavigate } from "react-router-dom";
 import HomeSearch from "../home/components/HomeSearch";
 import { useTranslation } from "react-i18next";
+import { getWithExpiry } from "../../logic/loigicUtils";
 
 interface BuySimViewProps {
   onProductSelect: (product: SelectedProduct) => void;
@@ -23,9 +24,11 @@ const BuySimView: React.FC<BuySimViewProps> = ({
   const dispatch = useAppDispatch();
   const navigate = useNavigate();
   const { t } = useTranslation();
-
-  const [countries, setCountries] = React.useState<Area[]>([]);
-  const [populars, setPopulars] = React.useState<Area[]>([]);
+  const location = useLocation();
+  const state = location.state;
+  const areas = getWithExpiry<Area[] | []>("areas");
+  // const [countries, setCountries] = React.useState<Area[]>([]);
+  // const [populars, setPopulars] = React.useState<Area[]>([]);
 
   const { data: loadArea = [] } = useQuery<Area[]>({
     queryKey: [DataCacheKey.AREAS],
@@ -39,8 +42,8 @@ const BuySimView: React.FC<BuySimViewProps> = ({
         // save to redux store
         console.log("Get area response data:", res);
         let areas = res.data as Area[];
-        setCountries(areas.filter((a) => a.isCountry === 1));
-        setPopulars(areas.filter((a) => a.isPopular === 0));
+        // setCountries(areas.filter((a) => a.isCountry === 1));
+        // setPopulars(areas.filter((a) => a.isPopular === 0));
         return res.data as Area[];
       } catch (error) {
         console.error(error);
@@ -52,6 +55,31 @@ const BuySimView: React.FC<BuySimViewProps> = ({
     staleTime: staleTime,
   });
 
+  // const getAreaMutation = useMutation({
+  //   mutationFn: async () => {
+  //     dispatch(startLoading({}));
+  //     const res = await productApi.loadArea({
+  //       isCountry: "-1",
+  //       isPopular: "-1",
+  //     });
+  //     return res;
+  //   },
+  //   onSuccess: (data) => {
+  //     dispatch(stopLoading());
+  //     if (data && data.errorCode === "0") {
+  //       let areasGet = data.data as Area[];
+  //       setCountries(areasGet.filter((a) => a.isCountry === 1));
+  //       setPopulars(areasGet.filter((a) => a.isPopular === 0));
+  //     } else {
+  //       console.error("Get area failed, no token received");
+  //     }
+  //   },
+  //   onError: (error: any) => {
+  //     dispatch(stopLoading());
+  //     console.error("Get area error:", error.response.data);
+  //   },
+  // });
+
   const handleSelect = (p: Area) => {
     // open product detail view
     navigate(`/product-detail/${p.id}`, {
@@ -61,6 +89,42 @@ const BuySimView: React.FC<BuySimViewProps> = ({
     });
   };
 
+  // useEffect(() => {
+  //   if (!areas || areas.length === 0) getAreaMutation.mutate();
+  //   else {
+  //     console.log("Areas loaded from cache:", areas.length, areas);
+  //     setCountries(areas.filter((a) => a.isCountry === 1));
+  //     setPopulars(areas.filter((a) => a.isPopular === 0));
+  //   }
+  // }, []);
+
+  useEffect(() => {
+    if (!state?.scrollToId || loadArea.length === 0) return;
+
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        scrollToSection();
+      });
+    });
+  }, [loadArea, state?.scrollToId]);
+
+  const scrollToSection = () => {
+    const element = document.getElementById(state?.scrollToId);
+    if (element) {
+      element.scrollIntoView({ behavior: "smooth", block: "start" });
+    }
+  };
+
+  const countries = React.useMemo(
+    () => loadArea.filter((a) => a.isCountry === 1),
+    [loadArea],
+  );
+
+  const regions = React.useMemo(
+    () => loadArea.filter((a) => a.isCountry === 0),
+    [loadArea],
+  );
+
   return (
     <div className="bg-[#fcfdfe] min-h-screen">
       <div className="max-w-7xl mx-auto px-4 py-4 md:py-6 border-b border-slate-50">
@@ -94,28 +158,24 @@ const BuySimView: React.FC<BuySimViewProps> = ({
         <div className="mb-12">
           <HomeSearch />
         </div>
-        <section className="mb-12">
+        <section className="mb-12" id="countries">
           <h2 className="text-xl md:text-[32px] font-black text-slate-900 mb-6 md:mb-8 tracking-tight">
             {t("simCountries")}
           </h2>
           <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 md:gap-6">
-            {loadArea
-              .filter((a) => a.isCountry === 1)
-              .map((p) => (
-                <ProductCard key={p.id} p={p} onClick={handleSelect} />
-              ))}
+            {countries.map((p) => (
+              <ProductCard key={p.id} p={p} onClick={handleSelect} />
+            ))}
           </div>
         </section>
-        <section className="mb-12">
+        <section className="mb-12" id="regions">
           <h2 className="text-xl md:text-[32px] font-black text-slate-900 mb-6 md:mb-8 tracking-tight">
             SIM {t("regionList")}
           </h2>
           <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 md:gap-6">
-            {loadArea
-              .filter((a) => a.isCountry === 0)
-              .map((p) => (
-                <ProductCard key={p.id} p={p} onClick={handleSelect} />
-              ))}
+            {regions.map((p) => (
+              <ProductCard key={p.id} p={p} onClick={handleSelect} />
+            ))}
           </div>
         </section>
       </div>

+ 9 - 9
EsimLao/esim-vite/src/pages/checkout/CheckoutView.tsx

@@ -70,7 +70,7 @@ const CheckoutView = () => {
           isSuccess: false,
           title: "Error",
           message: "Email and Confirm Email do not match.",
-        })
+        }),
       );
       return;
     }
@@ -96,7 +96,7 @@ const CheckoutView = () => {
           isSuccess: false,
           title: "Error",
           message: res.message || "Failed to confirm order.",
-        })
+        }),
       );
     }
   };
@@ -309,13 +309,13 @@ const CheckoutView = () => {
                 <p className="text-xs text-slate-400 line-through font-bold">
                   {formatCurrency(
                     state.checkoutDetails.totalMoney,
-                    state.checkoutDetails.curency
+                    state.checkoutDetails.curency,
                   )}
                 </p>
                 <p className="text-[#0071e3] font-black text-xl">
                   {formatCurrency(
                     state.checkoutDetails.paymentMoney,
-                    state.checkoutDetails.curency
+                    state.checkoutDetails.curency,
                   )}
                 </p>
               </div>
@@ -387,7 +387,7 @@ const CheckoutView = () => {
                 {t("iUnlocked")}
               </span>
             </label>
-            <label className="flex items-start cursor-pointer group">
+            {/* <label className="flex items-start cursor-pointer group">
               <input
                 type="checkbox"
                 className="mt-1 w-4 h-4 rounded border-slate-300 text-[#0071e3] focus:ring-[#0071e3]"
@@ -398,7 +398,7 @@ const CheckoutView = () => {
               <span className="ml-3 text-sm text-slate-500 font-medium group-hover:text-slate-700 transition-colors">
                 {t("iInvoice")}
               </span>
-            </label>
+            </label> */}
           </div>
 
           {/* Overview Card */}
@@ -422,7 +422,7 @@ const CheckoutView = () => {
                 <span>
                   {formatCurrency(
                     state.checkoutDetails.totalMoney * state.quantity,
-                    state.checkoutDetails.curency
+                    state.checkoutDetails.curency,
                   )}
                 </span>
               </div>
@@ -432,7 +432,7 @@ const CheckoutView = () => {
                   -
                   {formatCurrency(
                     state.checkoutDetails.discount,
-                    state.checkoutDetails.curency
+                    state.checkoutDetails.curency,
                   )}
                 </span>
               </div>
@@ -443,7 +443,7 @@ const CheckoutView = () => {
                 <span className="text-[#0071e3] font-black text-3xl">
                   {formatCurrency(
                     state.checkoutDetails.paymentMoney,
-                    state.checkoutDetails.curency
+                    state.checkoutDetails.curency,
                   )}
                 </span>
               </div>

+ 2 - 2
EsimLao/esim-vite/src/pages/contact/ContactView.tsx

@@ -33,10 +33,10 @@ const ContactView: React.FC = () => {
                   <span className="font-bold text-lg">Email</span>
                 </div>
                 <a
-                  href="mailto:sale.admin@viettech.asia"
+                  href="mailto:klinhnguyen@viettech.asia"
                   className="block text-[#EE0434] font-black text-lg md:text-xl pl-9 hover:underline"
                 >
-                  sale.admin@viettech.asia
+                  klinhnguyen@viettech.asia
                 </a>
               </div>
             </div>

+ 28 - 4
EsimLao/esim-vite/src/pages/home/HomeView.tsx

@@ -51,7 +51,7 @@ const HomeView: React.FC = () => {
             hasRightButton: true,
             rightButtonText: t("viewOrder"),
             rightButtonAction: "OPEN_ORDER_HISTORY",
-          })
+          }),
         );
       } else {
         dispatch(
@@ -60,7 +60,7 @@ const HomeView: React.FC = () => {
             message: t("paymentFailed"),
             title: t("paymentStatus"),
             buttonText: t("close"),
-          })
+          }),
         );
       }
     } else if (code) {
@@ -282,13 +282,37 @@ const HomeView: React.FC = () => {
               <div className="flex flex-wrap gap-3 md:gap-8 justify-center lg:justify-start">
                 <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
                   <img
-                    src={partner1}
+                    src="https://skysimhub.vn/assets/partners/1.png"
                     className="max-h-full max-w-full object-contain"
                   />
                 </div>
                 <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
                   <img
-                    src={partner2}
+                    src="https://skysimhub.vn/assets/partners/2.png"
+                    className="max-h-full max-w-full object-contain"
+                  />
+                </div>
+                <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
+                  <img
+                    src="https://skysimhub.vn/assets/partners/3.png"
+                    className="max-h-full max-w-full object-contain"
+                  />
+                </div>
+                <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
+                  <img
+                    src="https://skysimhub.vn/assets/partners/4.png"
+                    className="max-h-full max-w-full object-contain"
+                  />
+                </div>
+                <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
+                  <img
+                    src="https://skysimhub.vn/assets/partners/5.png"
+                    className="max-h-full max-w-full object-contain"
+                  />
+                </div>
+                <div className="bg-white border border-[#EE0434]/20 rounded-xl px-4 py-2 w-36 md:w-56 h-14 flex items-center justify-center shadow-sm">
+                  <img
+                    src="https://skysimhub.vn/assets/partners/6.png"
                     className="max-h-full max-w-full object-contain"
                   />
                 </div>

+ 3 - 1
EsimLao/esim-vite/src/pages/home/components/HomeFaq.tsx

@@ -22,6 +22,7 @@ const HomeFaq = () => {
         const res = await contentApi.LoadFaq({
           pageNumber: 0,
           pageSize: 10,
+          isFeatured: true,
         });
         return res.data.faqs as Faq[];
       } catch (error) {
@@ -44,7 +45,8 @@ const HomeFaq = () => {
         <div className="max-w-4xl mx-auto">
           <div className="text-center mb-12 md:mb-20">
             <h2 className="text-3xl md:text-6xl font-black tracking-tight text-[#EE0434] mb-4">
-              {t("frequently")} <span className="text-slate-900">{t("askedQuestions")}</span>
+              {t("frequently")}{" "}
+              <span className="text-slate-900">{t("askedQuestions")}</span>
             </h2>
             <p className="text-slate-500 text-sm md:text-xl font-medium">
               {t("weAreAlwaysHereToSupportYou")}

+ 8 - 2
EsimLao/esim-vite/src/pages/home/components/HomeProduct.tsx

@@ -37,7 +37,7 @@ const HomeProduct = () => {
           : {
               isCountry: "0",
               isPopular: "1",
-            }
+            },
       );
       return res;
     },
@@ -116,7 +116,13 @@ const HomeProduct = () => {
       <div className="max-w-7xl mx-auto flex flex-col items-center mt-16">
         <button
           className="flex items-center bg-gradient-to-r from-[#E21c34] to-[#500B28] p-2 pr-10 rounded-full shadow-xl hover:scale-105 transition-all"
-          onClick={() => navigate("/buy-sim")}
+          onClick={() =>
+            navigate("/buy-sim", {
+              state: {
+                scrollToId: activeTab === "country" ? "countries" : "regions",
+              },
+            })
+          }
         >
           <div className="w-16 h-16 bg-white rounded-full flex items-center justify-center text-slate-800">
             <svg

+ 29 - 19
EsimLao/esim-vite/src/pages/order-detail/OrderDetailView.tsx

@@ -159,28 +159,38 @@ const OrderDetailView = () => {
           </svg>
           {/* Central Text */}
           <div className="absolute inset-0 flex flex-col items-center justify-center">
-            <span className="text-3xl md:text-4xl font-black text-[#EE0434]">
-              {formatNumber(dataUsage.usageData)}
-              <span className="text-[16px]">{dataUsage.dataUnit}</span>
-            </span>
+            {dataUsage.totalData === 0 ? (
+              <span className="text-3xl md:text-4xl font-black text-[#EE0434]">
+                Unlimited
+              </span>
+            ) : (
+              <span className="text-3xl md:text-4xl font-black text-[#EE0434]">
+                {formatNumber(dataUsage.usageData)}
+                <span className="text-[16px]">{dataUsage.dataUnit}</span>
+              </span>
+            )}
           </div>
 
           {/* Min Label (Approximate position for 240deg start) */}
-          <div
-            className="absolute text-xl font-bold font-black text-[#000000]"
-            style={{ bottom: "5%", left: "12%" }}
-          >
-            {formatNumber(0)}
-            <span className="text-[16px]">{dataUsage.dataUnit}</span>
-          </div>
-          {/* Max Label (Approximate position for 240deg end) */}
-          <div
-            className="absolute text-xl font-bold font-black text-[#000000]"
-            style={{ bottom: "5%", right: "8%" }}
-          >
-            {formatNumber(dataUsage.totalData)}
-            <span className="text-[16px]">{dataUsage.dataUnit}</span>
-          </div>
+          {dataUsage.totalData === 0 ? null : (
+            <>
+              <div
+                className="absolute text-xl font-bold font-black text-[#000000]"
+                style={{ bottom: "5%", left: "12%" }}
+              >
+                {formatNumber(0)}
+                <span className="text-[16px]">{dataUsage.dataUnit}</span>
+              </div>
+              {/* Max Label (Approximate position for 240deg end) */}
+              <div
+                className="absolute text-xl font-bold font-black text-[#000000]"
+                style={{ bottom: "5%", right: "8%" }}
+              >
+                {formatNumber(dataUsage.totalData)}
+                <span className="text-[16px]">{dataUsage.dataUnit}</span>
+              </div>
+            </>
+          )}
         </div>
         <p className="mt-1 text-slate-400 text-sm font-bold uppercase tracking-widest">
           {dataUsage.status === 0

+ 40 - 18
EsimLao/esim-vite/src/pages/product-detail/ProductDetailView.tsx

@@ -323,16 +323,16 @@ const ProductDetailView: React.FC = () => {
         </nav>
       </div>
 
-      <div className="max-w-7xl mx-auto px-4 grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12">
-        <div className="lg:col-span-5 space-y-6">
-          <div className="relative aspect-[3/4] rounded-[24px] md:rounded-[32px] overflow-hidden shadow-2xl group">
+      <div className="max-w-7xl mx-auto px-4 grid grid-cols-1 lg:grid-cols-12 gap-6 lg:gap-12">
+        <div className="lg:col-span-5 space-y-4 md:space-y-6">
+          <div className="relative h-48 md:h-auto aspect-[3/4] rounded-[24px] md:rounded-[32px] overflow-hidden shadow-2xl group w-full">
             <img
               src={area?.imgUrl}
               alt={area?.areaName1}
               className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110"
             />
-            <div className="absolute top-6 left-6 flex items-start space-x-4">
-              <div className="w-12 h-12 md:w-16 md:h-16 rounded-full overflow-hidden border-2 border-white/50 shadow-lg">
+            <div className="absolute top-4 left-4 md:top-6 md:left-6 flex items-start space-x-3 md:space-x-4">
+              <div className="w-10 h-10 md:w-16 md:h-16 rounded-full overflow-hidden border-2 border-white/50 shadow-lg">
                 <img
                   src={`${area?.iconUrl}`}
                   alt={area?.areaName1}
@@ -355,12 +355,12 @@ const ProductDetailView: React.FC = () => {
           <PackageOverview packageInfo={selectedPackage} />
         </div>
 
-        <div className="lg:col-span-7 space-y-8 md:space-y-10 pt-4">
-          <div className="space-y-4">
+        <div className="lg:col-span-7 space-y-5 md:space-y-10 pt-2 md:pt-4">
+          <div className="space-y-2 md:space-y-4">
             <h3 className="text-lg md:text-xl font-black text-slate-900 tracking-tight">
               {t("numberOfDays")}
             </h3>
-            <div className="flex flex-wrap gap-3">
+            <div className="flex flex-wrap gap-2 md:gap-3">
               {daysOptions.map((day) => (
                 <button
                   key={day}
@@ -382,11 +382,11 @@ const ProductDetailView: React.FC = () => {
             </div>
           </div>
 
-          <div className="space-y-4">
+          <div className="space-y-2 md:space-y-4">
             <h3 className="text-lg md:text-xl font-black text-slate-900 tracking-tight">
               Data
             </h3>
-            <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3">
+            <div className="grid grid-cols-3 md:grid-cols-4 gap-2 md:gap-3">
               {dataOptions.map((data) => (
                 <button
                   key={data}
@@ -408,8 +408,8 @@ const ProductDetailView: React.FC = () => {
             </div>
           </div>
 
-          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
-            <div className="space-y-4">
+          <div className="grid grid-cols-2 gap-2 md:gap-4">
+            <div className="space-y-2 md:space-y-4">
               <h3 className="text-lg md:text-xl font-black text-slate-900 tracking-tight">
                 {t("simType")}
               </h3>
@@ -436,11 +436,11 @@ const ProductDetailView: React.FC = () => {
                 </button> */}
               </div>
             </div>
-            <div className="space-y-4">
+            <div className="space-y-2 md:space-y-4">
               <h3 className="text-lg md:text-xl font-black text-slate-900 tracking-tight">
                 {t("quantity")}
               </h3>
-              <div className="flex items-center space-x-4 p-2 bg-slate-50 rounded-2xl border border-slate-100 h-[68px] md:h-[76px]">
+              <div className="flex items-center space-x-4 p-1 md:p-2 bg-slate-50 rounded-2xl border border-slate-100 h-[68px] md:h-[76px]">
                 <button
                   onClick={() => handleQuantityChange(-1)}
                   className="w-12 h-full bg-white rounded-xl shadow-sm text-slate-600 font-bold text-2xl hover:bg-slate-100 transition-colors"
@@ -460,7 +460,7 @@ const ProductDetailView: React.FC = () => {
             </div>
           </div>
 
-          <div className="bg-red-50/50 border border-[#EE0434]/20 rounded-[24px] md:rounded-[40px] p-6 md:p-10 space-y-6">
+          <div className="hidden md:block bg-red-50/50 border border-[#EE0434]/20 rounded-[24px] md:rounded-[40px] p-6 md:p-10 space-y-6">
             <div className="flex justify-between items-end">
               <div className="flex items-center space-x-2">
                 <span className="text-[#EE0434] font-black text-lg">
@@ -491,11 +491,11 @@ const ProductDetailView: React.FC = () => {
           </div>
 
           {/* Suggestions Section */}
-          <div className="mt-12">
-            <h3 className="text-xl md:text-2xl font-black text-slate-900 mb-6">
+          <div className="mt-8 md:mt-12">
+            <h3 className="text-xl md:text-2xl font-black text-slate-900 mb-4 md:mb-6">
               {t("suggestionsEsim")} {area.areaName1}:
             </h3>
-            <div className="grid grid-cols-2 gap-3 md:gap-4">
+            <div className="grid grid-cols-2 gap-2 md:gap-4">
               {relatedAreas.map((item) => (
                 <ProductCard
                   key={item.id}
@@ -514,6 +514,28 @@ const ProductDetailView: React.FC = () => {
           </div>
         </div>
       </div>
+      {/* Mobile Sticky Bottom Bar */}
+      <div className="md:hidden fixed bottom-0 left-0 right-0 bg-white border-t border-slate-100 p-4 pb-8 shadow-[0_-10px_40px_-15px_rgba(0,0,0,0.1)] z-50 flex items-center justify-between gap-4">
+        <div className="flex flex-col">
+          <div className="flex items-center space-x-2 mb-1">
+            <span className="bg-red-100 text-[#EE0434] px-2 py-0.5 rounded text-xs font-black">
+              {prices.discountPercent}%
+            </span>
+            <span className="text-slate-400 line-through font-bold text-sm">
+              {formatCurrency(prices.original, area?.curency)}
+            </span>
+          </div>
+          <span className="text-3xl font-black text-[#EE0434] leading-none">
+            {formatCurrency(prices.final, area?.curency)}
+          </span>
+        </div>
+        <button
+          onClick={handleBuyNow}
+          className="flex-1 bg-[#EE0434] text-white py-3.5 rounded-2xl font-black text-lg shadow-lg shadow-red-200"
+        >
+          Buy Now
+        </button>
+      </div>
     </div>
   );
 };

+ 23 - 1
EsimLao/esim-vite/src/pages/product-detail/components/PackageOverview.tsx

@@ -18,7 +18,7 @@ const PackageOverview = ({ packageInfo }: { packageInfo: Package }) => {
         onClose={() => setIsInfoModalOpen(false)}
         packageInfo={packageInfo}
       />
-      <div className="bg-[#f0f9ff] rounded-[24px] p-6 md:p-8 border border-sky-100 shadow-sm transition-all">
+      <div className="hidden md:block bg-[#f0f9ff] rounded-[24px] p-6 md:p-8 border border-sky-100 shadow-sm transition-all">
         <h3 className="text-lg md:text-xl font-black text-slate-900 mb-4">
           {t("productInformation")}:
         </h3>
@@ -81,6 +81,28 @@ const PackageOverview = ({ packageInfo }: { packageInfo: Package }) => {
           </div>
         </button>
       </div>
+      {/* Product Information - Mobile Link */}
+      <div className="md:hidden">
+        <button
+          onClick={() => setIsInfoModalOpen(true)}
+          className="text-[#0091ff] font-bold text-sm flex items-center"
+        >
+          {t("seeMore")}
+          <svg
+            className="w-4 h-4 ml-1"
+            fill="none"
+            stroke="currentColor"
+            viewBox="0 0 24 24"
+          >
+            <path
+              strokeLinecap="round"
+              strokeLinejoin="round"
+              strokeWidth={2}
+              d="M9 5l7 7-7 7"
+            />
+          </svg>
+        </button>
+      </div>
     </>
   );
 };

+ 464 - 43
EsimLao/esim-vite/src/pages/support/SupportView.tsx

@@ -1,45 +1,26 @@
+import { getWithExpiry } from "../../logic/loigicUtils";
 import { contentApi } from "../../apis/contentApi";
 import { startLoading, stopLoading } from "../../features/loading/loadingSlice";
 import { DataCacheKey, staleTime } from "../../global/constants";
-import { Faq } from "../../services/content/types";
+import { Faq, FaqCategory } from "../../services/content/types";
 import { useQuery } from "@tanstack/react-query";
-import React, { useState, useEffect } from "react";
+import React, { useState, useEffect, useMemo } from "react";
 import { useTranslation } from "react-i18next";
 import { useDispatch } from "react-redux";
 import { Link } from "react-router-dom";
+import { text } from "stream/consumers";
 
 const SupportView: React.FC = () => {
   const { t } = useTranslation();
   const dispatch = useDispatch();
+  const faqs = getWithExpiry<Faq[] | []>(DataCacheKey.FAQS_HEADER);
 
-  const { data: loadFaqsData = [] } = useQuery<Faq[]>({
-    queryKey: [DataCacheKey.FAQ_GUIDES],
-    queryFn: async (): Promise<Faq[]> => {
-      try {
-        dispatch(startLoading({}));
-        const res = await contentApi.LoadFaqGuide({
-          pageNumber: 0,
-          pageSize: 10,
-        });
-        return res.data.faqs as Faq[];
-      } catch (error) {
-        console.error(error);
-        return []; // 🔴 bắt buộc
-      } finally {
-        dispatch(stopLoading());
-      }
-    },
-    staleTime: staleTime,
-  });
+  const [activeItem, setActiveItem] = useState(1.1);
 
-  useEffect(() => {
-    console.log("FAQ Guides Data:", loadFaqsData);
-  }, [loadFaqsData]);
-
-  const [activeItem, setActiveItem] = useState(t("travelEsimSim"));
   const categories = [
     {
-      title: t("travelEsimSim"),
+      id: 1,
+      title: "1.  GIỚI THIỆU CƠ BẢN VỀ ESIM ",
       count: 3,
       icon: (
         <svg
@@ -57,14 +38,148 @@ const SupportView: React.FC = () => {
         </svg>
       ),
       items: [
-        t("travelEsimSim"),
-        t("physicalTravelSim"),
-        t("howToBuyTravelEsimSim"),
+        {
+          childId: 1.1,
+          title: "eSIM là gì?",
+          content: `<p><strong>eSIM</strong> (viết tắt của <em>embedded SIM</em>) l&agrave; một loại <strong>SIM điện tử được t&iacute;ch hợp trực tiếp v&agrave;o bảng mạch của thiết bị di động, </strong>cho ph&eacute;p người d&ugrave;ng k&iacute;ch hoạt g&oacute;i cước di động m&agrave; kh&ocirc;ng cần sử dụng SIM vật l&yacute; truyền thống.</p>
+<p>Kh&aacute;c với SIM vật l&yacute; truyền thống (phải th&aacute;o lắp bằng tay), eSIM <strong>kh&ocirc;ng cần khe cắm</strong>, kh&ocirc;ng cần lắp đặt thủ c&ocirc;ng m&agrave; c&oacute; thể được <strong>k&iacute;ch hoạt từ xa th&ocirc;ng qua m&atilde; QR</strong> do nh&agrave; mạng cung cấp.</p>
+<p><strong>eSIM l&agrave; xu hướng c&ocirc;ng nghệ viễn th&ocirc;ng của hiện tại v&agrave; tương lai</strong>, đặc biệt ph&ugrave; hợp với người d&ugrave;ng hiện đại cần sự nhanh gọn, linh hoạt v&agrave; tối ưu trải nghiệm số.</p>`,
+        },
+        {
+          childId: 1.2,
+          title: "Lý do nên sử dụng eSIM và khi nào nên dùng?",
+          content: `<h3><strong><em>1.2.1. eSIM ng&agrave;y c&agrave;ng được nhiều người d&ugrave;ng lựa chọn</em></strong><em> v&igrave; những ưu điểm vượt trội về tiện &iacute;ch, t&iacute;nh linh hoạt v&agrave; sự ph&ugrave; hợp với lối sống hiện đại:</em></h3>
+<ul>
+<li><strong>K&iacute;ch hoạt nhanh, kh&ocirc;ng cần đến cửa h&agrave;ng:</strong> Người d&ugrave;ng c&oacute; thể đăng k&yacute; v&agrave; k&iacute;ch hoạt eSIM ngay tr&ecirc;n điện thoại trong v&agrave;i ph&uacute;t th&ocirc;ng qua m&atilde; QR do nh&agrave; mạng cung cấp.</li>
+<li><strong>Kh&ocirc;ng lo mất hoặc hỏng SIM:</strong> V&igrave; được h&agrave;n trực tiếp v&agrave;o thiết bị, eSIM loại bỏ nguy cơ rơi, g&atilde;y, cong hoặc hư ch&acirc;n tiếp x&uacute;c như SIM vật l&yacute;.</li>
+<li><strong>Tiết kiệm kh&ocirc;ng gian thiết bị:</strong> Kh&ocirc;ng cần khe SIM vật l&yacute; gi&uacute;p thiết bị nhỏ gọn hơn, dễ thiết kế chống nước v&agrave; chống bụi tốt hơn.</li>
+<li><strong>Hỗ trợ nhiều số tr&ecirc;n một thiết bị:</strong> Một số d&ograve;ng m&aacute;y cho ph&eacute;p lưu trữ nhiều eSIM, gi&uacute;p người d&ugrave;ng sử dụng song song số c&aacute; nh&acirc;n v&agrave; số c&ocirc;ng việc m&agrave; kh&ocirc;ng cần d&ugrave;ng hai m&aacute;y.</li>
+<li><strong>Dễ d&agrave;ng chuyển đổi giữa c&aacute;c nh&agrave; mạng:</strong> Người d&ugrave;ng c&oacute; thể chuyển đổi số hoặc đổi nh&agrave; mạng chỉ bằng v&agrave;i thao t&aacute;c đơn giản &ndash; kh&ocirc;ng cần thay SIM, kh&ocirc;ng phải th&aacute;o m&aacute;y.</li>
+<li><strong>Linh hoạt khi đi nước ngo&agrave;i:</strong> Với eSIM, bạn c&oacute; thể mua g&oacute;i cước quốc tế online v&agrave; k&iacute;ch hoạt tức th&igrave; m&agrave; kh&ocirc;ng cần th&aacute;o SIM ch&iacute;nh &ndash; rất ph&ugrave; hợp cho người thường xuy&ecirc;n c&ocirc;ng t&aacute;c hoặc du lịch.</li>
+</ul>
+<h3><strong><em>1.2.2. N&ecirc;n d&ugrave;ng eSIM trong c&aacute;c trường hợp sau:</em></strong></h3>
+<ul>
+<li>Sở hữu thiết bị c&oacute; hỗ trợ eSIM như iPhone XS trở l&ecirc;n, Samsung d&ograve;ng Galaxy S hoặc Fold mới, Pixel, Apple Watch, iPad Cellular...</li>
+<li>Thường xuy&ecirc;n di chuyển hoặc đi c&ocirc;ng t&aacute;c quốc tế v&agrave; cần d&ugrave;ng eSIM du lịch ngắn hạn.</li>
+<li>Cần sử dụng song song 2 số điện thoại (v&iacute; dụ: một số c&ocirc;ng việc, một số c&aacute; nh&acirc;n).</li>
+<li>Muốn tiết kiệm thời gian, hạn chế thao t&aacute;c thủ c&ocirc;ng với SIM vật l&yacute;.</li>
+<li>Thiết bị kh&ocirc;ng c&oacute; khe cắm SIM (v&iacute; dụ: đồng hồ th&ocirc;ng minh).</li>
+</ul>
+ <div class="w-full overflow-x-auto">
+      <table class="w-full border border-gray-300 border-collapse text-sm md:text-base">
+        <thead>
+          <tr class="bg-gray-100">
+            <th class="border border-gray-300 px-4 py-3 text-left font-semibold">
+              Tiêu chí
+            </th>
+            <th class="border border-gray-300 px-4 py-3 text-center font-semibold">
+              eSIM
+            </th>
+            <th class="border border-gray-300 px-4 py-3 text-center font-semibold">
+              SIM vật lý
+            </th>
+          </tr>
+        </thead>
+
+        <tbody>
+          <tr>
+            <td class="border px-4 py-3 font-medium">
+              Kích hoạt, đăng ký
+            </td>
+            <td class="border px-4 py-3">
+              Từ xa qua mã QR, thao tác nhanh chóng
+            </td>
+            <td class="border px-4 py-3">
+              Cần đến cửa hàng hoặc đợi giao SIM
+            </td>
+          </tr>
+
+          <tr class="bg-gray-50">
+            <td class="border px-4 py-3 font-medium">
+              Thay đổi nhà mạng / số
+            </td>
+            <td class="border px-4 py-3">
+              Dễ dàng, không cần tháo lắp
+            </td>
+            <td class="border px-4 py-3">
+              Phải tháo SIM, đổi SIM mới
+            </td>
+          </tr>
+
+          <tr>
+            <td class="border px-4 py-3 font-medium">
+              Dùng nhiều số cùng lúc
+            </td>
+            <td class="border px-4 py-3">
+              Lưu trữ nhiều eSIM trên máy, dễ chuyển đổi
+            </td>
+            <td class="border px-4 py-3">
+              Giới hạn khe SIM (thường 1–2 SIM vật lý)
+            </td>
+          </tr>
+
+          <tr class="bg-gray-50">
+            <td class="border px-4 py-3 font-medium">
+              Độ an toàn và bền bỉ
+            </td>
+            <td class="border px-4 py-3">
+              Không rơi, không hỏng vật lý
+            </td>
+            <td class="border px-4 py-3">
+              Dễ mất, dễ gãy hoặc lỗi tiếp xúc
+            </td>
+          </tr>
+
+          <tr>
+            <td class="border px-4 py-3 font-medium">
+              Khả năng tương thích
+            </td>
+            <td class="border px-4 py-3">
+              Phù hợp cho thiết bị hiện đại, nhỏ gọn
+            </td>
+            <td class="border px-4 py-3">
+              Không phù hợp với thiết bị không có khe SIM
+            </td>
+          </tr>
+
+          <tr class="bg-gray-50">
+            <td class="border px-4 py-3 font-medium">
+              Khi đi nước ngoài
+            </td>
+            <td class="border px-4 py-3">
+              Mua eSIM du lịch online, dùng ngay
+            </td>
+            <td class="border px-4 py-3">
+              Phải mua SIM mới, đổi thủ công
+            </td>
+          </tr>
+
+          <tr>
+            <td class="border px-4 py-3 font-medium">
+              Hỗ trợ chống nước, chống bụi
+            </td>
+            <td class="border px-4 py-3">
+              Tăng độ kín thiết bị (vì không cần khe SIM)
+            </td>
+            <td class="border px-4 py-3">
+              Có khe hở, dễ bụi, kém chống nước
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+`,
+        },
+        {
+          childId: 1.3,
+          title: "Tiện ích nổi bật của eSIM so với SIM vật lý",
+          content: "",
+        },
       ],
       color: "bg-red-500",
     },
     {
-      title: t("installationGuide"),
+      title: "2.  HƯỚNG DẪN CÀI ĐẶT eSIM TRÊN CÁC THIẾT BỊ",
       count: 3,
       icon: (
         <svg
@@ -82,14 +197,312 @@ const SupportView: React.FC = () => {
         </svg>
       ),
       items: [
-        t("emailAndEsimQrCode"),
-        t("installationGuideForIphoneIos"),
-        t("installationGuideForAndroid"),
+        {
+          childId: 2.1,
+          title: "Hướng dẫn cài đặt eSIM trên các thiết bị",
+          content: `<p>C&agrave;i đặt eSIM tr&ecirc;n c&aacute;c thiết bị tương th&iacute;ch (iPhone, Samsung, Google Pixel,&hellip;) rất đơn giản v&agrave; nhanh ch&oacute;ng. Sau khi thanh to&aacute;n, bạn sẽ nhận được email từ nh&agrave; cung cấp (như InfiGate) chứa th&ocirc;ng tin g&oacute;i eSIM v&agrave; m&atilde; QR để k&iacute;ch hoạt.</p>
+<p>To&agrave;n bộ qu&aacute; tr&igrave;nh c&agrave;i đặt v&agrave; k&iacute;ch hoạt eSIM được thực hiện <strong>ho&agrave;n to&agrave;n trực tuyến</strong>, chỉ mất khoảng <strong>3&ndash;5 ph&uacute;t</strong>.</p>`,
+        },
+        {
+          childId: 2.2,
+          title: "Chuẩn bị trước khi cài đặt eSIM",
+          content: `<p>Trước khi c&agrave;i đặt, bạn cần đảm bảo:</p>
+<h3><strong>2.1.1. Thiết bị hỗ trợ eSIM</strong></h3>
+<p>V&agrave;o <strong>C&agrave;i đặt &rarr; Th&ocirc;ng tin thiết bị (hoặc Giới thiệu về điện thoại)</strong> để kiểm tra.</p>
+<p>Một số d&ograve;ng m&aacute;y phổ biến hỗ trợ eSIM:</p>
+<ul>
+<li><strong>iPhone</strong>: Từ iPhone XS, XR trở l&ecirc;n<br /> </li>
+<li><strong>Samsung</strong>: Galaxy S20 trở l&ecirc;n, Z Fold/Flip, Note 20 Ultra, A54, A73...<br /> </li>
+<li><strong>Google Pixel</strong>: Từ Pixel 3 trở l&ecirc;n<br /> </li>
+<li><strong>Apple Watch</strong>, <strong>iPad Pro</strong> (bản Cellular)<br /> </li>
+</ul>
+<p><em>Lưu &yacute;</em>: Lưu &yacute;: Một số d&ograve;ng m&aacute;y x&aacute;ch tay c&oacute; thể kh&ocirc;ng bật được eSim. Tham khảo <a href="https://gigago.vn/thiet-bi-ho-tro-esim/">danh s&aacute;ch thiết bị hỗ trợ eSIM</a> của ch&uacute;ng t&ocirc;i để xem liệu thiết bị của bạn c&oacute; d&ugrave;ng được eSIM kh&ocirc;ng.</p>
+<p>&nbsp;</p>
+<h3><strong>2.1.2. Email v&agrave; m&atilde; QR eSIM</strong></h3>
+<ul>
+<li>Kiểm tra email để nhận <strong>m&atilde; QR</strong>, <strong>địa chỉ SM-DP+</strong>, v&agrave; <strong>m&atilde; k&iacute;ch hoạt</strong> từ nh&agrave; cung cấp.</li>
+<li>M&atilde; n&agrave;y c&oacute; thể được in ra, chụp lại hoặc qu&eacute;t từ thiết bị kh&aacute;c.</li>
+</ul>
+<p><em>M&atilde; QR c&oacute; thời hạn k&iacute;ch hoạt 30 ng&agrave;y kể từ khi nhận được email.</em></p>
+<h3><strong>2.1.3. Kết nối Wi-Fi ổn định</strong></h3>
+<ul>
+<li>Thiết bị cần c&oacute; kết nối Internet (qua WiFi hoặc 3G/4G) trong suốt qu&aacute; tr&igrave;nh c&agrave;i đặt.</li>
+</ul>
+<p><strong><em>Mẹo</em></strong>: iOS 17 v&agrave; Samsung S20 trở l&ecirc;n đ&atilde; hỗ trợ <strong>qu&eacute;t m&atilde; QR từ thư viện ảnh</strong>.</p>`,
+        },
+        {
+          childId: 2.3,
+          title: "Hướng dẫn cài đặt trên từng dòng thiết bị",
+          content: `<h3><strong>2.2.1. iPhone (iOS)</strong></h3>
+<h4><strong>2.2.1.1. C&aacute;ch 1: Qu&eacute;t m&atilde; QR</strong></h4>
+<ol>
+<li>Mở thiết bị iOS của bạn, v&agrave;o <strong>Settings</strong>/C&agrave;i đặt &gt; <strong>Cellular/</strong>Di động &gt; Add eSIM/Th&ecirc;m g&oacute;i cước di động &gt; Use QR code/D&ugrave;ng m&atilde; QR <em>(hoặc mở Camera v&agrave; qu&eacute;t m&atilde; QR)</em></li>
+<li>Qu&eacute;t m&atilde; QR nhận từ email.</li>
+<li>Tại m&agrave;n<strong> Activate eSIM/K&iacute;ch hoạt eSIM</strong>, chọn<strong> Tiếp tục</strong>/<strong>Continue</strong>.</li>
+<li>Tại m&agrave;n <strong>Cellular Setup Complete</strong>/<strong>Ho&agrave;n th&agrave;nh c&agrave;i đặt di động</strong>, chọn <strong>Done</strong>.
+<img src="https://skysimhub.vn/assets/guide/2_1.png" alt="Activate eSIM on iOS"/></li>
+</ol>
+<h4><strong>2.2.1.2. C&aacute;ch 2: Nhập th&ocirc;ng tin thủ c&ocirc;ng</strong></h4>
+<ol>
+<li>V&agrave;o <strong>Settings</strong>/<strong>C&agrave;i đặt</strong><strong> &gt; Cellular</strong>/<strong>Di động</strong><strong> &gt; Add eSIM/Th&ecirc;m eSIM </strong>(hoặc <strong>Set Up Cellular </strong>nếu kh&ocirc;ng c&oacute; <strong>Add eSIM</strong>)<strong>&gt; </strong>chọn <strong>Enter Details Manually</strong>.</li>
+<li>Nhập địa chỉ <strong>SM-DP+</strong> v&agrave; <strong>m&atilde; k&iacute;ch hoạt</strong>.</li>
+<li>Tại m&agrave;n Activate eSIM/K&iacute;ch hoạt eSIM, chọn Continue/Tiếp tục.</li>
+<li>Tại m&agrave;n <strong>Cellular Setup Complete/Ho&agrave;n th&agrave;nh c&agrave;i đặt di động</strong>, chọn &nbsp;Tại m&agrave;n Activate eSIM/K&iacute;ch hoạt eSIM, chọn<strong> Continue</strong>/<strong>Tiếp tục.</strong></li>
+<li>7. Tại m&agrave;n<strong> Cellular Setup Complete</strong>/<strong>Ho&agrave;n th&agrave;nh c&agrave;i đặt di động,</strong> chọn <strong>Done.</strong>
+<img src="https://skysimhub.vn/assets/guide/2_2.png" alt="Activate eSIM on iOS"/></li>
+</ol>
+<h4><strong>2.2.1.3. C&aacute;ch 3: Sử dụng n&uacute;t &ldquo;Install Now/C&agrave;i đặt ngay&rdquo; tr&ecirc;n m&agrave;n h&igrave;nh My eSIM tr&ecirc;n app hoặc email InfiGate gửi.</strong></h4>
+<ol>
+<li>Truy cập app InfiGate &gt; My eSIM hoặc mở email eSIM đ&atilde; được InfiGate gửi.</li>
+<li>Bấm n&uacute;t Instal Now/C&agrave;i đặt ngay trong m&agrave;n h&igrave;nh hiển thị chi tiết</li>
+<li>Tại m&agrave;n<strong> Activate eSIM/K&iacute;ch hoạt eSIM</strong>, chọn<strong> Tiếp tục</strong>/<strong>Continue</strong>.</li>
+<li>Tại m&agrave;n <strong>Cellular Setup Complete</strong>/<strong>Ho&agrave;n th&agrave;nh c&agrave;i đặt di động</strong>, chọn <strong>Done</strong>.</li>
+</ol>
+<h4><strong>2.2.1.4. K&iacute;ch hoạt eSIM du lịch tr&ecirc;n iPhone</strong></h4>
+<ol>
+<li>Sau khi đến quốc gia sử dụng eSIM, v&agrave;o <strong>Settings</strong>/<strong>C&agrave;i đặt</strong> &gt; <strong>Cellular</strong>/<strong>Di động</strong>.</li>
+<li>Bật <strong>Turn on this line </strong>/ <strong>Bật d&ograve;ng n&agrave;y </strong>v&agrave; <strong>Data roaming </strong>/ <strong>Chuyển v&ugrave;ng dữ liệu</strong> cho d&ograve;ng eSIM InfiGate.</li>
+<li>V&agrave;o <strong>Cellular</strong>/<strong>Di động</strong>, chọn <strong>Cellular Data</strong>/<strong>Dữ liệu di động</strong> &gt; chọn <strong>InfiGate eSIM</strong> l&agrave; k&ecirc;nh sử dụng dữ liệu di động ch&iacute;nh.</li>
+</ol>
+<p>&nbsp;<em>Bạn đ&atilde; c&oacute; thể sử dụng eSIM để truy cập Internet.<br /> </em></p>
+<h4><strong>2.2.1.5. X&oacute;a eSIM tr&ecirc;n iPhone</strong></h4>
+<ol>
+<li>V&agrave;o<strong> Settings</strong>/C&agrave;i đặt <strong>&gt; Cellular/Di động.</strong></li>
+<li>Chọn g&oacute;i eSIM cần x&oacute;a &rarr; nhấn <strong>Remove Cellular Plan/X&oacute;a g&oacute;i di động</strong>. &nbsp;Sau đ&oacute;, x&aacute;c nhận lựa chọn của bạn.</li>
+</ol>
+<p><em>Lưu &yacute;</em>: Một số eSIM chỉ k&iacute;ch hoạt được <strong>1 lần duy nhất</strong>. Nếu x&oacute;a, m&atilde; QR sẽ kh&ocirc;ng d&ugrave;ng lại được. Bạn cần <strong>li&ecirc;n hệ lại nh&agrave; cung cấp để được cấp lại m&atilde; mới</strong> (ph&iacute;: 25.000đ/lần).</p>
+<h3><strong>2.2.2. Android (Samsung, Google Pixel&hellip;)</strong></h3>
+<h4><strong>2.2.2.1. C&aacute;ch 1: Qu&eacute;t m&atilde; QR</strong></h4>
+<ol>
+<li>V&agrave;o <strong>C&agrave;i đặt/Setting&gt; Quản l&yacute; SIM/SIM Manager</strong></li>
+<li>Chọn <strong>Th&ecirc;m eSIM/Add eSIM &gt; Qu&eacute;t m&atilde; QR</strong></li>
+<li>Đưa m&atilde; QR v&agrave;o khung qu&eacute;t, sau đ&oacute; nhấn <strong>Th&ecirc;m (Add) </strong>v&agrave; đợi v&agrave;i ph&uacute;t để eSIM được th&ecirc;m v&agrave;o thiết bị.</li>
+</ol>
+<p><strong><em>Lưu &yacute;</em></strong>: <em>T&iacute;nh năng tải l&ecirc;n ảnh m&atilde; QR chỉ &aacute;p dụng cho Samsung Galaxy S20, c&aacute;c d&ograve;ng mới hơn của Samsung v&agrave; một số d&ograve;ng điện thoại Android kh&aacute;c.</em></p>
+<img src="https://skysimhub.vn/assets/guide/2_3.png" alt="Activate eSIM on Android"/>
+<h4><strong>2.2.2.2. C&aacute;ch 2: Nhập th&ocirc;ng tin thủ c&ocirc;ng</strong></h4>
+<ol>
+<li>Mở điện thoại, v&agrave;o mục <strong>C&agrave;i đặt/Setting</strong></li>
+<li>Chọn Quản l&yacute; <strong>SIM/SIM Manage</strong></li>
+<li>Chọn Th&ecirc;m <strong>eSIM/Add eSIM</strong></li>
+<li>Tại khung qu&eacute;t m&atilde; QR, chọn <strong>Enter activation code/Nhập m&atilde; k&iacute;ch hoạt</strong></li>
+<li>Nhập th&ocirc;ng tin eSIM được gửi từ nh&agrave; cung cấp v&agrave;o &ocirc; &gt; bấm <strong>Connect/Kết nối</strong>.</li>
+<li>Khi được hỏi <strong>Add eSIM</strong>/<strong>Th&ecirc;m eSIM</strong> kh&ocirc;ng, bạn bấm <strong>Add</strong>/<strong>Th&ecirc;m</strong> v&agrave; đợi v&agrave;i ph&uacute;t để điện thoại th&ecirc;m eSIM v&agrave;o m&aacute;y để ho&agrave;n tất c&agrave;i đặt.
+<img src="https://skysimhub.vn/assets/guide/2_4.png" alt="Activate eSIM on Android"/></li>
+</ol>
+<h4><strong>2.2.2.3. K&iacute;ch hoạt eSIM du lịch tr&ecirc;n Samsung</strong></h4>
+<ol>
+<li>Sau khi đến nơi, v&agrave;o <strong>Settings</strong>/<strong>C&agrave;i đặt</strong> &gt; <strong>Connections/Kết nối</strong>&gt;<strong> Mạng di động</strong>&gt; bật <strong>Chuyển v&ugrave;ng dữ liệu/Data Roaming</strong></li>
+<li>Quay trở lại m&agrave;n <strong>Connection/Kết nối</strong>&gt; V&agrave;o <strong>SIM Manager/Quản l&yacute; SIM&gt; </strong>&nbsp;bật <strong>eSIM InfiGate</strong></li>
+<li>V&agrave;o <strong>Mobile Data/Dữ liệu di dộng</strong>, chọn <strong>InfiGate eSIM</strong> l&agrave; mạng ch&iacute;nh</li>
+</ol>
+<p><em>eSIM sẵn s&agrave;ng để d&ugrave;ng Internet.</em></p>
+<h4><strong>2.2.2.4. X&oacute;a eSIM tr&ecirc;n Android</strong></h4>
+<ol>
+<li>V&agrave;o <strong>C&agrave;i đặt &gt; Connections/Kết nối &gt; SIM manager</strong>/<strong>Tr&igrave;nh quản l&yacute; SIM</strong></li>
+<li>Chọn eSIM cần x&oacute;a &rarr; Gạt sang <strong>&ldquo;OFF&rdquo;</strong> &rarr; nhấn <strong>X&oacute;a (Remove) </strong>v&agrave; x&aacute;c nhận lựa chọn của bạn.</li>
+</ol>
+<p><strong><em>Lưu &yacute;: </em></strong><em>Mỗi eSIM chỉ k&iacute;ch hoạt được 1 lần. Nếu cần d&ugrave;ng lại, bạn phải li&ecirc;n hệ nh&agrave; cung cấp để cấp lại m&atilde; QR. Ph&iacute; cấp lại eSIM l&agrave; 25.000đ/lần.</em></p>`,
+        },
+      ],
+      color: "bg-red-600",
+    },
+    {
+      title: "3.  HƯỚNG DẪN BẬT CHUYỂN VÙNG DỮ LIỆU (Roaming)",
+      count: 1,
+      icon: (
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
+          />
+        </svg>
+      ),
+      items: [
+        {
+          childId: 3.1,
+          title: "Hướng dẫn bật chuyển vùng dữ liệu (Roaming)",
+          content: `<p><em>*Vui l&ograve;ng đảm bảo rằng bạn đang ở quốc gia đến để c&oacute; thể sử dụng eSIM.</em></p>
+<ul>
+<li><strong>iOS</strong>: C&agrave;i đặt &gt; Di động &gt; Chọn eSIM &gt; Bật &ldquo;Chuyển v&ugrave;ng dữ liệu&rdquo;</li>
+<img src="https://skysimhub.vn/assets/guide/3_1.png" alt="Enable Data Roaming on iOS"/>
+</ul>
+<ul>
+<li><strong>Android</strong>: C&agrave;i đặt &gt; Kết nối &gt; Mạng di động &gt; Bật &ldquo;Chuyển v&ugrave;ng dữ liệu&rdquo;</li>
+<img src="https://skysimhub.vn/assets/guide/3_2.png" alt="Enable Data Roaming on Android"/>
+</ul>`,
+        },
+      ],
+      color: "bg-red-600",
+    },
+    {
+      title: "4. CÁCH KIỂM TRA DUNG LƯỢNG ĐÃ DÙNG",
+      count: 1,
+      icon: (
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
+          />
+        </svg>
+      ),
+      items: [
+        {
+          childId: 4.1,
+          title: "Cách kiểm tra dung lượng đã dùng",
+          content: `<p>Lưu &yacute;: Chuyển v&ugrave;ng thế giới hiện tại l&agrave; tổng dung lượng một chu kỳ. Để biết ch&iacute;nh x&aacute;c dung lượng mỗi ng&agrave;y đ&atilde; d&ugrave;ng, bạn c&oacute; thể l&agrave;m mới bộ đếm mỗi cuối ng&agrave;y bằng c&aacute;ch:</p>
+<p>V&agrave;o C&agrave;i đặt &gt; Chọn Di động &gt; K&eacute;o đến cuối trang v&agrave; chọn Reset Statistics</p>
+<p><strong>iOS:</strong></p>
+<p>V&agrave;o C&agrave;i đặt &gt; Chọn Di động &gt; Chọn Dữ liệu di động &gt; Chọn eSIM cần kiểm tra &gt; Quay lại m&agrave;n h&igrave;nh Di động &gt; Xem dung lượng đ&atilde; d&ugrave;ng tại Chuyển v&ugrave;ng thế giới hiện tại</p>
+<img src="https://skysimhub.vn/assets/guide/4_1.png" alt="Check Data Usage on iOS"/>
+<p><strong>Android:</strong></p>
+<p>V&agrave;o C&agrave;i đặt &gt; Chọn Kết nối &gt; Chọn Quản l&yacute; SIM &gt; Bật eSIM cần kiểm tra &gt; Quay lại m&agrave;n h&igrave;nh Kết nối &gt; Chọn Sử dụng dữ liệu &gt; Xem dung lượng đ&atilde; d&ugrave;ng tại mục chứa t&ecirc;n eSIM</p>
+<img src="https://skysimhub.vn/assets/guide/4_2.png" alt="Check Data Usage on Android"/>`,
+        },
+      ],
+      color: "bg-red-600",
+    },
+    {
+      title: "5. CÁCH KIỂM TRA ESIM ĐANG SỬ DỤNG DỮ LIỆU",
+      count: 1,
+      icon: (
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
+          />
+        </svg>
+      ),
+      items: [
+        {
+          childId: 5.1,
+          title: "Cách kiểm tra eSIM đang sử dụng dữ liệu",
+          content: `<p><strong>IOS:</strong></p>
+<p>V&agrave;o <strong>C&agrave;i đặt</strong> &gt; Chọn <strong>Di động</strong> &gt; Đảm bảo bạn đ&atilde; bật eSIM &gt; Chọn <strong>Dữ liệu di động</strong> &gt; eSIM đ&aacute;nh dấu tick ✓ l&agrave; eSIM đang d&ugrave;ng dữ liệu</p>
+<img src="https://skysimhub.vn/assets/guide/5_1.png" alt="Check eSIM using data on iOS"/>
+<p><strong>ANDROID:</strong></p>
+<p>V&agrave;o <strong>C&agrave;i đặt</strong> &gt; Chọn <strong>Kết nối</strong> &gt; Chọn <strong>Quản l&yacute; SIM</strong> &gt; Đảm bảo bạn đ&atilde; bật eSIM &gt; K&eacute;o xuống v&agrave; kiểm tra eSIM đang d&ugrave;ng dữ liệu tại <strong>Dữ liệu di động</strong></p>
+<img src="https://skysimhub.vn/assets/guide/5_2.png" alt="Check eSIM using data on Android"/>`,
+        },
+      ],
+      color: "bg-red-600",
+    },
+    {
+      title: "6. CÁCH ƯỚC TÍNH DUNG LƯỢNG",
+      count: 1,
+      icon: (
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
+          />
+        </svg>
+      ),
+      items: [
+        {
+          childId: 6.1,
+          title: "Cách ước tính dung lượng",
+          content: `<img src="https://skysimhub.vn/assets/guide/6_1.png" alt="Data Usage Estimation"/>`,
+        },
+      ],
+      color: "bg-red-600",
+    },
+    {
+      title: "7. CÁC SỰ CỐ ESIM PHỔ BIẾN",
+      count: 1,
+      icon: (
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
+          />
+        </svg>
+      ),
+      items: [
+        {
+          childId: 7.1,
+          title: "Các sự cố eSIM phổ biến",
+          content: `<h3><strong><em>2.7.1. T&ocirc;i kh&ocirc;ng nhận được email chứa m&atilde; eSIM?</em></strong></h3>
+<ul>
+<li>Email chứa th&ocirc;ng tin eSIM, bao gồm m&atilde; QR v&agrave; c&aacute;c th&ocirc;ng tin của g&oacute;i sẽ được gửi <strong>trong v&ograve;ng 5&ndash;10 ph&uacute;t sau thanh to&aacute;n</strong>.<br /> </li>
+<li>Nếu kh&ocirc;ng c&oacute;, h&atilde;y li&ecirc;n hệ:
+<ul>
+<li>Zalo/Hotline/Whatsapp: +84336548007</li>
+<li>Email: klinhnguyen@viettech.asia<br /> </li>
+</ul>
+</li>
+</ul>
+<h3><strong><em>2.7.2. T&ocirc;i kh&ocirc;ng thể qu&eacute;t m&atilde; QR?</em></strong></h3>
+<p>C&oacute; nhiều l&yacute; do khiến bạn kh&ocirc;ng thể qu&eacute;t (scan) m&atilde; QR th&agrave;nh c&ocirc;ng:</p>
+<ul>
+<li><strong>Kh&ocirc;ng c&oacute; kết nối Internet:</strong> để qu&eacute;t m&atilde; QR eSIM, bạn cần c&oacute; kết nối Internet (qua WiFi hoặc dữ liệu di động). Vui l&ograve;ng đảm bảo chất lượng Internet trong qu&aacute; tr&igrave;nh c&agrave;i đặt eSIM.</li>
+<li><strong>Điện thoại kh&ocirc;ng tương th&iacute;ch eSIM:</strong> Khi đ&oacute; h&atilde;y kiểm tra lại C&agrave;i đặt (Settings) để chắc chắn rằng điện thoại của bạn c&oacute; hỗ trợ eSIM.</li>
+<li><strong>Kh&ocirc;ng qu&eacute;t m&atilde; QR bằng phần c&agrave;i đặt eSIM:</strong> eSIM chỉ c&oacute; thể c&agrave;i đặt th&agrave;nh c&ocirc;ng bằng việc qu&eacute;t m&atilde; QR trong phần c&agrave;i đặt eSIM, chứ kh&ocirc;ng phải v&agrave;o ứng dụng Camera của điện thoại hay ứng dụng kh&aacute;c để qu&eacute;t.</li>
+<li><strong>M&atilde; QR hết hạn:</strong> ở một số trường hợp, m&atilde; QR c&oacute; thể đ&atilde; bị sử dụng rồi cũng l&agrave; l&yacute; do khiến bạn kh&ocirc;ng qu&eacute;t m&atilde;.</li>
+<li><strong>M&atilde; QR kh&ocirc;ng nằm trọn trong khung camera:</strong> vui l&ograve;ng đặt điện thoại sao cho m&atilde; QR nằm trọn trong khung qu&eacute;t trước khi tiến h&agrave;nh qu&eacute;t m&atilde;.</li>
+</ul>
+<h3><strong><em>2.7.3 T&ocirc;i cần l&agrave;m g&igrave; khi lỡ x&oacute;a eSIM?</em></strong></h3>
+<ul>
+<li>Th&ocirc;ng thường, mỗi eSIM chỉ được c&agrave;i đặt một lần duy nhất tr&ecirc;n một thiết bị v&agrave; bạn sẽ kh&ocirc;ng thể qu&eacute;t lại m&atilde; QR của eSIM đ&oacute;. Tuy nhi&ecirc;n, trong trường hợp cần thiết, bạn h&atilde;y li&ecirc;n hệ với bộ phận chăm s&oacute;c kh&aacute;ch h&agrave;ng của nh&agrave; cung cấp eSIM để được hỗ trợ nh&eacute;.</li>
+</ul>
+<h3><strong><em>2.7.4. eSIM đ&atilde; c&agrave;i nhưng kh&ocirc;ng c&oacute; s&oacute;ng?</em></strong></h3>
+<p>*Vui l&ograve;ng đảm bảo rằng bạn đang ở quốc gia đến để c&oacute; thể sử dụng eSIM.</p>
+<p><strong>C&aacute;ch 1:</strong> Vui l&ograve;ng kiểm tra xem bạn đ&atilde; bật chế độ Chuyển v&ugrave;ng dữ liệu v&agrave; chế độ Dữ liệu di động tr&ecirc;n điện thoại chưa.</p>
+<ul>
+<li><strong>iOS:</strong>
+<img src="https://skysimhub.vn/assets/guide/7_1.png" alt="Activate eSIM on Android"/></li>
+<li><strong>Android:</strong>
+<img src="https://skysimhub.vn/assets/guide/7_2.png" alt="Activate eSIM on Android"/>
+</li>
+</ul>
+<p><strong>C&aacute;ch 2: Bạn thử Reset lại điện thoại hoặc chờ khoảng 5-10 ph&uacute;t v&igrave; một số mạng k&iacute;ch hoạt hơi l&acirc;u.</strong></p>
+<p><strong>Nếu bạn vẫn kh&ocirc;ng thể khắc phục được sự cố, vui l&ograve;ng li&ecirc;n hệ với ch&uacute;ng t&ocirc;i c&agrave;ng sớm c&agrave;ng tốt qua<em> Zalo +84336548007</em> để được hỗ trợ</strong></p>`,
+        },
       ],
       color: "bg-red-600",
     },
   ];
 
+  const [content, setContent] = useState<{ title: string; content: string }>({
+    title: categories[0].items[0].title,
+    content: categories[0].items[0].content,
+  });
+
   return (
     <div className="bg-white min-h-screen">
       <div className="max-w-7xl mx-auto px-4 py-6">
@@ -127,7 +540,7 @@ const SupportView: React.FC = () => {
                   >
                     {cat.icon}
                   </div>
-                  <h3 className="text-[17px] font-black text-[#EE0434] leading-tight">
+                  <h3 className="text-[17px] font-black leading-tight">
                     {cat.title}
                   </h3>
                 </div>
@@ -135,24 +548,30 @@ const SupportView: React.FC = () => {
                   {cat.items.map((item, i) => (
                     <button
                       key={i}
-                      onClick={() => setActiveItem(item)}
+                      onClick={() => {
+                        setActiveItem(item.childId);
+                        setContent({
+                          title: item.title,
+                          content: item.content,
+                        });
+                      }}
                       className="group flex items-center justify-between w-full text-left relative"
                     >
                       <div
                         className={`absolute -left-[22px] w-2 h-2 rounded-full border-2 border-white ${
-                          activeItem === item
+                          activeItem === item.childId
                             ? "bg-[#EE0434] scale-125"
                             : "bg-slate-200"
                         }`}
                       ></div>
                       <span
                         className={`text-[14px] font-bold transition-colors pl-4 ${
-                          activeItem === item
+                          activeItem === item.childId
                             ? "text-[#EE0434]"
                             : "text-slate-500 group-hover:text-[#EE0434]"
                         }`}
                       >
-                        {item}
+                        {item.title}
                       </span>
                     </button>
                   ))}
@@ -162,11 +581,13 @@ const SupportView: React.FC = () => {
           </aside>
           <main className="lg:col-span-8">
             <h1 className="text-4xl md:text-5xl font-black text-[#EE0434] mb-10">
-              {t("guideAndHelp")}
+              {content.title}
             </h1>
-            <p className="text-lg leading-relaxed text-slate-600">
-              {t("selectTopicInstructions")}
-            </p>
+            <div
+              className="prose max-w-none text-gray-800"
+              style={{ lineHeight: "40px" }}
+              dangerouslySetInnerHTML={{ __html: content.content }}
+            />
           </main>
         </div>
       </div>