Просмотр исходного кода

页面添加loading.tsx;删除一些不起作用的Suspense;删除一些没用额文件;

fogwind 16 часов назад
Родитель
Сommit
9d032641f5
38 измененных файлов с 625 добавлено и 728 удалено
  1. 1 1
      .env.example
  2. BIN
      public/image/placeholder.webp
  3. 3 3
      src/app/(checkout)/checkout/_components/LoadingPaymentMethod.tsx
  4. 48 0
      src/app/(checkout)/checkout/cart/loading.tsx
  5. 99 0
      src/app/(checkout)/checkout/continuetopay/loading.tsx
  6. 98 0
      src/app/(checkout)/checkout/loading.tsx
  7. 11 0
      src/app/(public)/(cms)/loading.tsx
  8. 0 0
      src/app/(public)/(cms)/track_order/_components/TrackFaqs.tsx
  9. 0 0
      src/app/(public)/(cms)/track_order/_components/TrackOrder.tsx
  10. 0 0
      src/app/(public)/(cms)/track_order/page.tsx
  11. 45 0
      src/app/(public)/category/[slug]/[id]/loading.tsx
  12. 2 4
      src/app/(public)/category/[slug]/[id]/page.tsx
  13. 11 0
      src/app/(public)/customer/loading.tsx
  14. 56 0
      src/app/(public)/loading.tsx
  15. 6 14
      src/app/(public)/paymentresult/_components/SkeletonCancelOrFailure.tsx
  16. 90 106
      src/app/(public)/paymentresult/_components/SuccessPageSkeleton.tsx
  17. 6 0
      src/app/(public)/paymentresult/result/loading.tsx
  18. 53 0
      src/app/(public)/product/[...urlProduct]/loading.tsx
  19. 1 6
      src/app/(public)/product/[...urlProduct]/page.tsx
  20. 3 3
      src/app/(public)/product/_components/ProductMedia.tsx
  21. 48 0
      src/app/(public)/search/loading.tsx
  22. 10 0
      src/app/globals.css
  23. 6 2
      src/components/common/LoadingSpinner.tsx
  24. 0 26
      src/components/common/skeleton/AddressSkeleton.tsx
  25. 0 31
      src/components/common/skeleton/AuthPlaceHolder.tsx
  26. 0 61
      src/components/common/skeleton/CheckoutSkeleton.tsx
  27. 0 50
      src/components/common/skeleton/FilterSkeleton.tsx
  28. 0 14
      src/components/common/skeleton/IconSkeleton.tsx
  29. 0 22
      src/components/common/skeleton/NavbarSkeleton.tsx
  30. 0 79
      src/components/common/skeleton/ProductCartSkeleton.tsx
  31. 22 87
      src/components/common/skeleton/ProductSkeleton.tsx
  32. 0 15
      src/components/common/skeleton/SearchSkeleton.tsx
  33. 0 135
      src/components/common/slider/HeroCarousel.tsx
  34. 0 42
      src/components/common/slider/HeroCarouselShimmer.tsx
  35. 0 2
      src/components/common/slider/index.ts
  36. 4 4
      src/components/layout/navbar/MobileSearch.tsx
  37. 0 17
      src/components/layout/navbar/NavigationSkeleton.tsx
  38. 2 4
      src/components/layout/navbar/index.tsx

+ 1 - 1
.env.example

@@ -16,7 +16,7 @@ NEXT_PUBLIC_BAGISTO_STOREFRONT_KEY=your_storefront_key_here
 
 # NextAuth Configuration 测试环境和生产环境要写实际部署的域名
 NEXTAUTH_URL=http://localhost:3001
-# NextAuth 使用 secret(下面的值)对 session中的token 对象进行 签名 + 加密,生成一个 JWT 字符串,解密这个JWT字符串就可以还原token对象。
+# NextAuth 使用 secret(下面的值)对 session中的token 对象进行 签名 + 加密,生成一个 JWT 字符串,解密这个JWT字符串就可以还原token对象。openssl rand -base64 32
 NEXTAUTH_SECRET=9jstKgQ1Q22PlDDhPtXTZ6G4MEzHGDJIkebcd/5UyZ4=
 
 # paypal client id 测试站 AXSFRWCfsqKWU2OuXAirHm5FG7U3J4KlYOpP4NvvJ9hQzK10SWMrHqotwnvQhjznf9A-stXrtVmrHBQR

BIN
public/image/placeholder.webp


+ 3 - 3
src/app/(checkout)/checkout/_components/LoadingPaymentMethod.tsx

@@ -2,11 +2,11 @@ export default function LoadingPaymentMethod() {
     return (
         <div className="mt-3 w-full animate-pulse px-0">
             <div className="group box-border flex items-center relative mt-3 p-3 rounded-sm">
-                <p className="pr-2 flex-none h-8 w-12 bg-gray-300"></p>
-                <p className="text-ly-12 text-gray-300 bg-gray-300 ml-1">Paypay Smart Button</p>
+                <p className="pr-2 flex-none h-8 w-12 bg-skeletonbg"></p>
+                <p className="text-ly-12 w-45 h-3.5 bg-skeletonbg ml-1"></p>
   
 
-                <div className="absolute top-1/2 -translate-y-1/2 right-3 bg-gray-300 w-4 h-4"></div>
+                <div className="absolute top-1/2 -translate-y-1/2 right-3 bg-skeletonbg w-4 h-4"></div>
             </div>
         </div>
     );

+ 48 - 0
src/app/(checkout)/checkout/cart/loading.tsx

@@ -0,0 +1,48 @@
+import Image from "next/image";
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2,3,4,5];
+    return (
+        <div className="w-full h-full animate-pulse">
+            <header className="sticky top-0 z-10 w-full">
+                <div className="relative w-full h-15 flex items-center justify-center bg-neutral-50 text-ly-16">
+                    <div className="absolute left-4 w-6 h-6 bg-skeletonbg"></div>
+                    <p className="flex-none h-6 w-25 bg-skeletonbg"></p>
+                </div>
+            </header>
+            <div className="mt-6 box-border px-4 pb-8">
+                {arr.map((i) => {
+                    return (
+                        <div key={i} className="w-full flex gap-2 mt-4 first:mt-0 pb-4 border-b-1 border-b-[#f0f0f0] last:border-none">
+                            <div className="relative w-33 h-44 flex-none bg-skeletonbg">
+                                <Image className="object-cover" fill src={NOT_IMAGE} alt="placeholder image"/>
+                            </div>
+                            <div className="w-full flex flex-col justify-between">
+                                <div className="w-full">
+                                    <div className="flex items-center gap-2 w-full">
+                                        <div className="w-full line-clamp-2 text-ly-12 leading-5">
+                                            <p className="bg-skeletonbg h-5">&nbsp;</p>
+                                            <p className="bg-skeletonbg w-1/2 h-5 mt-0.5">&nbsp;</p>
+                                        </div>
+                                        <button className="flex-none w-4 h-4 bg-skeletonbg" type="button"></button>
+                                    </div>
+                                    <div className="w-full mt-2 text-ly-12 h-5 rounded-sm px-2.5 py-1.5 leading-5 bg-skeletonbg"></div>
+                                </div>
+                                <div className="flex items-center justify-between">
+                                    <div className="flex items-center gap-1.5">
+                                        <span className="text-ly-14 font-bold bg-skeletonbg h-4 w-15"></span>
+                                        {/* <span className="text-ly-12 text-[#d3d3d3] line-through">$200.12</span> */}
+                                    </div>
+                                    <div className="w-25 h-8 flex-none flex rounded-lg p-2 gap-4 bg-skeletonbg"></div>
+                                </div>
+                            </div>
+                        </div>
+                    )
+                })}        
+                
+
+            
+            </div>
+        </div>
+    );
+}

+ 99 - 0
src/app/(checkout)/checkout/continuetopay/loading.tsx

@@ -0,0 +1,99 @@
+import Image from "next/image";
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2];
+    return (
+        <div className="w-full h-full animate-pulse">
+            <header className="sticky top-0 z-10 w-full">
+                <div className="relative w-full h-15 flex items-center justify-center bg-neutral-50 text-ly-16">
+                    <div className="absolute left-4 w-6 h-6 bg-skeletonbg"></div>
+                    <p className="flex-none h-6 w-25 bg-skeletonbg"></p>
+                </div>
+            </header>
+            <div>
+                <div className="sticky top-15 z-10 box-border w-full h-14 px-4 flex items-center justify-between bg-skeletonbg"></div>
+                        
+                <div className="mt-6 box-border px-4">
+                    <h3 className="text-ly-24 font-medium bg-skeletonbg w-30 h-6"></h3>
+                    <div className="w-full mt-3 box-border rounded-md px-3.75">
+                        <div className="flex h-11.25 items-center justify-between">
+                            <p className="h-3.5 font-medium w-30 bg-skeletonbg"></p>
+                        </div>
+                        <div className="flex items-center h-10">
+                            <span className="text-ly-12 ml-2.5 bg-skeletonbg w-90 h-3.5"></span>
+                        </div>
+                    </div>  
+    
+                </div>
+            
+                <div className="mt-6 box-border px-4">
+                    <h3 className="text-ly-24 font-medium bg-skeletonbg w-30 h-6"></h3>
+                    <div className="w-full mt-3 box-border rounded-md px-3.75">
+                        <div className="flex h-11.25 items-center justify-between">
+                            <p className="h-3.5 font-medium w-30 bg-skeletonbg"></p>
+                        </div>
+                        <div className="flex items-center h-10">
+                            <span className="text-ly-12 ml-2.5 bg-skeletonbg w-90 h-3.5"></span>
+                        </div>
+                    </div>  
+                </div>
+                         
+            
+                <div className="w-full box-border px-4 mt-6">
+                    <div className="flex items-center">
+                        <span className="text-ly-12 flex-none mr-1 bg-skeletonbg">
+                            Order Summary(2)
+                        </span>
+                        <button className="flex-none w-4 h-4 bg-skeletonbg" type="button"></button>             
+                    </div>
+                    <div className="relative w-full box-border pr-9 mt-3.5">
+                        <div className="w-full box-border flex overflow-x-auto">
+                            {arr.map((i) => { 
+                               
+                                return(
+                                    <div key={i} className="relative flex-none w-16 h-21.5 mr-3 last:mr-0 bg-skeletonbg">
+                                        <Image className="object-cover" fill src={NOT_IMAGE} alt="placeholder image"/>
+                                    </div>
+                                )
+                            })}
+    
+                        </div>
+                        <button className="absolute top-1/2 right-1 w-4 h-4 -translate-y-1/2 bg-skeletonbg"></button>
+                    </div>
+                </div>
+            
+                <div className="box-border px-4 w-full mt-6">
+                    <h3 className="text-ly-24 font-medium bg-skeletonbg w-30 h-6"></h3>
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                    </div>
+     
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                    </div>
+                    
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                    </div>
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                    </div>
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                        <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-15 h-5"></p>
+                    </div>
+                    
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-16 leading-ly-24 bg-skeletonbg w-15 h-6"></p>
+                        <p className="text-ly-16 leading-ly-24 font-bold bg-skeletonbg w-15 h-6"></p>
+                    </div>
+                </div>         
+            </div>
+            
+        </div>
+    );
+}

+ 98 - 0
src/app/(checkout)/checkout/loading.tsx

@@ -0,0 +1,98 @@
+import Image from "next/image";
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2];
+    return (
+        <div className="w-full h-full animate-pulse">
+            <header className="sticky top-0 z-10 w-full">
+                <div className="relative w-full h-15 flex items-center justify-center bg-neutral-50 text-ly-16">
+                    <div className="absolute left-4 w-6 h-6 bg-skeletonbg"></div>
+                    <p className="flex-none h-6 w-25 bg-skeletonbg"></p>
+                </div>
+            </header>
+            <div className="w-full px-0">
+                <div className="box-border w-full h-15 flex items-center px-3.75 relative">
+                    <div className="w-4 h-4 mr-1 bg-skeletonbg"></div>
+                
+                    <span className="text-ly-12 bg-skeletonbg w-70 h-3.5"></span>
+                    <div className="absolute top-1/2 right-3.75 -translate-y-1/2 w-4 h-4 bg-skeletonbg"></div>
+                </div>
+            
+            </div>
+
+            <div className="relative box-border w-full mt-6 px-4">
+                <div className="flex justify-between items-center">
+                    <button className="flex items-center text-ly-12">
+                        <span className="bg-skeletonbg w-30 h-3.5"> </span>
+                        <div className="w-4 h-4 ml-2 bg-skeletonbg"></div>
+                    </button>
+                    <span className="text-ly-14 font-bold bg-skeletonbg w-20 h-4"></span>
+                </div>
+    
+                <div className="relative mt-3 w-full">
+                    <div className="flex w-full gap-2 overflow-auto pr-6">
+                        {arr.map((i) => {
+                            
+                            return (
+                                <div className="relative w-22.5 h-30 flex-none bg-skeletonbg" key={i}>
+                                    <Image fill className="object-cover" src={NOT_IMAGE} alt="placeholder image" />
+                                </div>
+                            )
+                        })}
+                    </div>
+
+                </div>
+                
+            </div>
+
+            <div className="mt-6 box-border px-4">
+                <h3 className="text-ly-24 font-medium bg-skeletonbg">Shipping Method</h3>
+            
+                <div className="w-full">
+                    <label className="group block relative box-border mt-3 p-3 border-1 border-skeletonbg rounded-sm ">
+                        <p className="text-ly-13 bg-skeletonbg">
+                            <span>USPS/FedEx/DHL/UPS</span>
+                        </p>
+                        <p className="text-ly-12 bg-skeletonbg mt-1">(2-5 business days)</p>
+
+                        <div className="absolute top-1/2 -translate-y-1/2 right-3 flex items-center">
+                            <span className="text-ly-14 font-medium mr-4 bg-skeletonbg">$0.00</span>
+                            <div className="w-4 h-4 bg-skeletonbg"></div>
+                        </div>
+                    </label>
+                </div>
+            </div>
+
+            <div className="mt-3 box-border px-4">
+                <div className="relative box-border w-full bg-skeletonbg p-3">
+                    <div className="flex justify-between items-center">
+                        <span className="text-ly-13 w-30 h-3.5"></span>
+                        <span className="text-ly-12 w-10 h-3.5"></span>
+                    </div>
+                    <div className="mt-2 w-57 text-ly-12 leading-3.5 h-3.5"></div>
+                </div>
+            </div>
+
+
+            <div className="mt-6 box-border px-4">
+                <div className="relative box-border w-full flex justify-between items-center">
+                    <span className="text-ly-24 font-medium bg-skeletonbg w-15 h-6"></span>
+                    <div className="flex items-center">
+                    
+                        <span className="flex items-center text-ly-14 px-2 flex-none h-6 w-10 bg-skeletonbg mr-2"></span>
+                        <button className="w-6 h-6 flex-none bg-skeletonbg" type="button"></button>
+                    </div>
+                </div>
+                
+                <div className="w-full mt-3">
+                    <div className="box-border w-full h-40 bg-skeletonbg p-3 rounded-md"></div>
+                    
+                    <div className="flex justify-between items-center mt-3 bg-skeletonbg border-skeletonbg box-border w-full border-1 h-12 rounded-sm pl-3 pr-2"></div>
+                </div>
+            </div>
+
+
+            
+        </div>
+    );
+}

+ 11 - 0
src/app/(public)/(cms)/loading.tsx

@@ -0,0 +1,11 @@
+import {LoadingSpinner} from "@/components/common/LoadingSpinner";
+export default function Loading() {
+
+    return (
+        <div className="fixed top-0 left-0 w-full h-full box-border">
+            <div className="w-full h-full flex justify-center items-center bg-skeletonbg/60">
+                <LoadingSpinner size={40} />
+            </div>
+        </div>
+    );
+}

src/app/(public)/track_order/_components/TrackFaqs.tsx → src/app/(public)/(cms)/track_order/_components/TrackFaqs.tsx


src/app/(public)/track_order/_components/TrackOrder.tsx → src/app/(public)/(cms)/track_order/_components/TrackOrder.tsx


src/app/(public)/track_order/page.tsx → src/app/(public)/(cms)/track_order/page.tsx


+ 45 - 0
src/app/(public)/category/[slug]/[id]/loading.tsx

@@ -0,0 +1,45 @@
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2,3,4,5,6];
+    return (
+        <div className="w-full h-full box-border px-4 animate-pulse">
+     
+            <div className="w-full mt-3 bg-skeletonbg">
+                <img className="block w-full h-42.75 object-cover" src={NOT_IMAGE} />       
+            </div>
+            <div>
+                <div className="bg-skeletonbg w-20 h-6 mt-8"></div>
+                <p className="bg-skeletonbg h-3.5 mt-4"></p>
+                <p className="bg-skeletonbg w-1/2 h-3.5 mt-1"></p>
+                <div className="flex justify-end mt-2">
+                    <span className="w-25 h-4.5 bg-skeletonbg"></span>
+                </div>
+            </div>
+
+
+            <div className="flex justify-between items-center mt-6">
+                <div className="w-15 h-4 bg-skeletonbg"></div>
+                <div className="w-18 h-7 bg-skeletonbg"></div>
+            </div>
+
+            <div className="flex flex-wrap justify-between items-center">
+                {arr.map((i) => {
+                    return (
+                        <div className="flex-none w-42.5 mt-4" key={i}>
+                            <img className="block w-42.5 h-57 object-contain bg-skeletonbg" src={NOT_IMAGE} />
+                            <p className="mt-2 h-5 bg-skeletonbg"></p>
+                            <p className="w-26 h-5 bg-skeletonbg mt-2"></p>
+                            <p className="mt-2 flex items-center justify-between">
+                                <span className="w-20 h-5 bg-skeletonbg"></span>
+                                <span className="h-8 w-8 bg-skeletonbg"></span>
+                            </p>
+                        </div>
+                    );
+
+                })}
+                
+            </div>
+
+        </div>
+    );
+}

+ 2 - 4
src/app/(public)/category/[slug]/[id]/page.tsx

@@ -22,8 +22,6 @@ import { newSortByFields } from "@utils/constants";
 // import { CategoryDetail } from "@components/theme/search/CategoryDetail";
 import CategoryDesc from "./_components/CategoryDesc";
 import FaqList, { type FaqItem } from "./_components/FaqList";
-import { Suspense } from "react";
-import FilterListSkeleton from "@components/common/skeleton/FilterSkeleton";
 // import { TreeCategoriesResponse } from "@/types/theme/category-tree";
 // import { MobileSearchBar } from "@components/layout/navbar/MobileSearch";
 import {
@@ -297,7 +295,7 @@ export default async function CategoryPage({
     <>
       {/* <MobileSearchBar /> */}
       <section>
-        <Suspense fallback={<FilterListSkeleton />}>
+    
           {/* <CategoryDetail
             categoryItem={{
               description: translation?.description ?? "",
@@ -318,7 +316,7 @@ export default async function CategoryPage({
               categoryProductDatas? categoryProductDatas.categoryProducts.description: ''
             } //translation?.description ?? ""}
           />
-        </Suspense>
+   
         {/* <div className="my-10 hidden gap-4 md:flex md:items-baseline md:justify-between w-full max-w-screen-2xl mx-auto px-4">
           <FilterList filterAttributes={filterAttributes} />
           <SortOrder sortOrders={SortByFields} title="Sort by" />

+ 11 - 0
src/app/(public)/customer/loading.tsx

@@ -0,0 +1,11 @@
+import {LoadingSpinner} from "@/components/common/LoadingSpinner";
+export default function Loading() {
+
+    return (
+        <div className="fixed top-0 left-0 w-full h-full box-border">
+            <div className="w-full h-full flex justify-center items-center bg-skeletonbg/60">
+                <LoadingSpinner size={40} />
+            </div>
+        </div>
+    );
+}

+ 56 - 0
src/app/(public)/loading.tsx

@@ -0,0 +1,56 @@
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2,3,4,5,6];
+    return (
+        <div className="w-full h-full box-border animate-pulse">
+     
+            <div className="w-full bg-skeletonbg">
+                <img className="block w-full h-130 object-cover" src={NOT_IMAGE} />       
+            </div>
+
+            <div className="flex justify-between box-border px-4 py-1.5">
+                <span className="w-20 h-5 bg-skeletonbg"></span>
+                <span className="w-20 h-5 bg-skeletonbg"></span>
+                <span className="w-20 h-5 bg-skeletonbg"></span>
+            </div>
+
+            <div className="box-border px-4 mt-1 flex flex-wrap justify-between">
+                {arr.map((i) => {
+                    return (
+                        <div className="w-27 h-36 mt-3 bg-skeletonbg" key={'one'+String(i)}>
+                            <img className="block w-full h-full object-cover" src={NOT_IMAGE} />
+                        </div>
+                    )
+                })}
+                
+            </div>
+
+            
+            <div className="box-border px-4 mt-6">
+                <div className="h-6 w-40 bg-skeletonbg"></div>
+                <div className="flex justify-between flex-wrap">
+                    {arr.map((i) => {
+                        if(i > 4) return <></>;
+                        return (
+                            <div className="flex-none w-42.75 mt-4" key={'two'+String(i)}>
+                                <img className="block w-42.75 h-57 bg-skeletonbg object-cover" src={NOT_IMAGE} />
+                                <p className="h-5 mt-2 bg-skeletonbg"></p>
+                                <p className="w-3/5 h-4 mt-2 bg-skeletonbg"></p>
+                                <div className="flex justify-between items-center mt-2">
+                                    <span className="w-25 h-5 bg-skeletonbg"></span>
+                                    <span className="w-8 h-8 bg-skeletonbg"></span>
+                                </div>
+                            </div>
+                        )
+
+                    })}
+                    
+                </div>
+            </div>
+
+        
+            
+
+        </div>
+    );
+}

+ 6 - 14
src/app/(public)/paymentresult/_components/SkeletonCancelOrFailure.tsx

@@ -5,26 +5,18 @@ export default function SkeletonCancelOrFailure() {
 
             <div className="w-full">
                 <div className="box-border px-4 w-full">
-                    <div className="w-12 h-12 mx-auto mt-9 bg-gray-300"></div>
+                    <div className="w-12 h-12 mx-auto mt-9 bg-skeletonbg"></div>
                     <p className="text-ly-16 text-center mt-6">
-                        <span className="text-gray-300 bg-gray-300">Your Order Has Been Received</span>
+                        <span className="inline-block bg-skeletonbg h-4 w-70"></span>
                     </p>
                     <p className="text-ly-16 mt-4 flex justify-center">
-                        <span className="px-3.75 leading-ly-28 text-gray-300 bg-gray-300">Order #600000000</span>
+                        <span className="px-3.75 h-7 w-30 bg-skeletonbg"></span>
                     </p>
               
-                    <div className="mt-6 flex justify-center items-center h-12 border-1 rounded-3xl text-ly-14">
-                        <span className="text-gray-300 bg-gray-300">Continue Shopping</span>
-                    </div>
+                    <div className="mt-6 flex justify-center items-center h-12 rounded-3xl bg-skeletonbg"></div>
                 </div>
-                <div className="box-border px-4 w-full mt-6">
-                    <div className="relative w-full bg-ly-lightgray box-border p-3">
-                        <button className="absolute top-3 right-3 w-6 h-6 bg-gray-300"></button>
-                        <p className="text-ly-13"><span className="text-gray-300 bg-gray-300">Faqs</span></p>
-                        <p className="text-ly-12 text-[#a6a6a6] mt-2">
-                            <span className="text-gray-300 bg-gray-300">Pls contact customer service if need any help</span>
-                        </p>
-                    </div>
+                <div className="box-border px-4 w-full mt-6 ">
+                    <div className="w-full h-17.5 bg-skeletonbg"></div>
                 </div>
 
 

+ 90 - 106
src/app/(public)/paymentresult/_components/SuccessPageSkeleton.tsx

@@ -1,124 +1,108 @@
-
-export default function SuccessPageSkeleton() { 
+import Image from "next/image";
+import {NOT_IMAGE} from "@/utils/constants";
+export default function SuccessPageSkeleton() {
     return (
-        <div className="w-full animate-pulse px-0">
+        <div className="w-full h-full animate-pulse">
+
+
+            
+            <div className="box-border px-4 w-full">
+                <div className="w-12 h-12 mx-auto mt-9 bg-skeletonbg"></div>
+                <p className="text-ly-16 text-center mt-6">
+                    <span className="bg-skeletonbg w-60 h-4 inline-block"></span>
+                </p>
+                <p className="text-ly-16 mt-4 flex justify-center">
+                    <span className="px-3.75 leading-ly-28 bg-skeletonbg w-40 h-7"></span>
+                </p>
+                <p className="text-ly-12 text-center mt-4 leading-ly-22">
+                    <span className="bg-skeletonbg w-25 h-3.5 inline-block"></span>
+                </p>
+                <p className="text-ly-12 text-center leading-ly-22">
+                    <span className="bg-skeletonbg w-40 h-3.5 inline-block"></span>
+                </p>
+                <p className="text-ly-12 text-center leading-ly-22">
+                    <span className="bg-skeletonbg w-50 h-3.5 inline-block"></span>
+                </p>
+                <p className="text-ly-12 text-center leading-ly-22">
+                    <span className="bg-skeletonbg w-60 h-3.5 inline-block"></span>
+                </p>
+                <div className="mt-6 flex justify-center items-center h-12 rounded-3xl text-ly-14 bg-skeletonbg"></div>
+            </div>
+            <div className="box-border px-4 w-full mt-6 ">
+                <div className="w-full h-17.5 bg-skeletonbg"></div>
+            </div>
+
 
-            <div className="w-full">
-                <div className="box-border px-4 w-full">
-                    <div className="w-12 h-12 mx-auto mt-9 bg-gray-300"></div>
-                    <p className="text-ly-16 text-center mt-6">
-                        <span className="text-gray-300 bg-gray-300">Your Order Has Been Received</span>
-                    </p>
-                    <p className="text-ly-16 mt-4 flex justify-center">
-                        <span className="px-3.75 leading-ly-28 text-gray-300 bg-gray-300">Order #600000000</span>
-                    </p>
-                    <p className="text-ly-12 text-center mt-4 leading-ly-22">
-                        <span className="text-gray-300 bg-gray-300">Hello, lala</span>
-                    </p>
-                    <p className="text-ly-12 text-center leading-ly-22">
-                        <span className="text-gray-300 bg-gray-300">Thank you so much for your order!</span>
-                    </p>
-                    <p className="text-ly-12 text-center leading-ly-22">
-                        <span className="text-gray-300 bg-gray-300">We’ll get started on your order very soon!</span>
-                    </p>
-                    <p className="text-ly-12 text-center leading-ly-22">
-                        <span className="text-gray-300 bg-gray-300">You’ll receive an order confirmation email with details of your order in an hour, please be sure to check your email and confirm your order, that is very important for us to process your order.</span>
-                    </p>
-                    <div className="mt-6 flex justify-center items-center h-12 border-1 rounded-3xl text-ly-14">
-                        <span className="text-gray-300 bg-gray-300">Continue Shopping</span>
+            <div className="box-border px-4 w-full mt-6">
+                <h4 className="text-ly-24 font-medium bg-skeletonbg w-70 h-6"></h4>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-full h-3.5 bg-skeletonbg"></p>
+                        <p className="w-full h-3.5 bg-skeletonbg mt-0.5"></p>
+                        <p className="w-20 h-3.5 bg-skeletonbg mt-0.5"></p>
                     </div>
                 </div>
-                <div className="box-border px-4 w-full mt-6">
-                    <div className="relative w-full bg-ly-lightgray box-border p-3">
-                        <button className="absolute top-3 right-3 w-6 h-6 bg-gray-300"></button>
-                        <p className="text-ly-13"><span className="text-gray-300 bg-gray-300">Faqs</span></p>
-                        <p className="text-ly-12 text-[#a6a6a6] mt-2">
-                            <span className="text-gray-300 bg-gray-300">Pls contact customer service if need any help</span>
-                        </p>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-20 h-3.5 bg-skeletonbg"></p>
                     </div>
                 </div>
-                <div className="box-border px-4 w-full mt-6">
-                    <h4 className="text-ly-24 font-medium">
-                        <span className="text-gray-300 bg-gray-300">Order Information</span>
-                    </h4>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Ship to:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            Alessandro  6263378809
-                        </div>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-20 h-3.5 bg-skeletonbg"></p>
                     </div>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Order number:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            600465290
-                        </div>
-                    </div>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Status:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            Processing
-                        </div>
-                    </div>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Order date:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            September 24,2020
-                        </div>
+                </div>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-20 h-3.5 bg-skeletonbg"></p>
                     </div>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Shipping method:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            Same day delivery
-                        </div>
+                </div>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-20 h-3.5 bg-skeletonbg"></p>
                     </div>
-                    <div className="mt-6 flex justify-between">
-                        <div className="text-ly-12 flex-none text-gray-300 bg-gray-300">Payment method:</div>
-                        <div className="w-40.5 text-ly-12 leading-ly-20 flex-none text-gray-300 bg-gray-300">
-                            Paypal-express
-                        </div>
+                </div>
+                <div className="mt-6 flex justify-between">
+                    <div className="text-ly-12 flex-none w-20 h-3.5 bg-skeletonbg"></div>
+                    <div className="w-40.5 text-ly-12 leading-ly-20 flex-none">
+                        <p className="w-20 h-3.5 bg-skeletonbg"></p>
                     </div>
-
                 </div>
 
-                {/* <div className="box-border px-4 w-full mt-6">
-                    <div className="w-full flex gap-2 pb-4 border-b-1 border-[#f0f0f0] last:border-0 last:pb-0">
-                        <div className="relative w-33 h-44 flex-none">
-                            <Image fill src="https://cdn.alipearlhair.com/media/catalog/product/2/_/2_104_20.jpg" alt="logo" />
-                        </div>
-                        <div className="flex-none w-50.75 flex flex-col justify-between">
-                            <div>
-                                <p className="text-ly-12 leading-ly-20 line-clamp-2">
-                                    Deep Wave Wig 100% Human Hair Deep Wave Wig 100% Human Hair  100% Human Hair
-                                </p>
-                                <p className="mt-2 text-ly-12 leading-ly-20 text-ly-placeholder">14/4*4 HD Lace/150%</p>
-                            </div>
-                            <div className="flex justify-between">
-                                <p className="text-ly-14 leading-ly-20 font-bold">$10.00</p>
-                                <p className="text-ly-12 leading-ly-20">x 1</p>
-                            </div>
-                        </div>
-                    </div>
-                </div> */}
+            </div>
 
-                {/* <div className="box-border px-4 w-full mt-6 pt-6 border-t-1 border-black">
-                    <div className="flex justify-between mt-3 first:mt-0">
-                        <p className="text-ly-12 leading-ly-20">Subtotal</p>
-                        <p className="text-ly-12 leading-ly-20">0.00</p>
+            <div className="box-border px-4 w-full mt-6">
+                
+                <div className="w-full flex gap-2 pb-4 last:border-0 last:pb-0">
+                    <div className="relative w-33 h-44 flex-none bg-skeletonbg">
+                        <Image className="object-cover" fill src={NOT_IMAGE} alt="placeholder imag" />
                     </div>
-                    <div className="flex justify-between mt-3 first:mt-0">
-                        <p className="text-ly-12 leading-ly-20">Shipping Method</p>
-                        <p className="text-ly-12 leading-ly-20">0.00</p>
-                    </div>
-                    <div className="flex justify-between mt-3 first:mt-0">
-                        <p className="text-ly-12 leading-ly-20">You Earn</p>
-                        <p className="text-ly-12 leading-ly-20">600 Reward Points</p>
-                    </div>
-                    <div className="flex justify-between mt-3 first:mt-0">
-                        <p className="text-ly-16 leading-ly-24">Total</p>
-                        <p className="text-ly-16 leading-ly-24 font-bold">0.00</p>
+                    <div className="flex-none w-50.75 flex flex-col justify-between">
+                        <div>
+                            <p className="text-ly-12 leading-ly-20 line-clamp-2">
+                                <span className="bg-skeletonbg w-full h-3.5 inline-block"></span>
+                                <span className="bg-skeletonbg w-1/2 h-3.5 inline-block"></span>
+                            </p>
+                            <p className="mt-2 text-ly-12 leading-ly-20">
+                                <span className="bg-skeletonbg w-3/4 h-3.5 inline-block"></span>
+                            </p>
+                        </div>
+
+                        <div className="flex justify-between">
+                            <p className="text-ly-14 leading-ly-20 font-bold bg-skeletonbg w-20 h-5"></p>
+                            <p className="text-ly-12 leading-ly-20 bg-skeletonbg w-10 h-5"></p>
+                        </div>
                     </div>
-                </div> */}
+                </div>
+                
+                
             </div>
+
         </div>
     );
-}
+}

+ 6 - 0
src/app/(public)/paymentresult/result/loading.tsx

@@ -0,0 +1,6 @@
+import SuccessPageSkeleton from '../_components/SuccessPageSkeleton';
+export default function Loading() {
+    return (<>
+        <SuccessPageSkeleton />
+    </>);
+}

+ 53 - 0
src/app/(public)/product/[...urlProduct]/loading.tsx

@@ -0,0 +1,53 @@
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2,3];
+    return (
+        <div className="w-full h-full box-border animate-pulse">
+     
+            <div className="w-full bg-skeletonbg">
+                <img className="block w-full h-130 object-cover" src={NOT_IMAGE} />       
+            </div>
+            <div className="flex flex-wrap pl-4 mt-1">
+                {arr.map((i) => {
+                    return (
+                        <div className="flex-none w-15 h-20 mr-2" key={i}>
+                            <img className="block w-15 h-20 object-contain bg-skeletonbg" src={NOT_IMAGE} />
+                        </div>
+                    );
+
+                })}
+                
+            </div>
+
+            <div className="box-border px-4 mt-4">
+  
+                <p className="bg-skeletonbg h-5"></p>
+                <p className="bg-skeletonbg w-3/4 h-5 mt-1"></p>
+
+            </div>
+            
+            <div className="box-border px-4 mt-2">
+                <div className="h-10 bg-skeletonbg mt-2"></div>
+            </div>
+
+            <div className="box-border px-4 flex justify-between items-center mt-2">
+                <div className="w-40 h-7 bg-skeletonbg"></div>
+                <div className="w-60 h-5 bg-skeletonbg"></div>
+            </div>
+
+            <div className="box-border w-full px-4 mt-3">
+                <div className="h-5 bg-skeletonbg w-3/4"></div>
+            </div>
+
+            <div className="box-border w-full px-4 mt-3">
+                <div className="h-10 bg-skeletonbg"></div>
+            </div>
+
+            <div className="box-border w-full px-4 mt-3">
+                <div className="h-35 bg-skeletonbg"></div>
+            </div>
+            
+
+        </div>
+    );
+}

+ 1 - 6
src/app/(public)/product/[...urlProduct]/page.tsx

@@ -1,7 +1,6 @@
 import { notFound } from "next/navigation";
 import { Suspense } from "react";
 import {
-  ProductDetailSkeleton,
   RelatedProductSkeleton,
 } from "@/components/common/skeleton/ProductSkeleton";
 import { BASE_SCHEMA_URL, PRODUCT_TYPE } from "@/utils/constants";
@@ -13,7 +12,6 @@ import type {
   ProductMediaType,
 } from "@components/catalog/type";
 import { RelatedProductsSection } from "@components/catalog/product/RelatedProductsSection";
-import { HeroCarouselShimmer } from "@components/common/slider";
 import { ProductMedia } from "@/app/(public)/product/_components/ProductMedia";
 import { ProductInformation } from "@/app/(public)/product/_components/ProductInformation";
 import { ProductDetail } from "@/app/(public)/product/_components/ProductDetail";
@@ -88,13 +86,11 @@ export default async function ProductPage({
         type="application/ld+json"
       />
       <div className="w-full">
-        <Suspense fallback={<HeroCarouselShimmer />}>
           <ProductMedia mediaData={mediaImgs} />
-        </Suspense>
       </div>
 
       <div className="">
-        <Suspense fallback={<ProductDetailSkeleton />}>
+
           <ProductInformation
             key={product._id}
             productId={product._id}
@@ -115,7 +111,6 @@ export default async function ProductPage({
           />
           <ProductDetail detail={product.description || ""} />
           
-        </Suspense>
         <Recommend/>
       </div>
         

+ 3 - 3
src/app/(public)/product/_components/ProductMedia.tsx

@@ -64,7 +64,7 @@ export function ProductMedia({
         ))}
         {/* 自定义分页数字 */}
         <div slot="container-end">
-          <div className="product-media-swiper-pagination z-1 absolute top-3 right-4 pt-1.5 pb-1.5 pl-3 pr-3 rounded-3xl text-ly-14 text-white bg-ly-deepgreen/50"></div>
+          <div className="product-media-swiper-pagination z-1 absolute top-3 right-4 flex items-center h-7 px-2.5 rounded-3xl text-ly-14 text-white bg-ly-deepgreen/50"></div>
         </div>
       </Swiper>
       <div className=" pl-4">
@@ -91,8 +91,8 @@ export function ProductMedia({
               >
                 <Image
                   src={getImageUrl(img.publicPath)}
-                  width={100}
-                  height={130}
+                  width={60}
+                  height={80}
                   loading="eager"
                   alt={`Thumbnail ${idx + 1}`}
                   className="w-full h-full object-cover"

+ 48 - 0
src/app/(public)/search/loading.tsx

@@ -0,0 +1,48 @@
+import {NOT_IMAGE} from "@/utils/constants";
+export default function Loading() {
+    const arr = [1,2,3,4,5,6];
+    return (
+        <div className="w-full h-full box-border px-4 animate-pulse">
+     
+            <div className="w-full h-10 mt-3 bg-skeletonbg"></div>
+
+                <div className="w-full mx-auto px-4 py-6">
+                <div className="text-base font-medium mb-4 w-25 h-4"></div>
+                <div className="flex flex-wrap items-center justify-start gap-3">
+                
+                    <div className="bg-skeletonbg rounded-sm w-30 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-20 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-25 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-18 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-32 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-20 h-8"></div>
+                    <div className="bg-skeletonbg rounded-sm w-20 h-8"></div>
+                </div>
+            </div>
+
+            <div className="flex justify-between items-center mt-6">
+                <div className="w-15 h-4 bg-skeletonbg"></div>
+                <div className="w-18 h-7 bg-skeletonbg"></div>
+            </div>
+
+            <div className="flex flex-wrap justify-between items-center">
+                {arr.map((i) => {
+                    return (
+                        <div className="flex-none w-42.5 mt-4" key={i}>
+                            <img className="block w-42.5 h-57 object-contain bg-skeletonbg" src={NOT_IMAGE} />
+                            <p className="mt-2 h-5 bg-skeletonbg"></p>
+                            <p className="w-26 h-5 bg-skeletonbg mt-2"></p>
+                            <p className="mt-2 flex items-center justify-between">
+                                <span className="w-20 h-5 bg-skeletonbg"></span>
+                                <span className="h-8 w-8 bg-skeletonbg"></span>
+                            </p>
+                        </div>
+                    );
+
+                })}
+                
+            </div>
+
+        </div>
+    );
+}

+ 10 - 0
src/app/globals.css

@@ -145,6 +145,8 @@
   --color-selected-bg-bottom-dark: var(--selected-bg-bottom-dark);
 
   --color-input-color: var(--input-color); /*placeholder:text-input-color 设置placeholder颜色*/
+
+  --color-skeletonbg: var(--skeleton-loading-background-color);
 }
 
 
@@ -180,6 +182,8 @@
     --selected-bg-bottom-dark: #314779;
 
     --input-color: #b3b3b3;
+
+    --skeleton-loading-background-color: #f7f7f7;
   }
 
 
@@ -294,6 +298,12 @@
       top: unset;
   }
 
+  .product-media-swiper .product-media-swiper-pagination{
+      width: auto;
+      left: auto;
+      bottom:auto;
+  }
+
   .fade-in{
     animation: fade-in 0.3s ease-in-out forwards;
   }

+ 6 - 2
src/components/common/LoadingSpinner.tsx

@@ -2,7 +2,7 @@ import { type FC } from "react";
 
 interface LoadingSpinnerProps {
   colorClassName?: string;
-  size?: 16 | 24 | 32 | 48;
+  size?: 16 | 20 | 24 | 28 | 32 | 36 | 40 | 48;
   className?: string;
 }
 
@@ -13,8 +13,12 @@ export const LoadingSpinner: FC<LoadingSpinnerProps> = ({
 }) => {
   const sizeClasses = {
     16: "h-4 w-4",
+    20: "h-5 w-5",
     24: "h-6 w-6",
-    32: "h-8 w-8", 
+    28: "h-7 w-7",
+    32: "h-8 w-8",
+    36: "w-9 h-9", 
+    40: "w-10 h-10",
     48: "h-12 w-12"
   };
 

+ 0 - 26
src/components/common/skeleton/AddressSkeleton.tsx

@@ -1,26 +0,0 @@
-export default function AddressSkeleton() {
-  return (
-    <div className="mt-5 grid grid-cols-1 gap-4 md:grid-cols-2">
-      {[...Array(4)].map((_, i) => (
-        <div
-          key={i}
-          className="animate-pulse space-y-3 rounded-2xl border border-neutral-300 bg-neutral-200 p-4 dark:border-neutral-800 dark:bg-neutral-900"
-        >
-          <div className="flex items-center justify-between">
-            <div className="h-6 w-6 rounded-full bg-neutral-300 dark:bg-neutral-800" />
-            <div className="flex items-center space-x-2">
-              <div className="h-4 w-4 rounded-full bg-neutral-300 dark:bg-neutral-800" />
-              <div className="h-4 w-4 rounded bg-neutral-300 dark:bg-neutral-800" />
-            </div>
-          </div>
-
-          <div className="h-4 w-2/3 rounded bg-neutral-300 dark:bg-neutral-800" />
-
-          <div className="h-3 w-full rounded bg-neutral-300 dark:bg-neutral-800" />
-          <div className="h-3 w-5/6 rounded bg-neutral-300 dark:bg-neutral-800" />
-          <div className="h-3 w-1/2 rounded bg-neutral-300 dark:bg-neutral-800" />
-        </div>
-      ))}
-    </div>
-  );
-}

+ 0 - 31
src/components/common/skeleton/AuthPlaceHolder.tsx

@@ -1,31 +0,0 @@
-export const AuthPlaceHolder = () => (
-  <div className="mx-auto animate-pulse pt-4 md:pt-8 lg:pt-12">
-    <div className="grid grid-cols-1 gap-12 md:grid-cols-2">
-      <div className="flex px-4">
-        <div className="w-full animate-pulse">
-          <div className="h-12 w-1/3 rounded bg-gray-200"></div>
-          <div className="mt-2 h-4 w-3/4 rounded bg-gray-200"></div>
-
-          <div className="mt-12 space-y-4">
-            <div className="grid grid-cols-2 gap-4">
-              <div className="h-12 rounded-lg bg-gray-200"></div>
-              <div className="h-12 rounded-lg bg-gray-200"></div>
-            </div>
-
-            <div className="h-12 w-full rounded-lg bg-gray-200"></div>
-
-            <div className="h-12 w-full rounded-lg bg-gray-200"></div>
-
-            <div className="h-12 w-full rounded-lg bg-gray-200"></div>
-
-            <div className="mt-12 h-12 w-full rounded-lg bg-gray-300"></div>
-          </div>
-
-          <div className="mt-4 h-6 w-1/2 rounded bg-gray-200"></div>
-        </div>
-      </div>
-
-      <div className="hidden h-80 w-full rounded-xl bg-gray-200 dark:bg-gray-700 sm:h-[400px] md:hidden md:h-[600px] lg:inline" />
-    </div>
-  </div>
-);

+ 0 - 61
src/components/common/skeleton/CheckoutSkeleton.tsx

@@ -1,61 +0,0 @@
-export default function CheckoutSkeleton() {
-  return (
-    <div className="mx-auto w-full flex-1 animate-pulse space-y-6 rounded-md px-0 py-10 text-white">
-      {/* Logo */}
-      <div className="flex items-center gap-x-2">
-        <div className="h-10 w-12 rounded-sm bg-gray-300 text-center text-sm text-black dark:bg-gray-600 dark:text-white" />
-        <div className="h-6 w-24 rounded-sm bg-gray-300 text-center text-sm text-black dark:bg-gray-600 dark:text-white" />
-      </div>
-
-      <div className="flex items-center gap-3">
-        <div className="h-6 w-6 rounded-full bg-gray-300 text-center text-sm text-black dark:bg-gray-600 dark:text-white">
-          1
-        </div>
-        <div className="h-4 w-20 rounded bg-gray-200 dark:bg-gray-700" />
-      </div>
-
-      <div className="h-12 w-full rounded bg-gray-200 dark:bg-gray-800" />
-
-      <div className="h-4 w-40 rounded bg-gray-200 dark:bg-gray-700" />
-
-      <div className="flex justify-end">
-        <div className="h-12 w-24 rounded-full bg-gray-300 dark:bg-gray-700" />
-      </div>
-
-      {[2, 3, 4, 5].map((step) => (
-        <div key={step} className="flex items-center gap-3">
-          <div className="h-6 w-6 rounded-full bg-gray-300 text-center text-sm text-black dark:bg-gray-700 dark:text-white">
-            {step}
-          </div>
-          <div className="h-4 w-24 rounded bg-gray-200 dark:bg-gray-700" />
-        </div>
-      ))}
-    </div>
-  );
-}
-
-export const CartCheckoutPageSkeleton = () => {
-  return (
-    <section className="w-full animate-pulse py-6 text-black dark:text-white">
-      <div className="flex w-full flex-col">
-        {[1, 2].map((_, index) => (
-          <div
-            key={index}
-            className="mb-4 flex w-full gap-4 rounded-lg bg-white px-4 py-4 dark:bg-neutral-900"
-          >
-            <div className="h-6 w-6 flex-shrink-0 rounded-full bg-gray-200 dark:bg-gray-700" />
-
-            <div className="flex flex-1 flex-col justify-between space-y-2">
-              <div className="flex items-start justify-between">
-                <div className="h-6 w-3/5 rounded bg-gray-200 dark:bg-gray-700" />
-                <div className="h-6 w-16 rounded bg-gray-200 dark:bg-gray-700" />
-              </div>
-
-              <div className="h-3 w-1/2 rounded bg-gray-200 dark:bg-gray-700" />
-            </div>
-          </div>
-        ))}
-      </div>
-    </section>
-  );
-};

+ 0 - 50
src/components/common/skeleton/FilterSkeleton.tsx

@@ -1,50 +0,0 @@
-import { type FC } from "react";
-
-export default function FilterListSkeleton() {
-  return (
-    <div className="flex w-full flex-auto items-center gap-x-4 sm:max-w-md">
-      {Array.from({ length: 3 }).map((_, idx) => (
-        <div key={idx} className="w-full md:min-w-48">
-          <div className="animate-pulse space-y-2">
-            <div className="h-4 w-1/2 rounded bg-gray-300 dark:bg-gray-700" />
-            <div className="h-10 w-full rounded bg-gray-200 dark:bg-gray-800" />
-            <div className="mt-2 flex flex-wrap gap-2">
-              {Array.from({ length: 2 }).map((__, chipIdx) => (
-                <div
-                  key={chipIdx}
-                  className="h-6 w-16 rounded-full bg-gray-300 dark:bg-gray-700"
-                />
-              ))}
-            </div>
-          </div>
-        </div>
-      ))}
-    </div>
-  );
-}
-
-export const SortOrderSkeleton: FC = () => {
-  return (
-    <section className="flex w-full flex-1 items-center gap-x-2.5 sm:max-w-[15.625rem]">
-      <div className="hidden h-4 w-24 animate-pulse rounded bg-gray-300 md:block dark:bg-gray-700" />
-      <div className="h-10 w-full animate-pulse rounded bg-gray-200 dark:bg-gray-800" />
-    </section>
-  );
-};
-export const ProductCardSkeleton: FC = () => {
-  return (
-    <div className="flex animate-pulse flex-col gap-y-2.5">
-      <div className="group relative overflow-hidden rounded-lg">
-        <div className="aspect-square w-full rounded-lg bg-gray-300 dark:bg-gray-700" />
-        <div className="absolute bottom-4 left-1/2 flex -translate-x-1/2 items-center gap-x-4 rounded-full bg-white/50 px-4 py-1.5 text-xs font-semibold text-black opacity-0 backdrop-blur-md duration-300 group-hover:opacity-100 dark:text-white">
-          <div className="h-6 w-6 rounded-full bg-gray-400 dark:bg-gray-600" />
-        </div>
-      </div>
-
-      <div>
-        <div className="mb-2.5 h-5 w-3/4 rounded bg-gray-300 dark:bg-gray-700" />
-        <div className="h-4 w-1/3 rounded bg-gray-300 dark:bg-gray-700" />
-      </div>
-    </div>
-  );
-};

+ 0 - 14
src/components/common/skeleton/IconSkeleton.tsx

@@ -1,14 +0,0 @@
-
-type IconSkeletonProps = {
-  className?: string;
-};
-
-export function IconSkeleton({ className }: IconSkeletonProps) {
-  return (
-    <div
-      className={`relative flex h-9 w-9 items-center justify-center rounded-md border border-solid border-neutral-200 bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-800 md:h-9 md:w-9 lg:h-11 lg:w-11 ${className ?? ""}`}
-    >
-      <div className="h-4 w-4 rounded-full bg-neutral-200 dark:bg-neutral-700 animate-pulse" />
-    </div>
-  );
-}

+ 0 - 22
src/components/common/skeleton/NavbarSkeleton.tsx

@@ -1,22 +0,0 @@
-export function NavbarSkeletonLoader() {
-  return (
-    <div className="space-y-6">
-      <div className="h-12 w-full animate-pulse rounded-md bg-gray-300" />
-      <div className="h-8 w-3/4 animate-pulse rounded-md bg-gray-300" />
-
-      <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
-        {Array.from({ length: 6 }).map((_, index) => (
-          <div
-            key={index}
-            className="space-y-4 rounded-md bg-white p-4 shadow-lg"
-          >
-            <div className="h-48 animate-pulse rounded-md bg-gray-300" />
-
-            <div className="h-6 animate-pulse rounded-md bg-gray-300" />
-            <div className="h-4 w-3/4 animate-pulse rounded-md bg-gray-300" />
-          </div>
-        ))}
-      </div>
-    </div>
-  );
-}

+ 0 - 79
src/components/common/skeleton/ProductCartSkeleton.tsx

@@ -1,79 +0,0 @@
-import clsx from "clsx";
-import CheckoutSkeleton from "./CheckoutSkeleton";
-
-export default function ProductCartSkeleton() {
-  return (
-    <div className="flex">
-      <CheckoutSkeleton />
-      <CartSkeleton className="w-1/2" />
-    </div>
-  );
-}
-
-export const CartSkeleton = ({ className }: { className: string }) => {
-  return (
-    <div
-      className={clsx(
-        "hidden h-full w-1/2 flex-col justify-between px-8 py-8 pt-4 text-black dark:text-white lg:flex lg:max-w-full",
-        className,
-      )}
-    >
-      <div>
-        <div className="my-6 animate-pulse" role="status">
-          <div className="h-12 w-1/2 rounded-md bg-gray-200 dark:bg-gray-700" />
-          <span className="sr-only">Loading...</span>
-        </div>
-
-        {Array(2)
-          .fill(0)
-          .map((_, index) => (
-            <div
-              key={index}
-              className="mb-3 flex w-full max-w-full animate-pulse gap-4 rounded-lg bg-white px-4 py-4 dark:bg-neutral-900"
-            >
-              <div className="h-[194px] w-[194px] flex-shrink-0 rounded-md bg-gray-200 dark:bg-gray-700" />
-
-              <div className="flex flex-1 flex-col justify-between space-y-2">
-                <div className="flex items-start justify-between">
-                  <div className="h-8 w-3/5 rounded bg-gray-200 dark:bg-gray-700" />
-                  <div className="h-8 w-16 rounded bg-gray-200 dark:bg-gray-700" />
-                </div>
-
-                <div className="h-3 w-1/2 rounded bg-gray-200 dark:bg-gray-700" />
-
-                <div className="h-8 w-24 rounded bg-gray-200 dark:bg-gray-700" />
-
-                <div className="space-y-1 pt-2">
-                  <div className="h-3 w-full rounded bg-gray-200 dark:bg-gray-700" />
-                  <div className="h-3 w-11/12 rounded bg-gray-200 dark:bg-gray-700" />
-                  <div className="h-3 w-3/4 rounded bg-gray-200 dark:bg-gray-700" />
-                </div>
-              </div>
-            </div>
-          ))}
-      </div>
-      <CartTotalSkeleton />
-    </div>
-  );
-};
-
-export function CartTotalSkeleton() {
-  return (
-    <div className="w-full max-w-full animate-pulse space-y-4 rounded-md bg-white py-4 text-black dark:bg-neutral-900 dark:text-white">
-      <div className="flex items-center justify-between px-4">
-        <div className="h-4 w-20 rounded bg-gray-200 dark:bg-gray-700" />
-        <div className="h-4 w-20 rounded bg-gray-200 dark:bg-gray-700" />
-      </div>
-
-      <div className="flex items-center justify-between px-4">
-        <div className="h-4 w-24 rounded bg-gray-200 dark:bg-gray-700" />
-        <div className="h-4 w-24 rounded bg-gray-200 dark:bg-gray-700" />
-      </div>
-
-      <div className="flex items-center justify-between px-4 pt-2">
-        <div className="h-6 w-32 rounded bg-gray-200 dark:bg-gray-700" />
-        <div className="h-6 w-32 rounded bg-gray-200 dark:bg-gray-700" />
-      </div>
-    </div>
-  );
-}

+ 22 - 87
src/components/common/skeleton/ProductSkeleton.tsx

@@ -1,89 +1,24 @@
-"use client";
-
-import { useScrollToTop } from "@/utils/hooks/useScrollTo";
-
-export const ProductPageSkeleton = () => {
-  useScrollToTop();
-
-  return (
-    <div className="min-h-screen py-8">
-      <div className="container mx-auto">
-        <ProductDetailSkeleton />
-        <RelatedProductSkeleton />
-      </div>
-    </div>
-  );
-};
-
-export const ProductDetailSkeleton = () => {
-  return (
-    <div className="flex flex-row gap-x-8">
-      <div className="flex min-w-[878px] items-center justify-center">
-        <div className="h-[736px] w-full animate-pulse rounded-2xl bg-neutral-100 dark:bg-neutral-900" />
-      </div>
-
-      <div className="flex w-full flex-col space-y-6">
-        <div className="h-12 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-        <div className="h-12 w-1/2 animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-        <div className="flex justify-between">
-          <div className="h-6 w-1/3 animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-
-          <div className="h-6 w-1/3 animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-        </div>
-        <hr className="text-neutral-100 dark:text-neutral-900" />
-
-        <div className="space-y-4">
-          <div className="h-6 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-4 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-6 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-4 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-4 w-2/3 animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-        </div>
-        <div className="flex gap-x-6">
-          <div className="h-10 w-24 animate-pulse rounded-full bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-10 w-24 animate-pulse rounded-full bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-10 w-24 animate-pulse rounded-full bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-10 w-24 animate-pulse rounded-full bg-neutral-100 dark:bg-neutral-900" />
-        </div>
-        <div className="flex gap-x-6">
-          <div className="h-12 w-32 animate-pulse rounded-full bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-12 w-48 animate-pulse rounded-xl bg-neutral-100 dark:bg-neutral-900" />
-        </div>
-
-        <hr className="text-neutral-100 dark:text-neutral-900" />
-
-        <div className="space-y-4">
-          <div className="h-10 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-10 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-          <div className="h-10 w-full animate-pulse rounded-md bg-neutral-100 dark:bg-neutral-900" />
-        </div>
-      </div>
-    </div>
-  );
-};
-
+import {NOT_IMAGE} from "@/utils/constants";
 export const RelatedProductSkeleton = () => {
-  return (
-    <div className="mt-20">
-      <div className="flex flex-col">
-        <div className="h-12 w-1/3 animate-pulse rounded-md bg-neutral-100 text-2xl font-semibold text-white dark:bg-neutral-900" />
-        <div className="mt-4 h-6 w-1/2 animate-pulse rounded-md bg-neutral-100 text-2xl font-semibold text-white dark:bg-neutral-900" />
-        <div className="mt-1 h-6 w-1/6 animate-pulse rounded-md bg-neutral-100 text-2xl font-semibold text-white dark:bg-neutral-900" />
-      </div>
-
-      <div className="mt-10 grid grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
-        {Array(4)
-          .fill(0)
-          .map((_, index) => {
-            return (
-              <div key={index} className="animate-pulse">
-                <div className="max-w-92.5 aspect-square w-full rounded-lg bg-neutral-100 dark:bg-neutral-900" />
-                <div className="mt-4 h-6 w-3/4 rounded-md bg-neutral-100 dark:bg-neutral-900" />
-                <div className="mt-2 h-4 w-1/2 rounded-md bg-neutral-100 dark:bg-neutral-900" />
-              </div>
-            );
-          })}
-      </div>
-    </div>
-  );
+    const arr = [1,2,3,4];
+    return (
+        <div className="w-full px-4 py-8 box-border">
+            <div className="bg-skeletonbg h-6 w-60"></div>
+            <div className="w-full flex justify-between flex-wrap mt-2">
+                {arr.map((i) => {
+                    return (
+                        <div className="flex-none w-42.5 mt-4" key={i}>
+                            <img className="block w-42.5 h-57 object-contain bg-skeletonbg" src={NOT_IMAGE} />
+                            <p className="mt-2 h-5 bg-skeletonbg"></p>
+                            <p className="w-26 h-5 bg-skeletonbg mt-2"></p>
+                            <p className="mt-2 flex items-center justify-between">
+                                <span className="w-20 h-5 bg-skeletonbg"></span>
+                                <span className="h-8 w-8 bg-skeletonbg"></span>
+                            </p>
+                        </div>
+                    );
+                })}
+            </div>
+        </div>
+    );
 };

+ 0 - 15
src/components/common/skeleton/SearchSkeleton.tsx

@@ -1,15 +0,0 @@
-import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
-
-export const SearchSkeleton = () => {
-  return (
-    <div className="max-w-[550px] relative w-full md:min-w-[386px] xl:min-w-[516px]">
-      <input
-        className="input w-full rounded-lg border border-neutral-200 bg-white py-2 pl-3 pr-10 text-sm text-black outline-none placeholder:text-neutral-500 dark:border-neutral-800 dark:bg-transparent dark:text-white dark:placeholder:text-neutral-400 md:pl-4"
-        placeholder="Search for products..."
-      />
-      <div className="absolute bottom-0 right-1 top-0 flex w-9 items-center justify-center border-l border-neutral-200 dark:border-neutral-700 md:border-0">
-        <MagnifyingGlassIcon className="size-5 stroke-neutral-500" />
-      </div>
-    </div>
-  );
-}

+ 0 - 135
src/components/common/slider/HeroCarousel.tsx

@@ -1,135 +0,0 @@
-"use client";
-
-import * as React from "react";
-import Image from "next/image";
-import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
-import { GridTileImage } from "@/components/theme/ui/grid/Tile";
-import { Shimmer } from "@/components/common/Shimmer";
-import {
-  HeroCarouselShimmer,
-  HeroCarouselThumbnailShimmer,
-} from "./HeroCarouselShimmer";
-
-export default function HeroCarousel({
-  images,
-}: {
-  images: { src: string; altText: string }[];
-}) {
-  const [current, setCurrent] = React.useState(0);
-  const [isLoading, setIsLoading] = React.useState(true);
-
-  const prevSlide = () => {
-    setIsLoading(true);
-    setCurrent((prev) => (prev === 0 ? images.length - 1 : prev - 1));
-  };
-
-  const nextSlide = () => {
-    setIsLoading(true);
-    setCurrent((prev) => (prev === images.length - 1 ? 0 : prev + 1));
-  };
-
-  if (!images || images.length === 0) {
-    return (
-      <>
-        <HeroCarouselShimmer />
-        <HeroCarouselThumbnailShimmer count={3} />
-      </>
-    );
-  }
-  const buttonClassName =
-    "flex h-full cursor-pointer items-center justify-center px-6 transition-all ease-in-out hover:scale-110 hover:text-black dark:hover:text-white";
-
-  return (
-    <>
-      <div className="group relative overflow-hidden">
-        <div
-          key={current}
-          className="group relative h-full max-h-[738px] w-full overflow-hidden rounded-2xl transition-opacity duration-600 ease-in-out"
-          style={{
-            aspectRatio: "380/316",
-          }}
-        >
-          <div className="relative h-full w-full">
-            {isLoading && (
-              <Shimmer
-                className="absolute inset-0 z-10 h-full w-full"
-                rounded="lg"
-              />
-            )}
-            <Image
-              fill
-              alt={images[current]?.altText as string}
-              className={`h-full w-full object-cover transition duration-300 ease-in-out group-hover:scale-105 ${
-                isLoading ? "opacity-0" : "opacity-100"
-              }`}
-              priority={true}
-              sizes="(max-width: 1024px) 100vw, (max-width: 1536px) 66vw, 1000px"
-              src={images[current]?.src as string}
-              onLoad={() => setIsLoading(false)}
-              onError={() => setIsLoading(false)}
-            />
-          </div>
-        </div>
-
-        {images?.length > 1 ? (
-          <div className="absolute bottom-[5%] flex w-full justify-center">
-            <div className="mx-auto flex h-11 items-center rounded-full border border-gray-500/70 bg-gray-500/70 text-white/80 backdrop-blur transition-all duration-300 dark:border-black dark:bg-neutral-900/80">
-              <button
-                aria-label="Previous image"
-                className={buttonClassName}
-                onClick={prevSlide}
-              >
-                <ArrowLeftIcon className="h-5" />
-              </button>
-              <div className="mx-1 h-6 w-px bg-white/80" />
-              <button
-                aria-label="Next image"
-                className={buttonClassName}
-                onClick={nextSlide}
-              >
-                <ArrowRightIcon className="h-5" />
-              </button>
-            </div>
-          </div>
-        ) : null}
-      </div>
-
-      {images?.length > 1 ? (
-        <ul className="fade-in my-3 flex flex-nowrap gap-2 overflow-x-auto overflow-y-hidden py-1 sm:my-7 lg:mb-0">
-          {images.map((image, index) => {
-            const isActive = index === current;
-
-            return (
-              <li
-                key={image.src}
-                className="relative aspect-square w-16 md:w-32 flex-shrink-0"
-              >
-                <button
-                  className="h-full w-full"
-                  onClick={() => {
-                    setCurrent(index);
-                  }}
-                >
-                  <GridTileImage
-                    active={isActive}
-                    alt={image.altText}
-                    fill
-                    objectFit="cover"
-                    src={image.src}
-                    sizes="(max-width: 768px) 16vw, 10vw"
-                  />
-                </button>
-              </li>
-            );
-          })}
-        </ul>
-      ) : isLoading ? (
-        <div className="my-3 sm:my-7 lg:mb-0">
-          <div className="relative aspect-square w-16 md:w-32">
-            <Shimmer className="h-full w-full" rounded="lg" />
-          </div>
-        </div>
-      ) : null}
-    </>
-  );
-}

+ 0 - 42
src/components/common/slider/HeroCarouselShimmer.tsx

@@ -1,42 +0,0 @@
-"use client";
-
-import { Shimmer } from "@/components/common/Shimmer";
-// 占位组件
-export function HeroCarouselShimmer({ratio = "3/4"} : {ratio?: string}) {
-  return (
-    <div className="group relative overflow-hidden">
-      <div
-        className="group relative h-full max-h-[738px] w-full overflow-hidden rounded-2xl"
-        style={{
-          aspectRatio: ratio,
-        }}
-      >
-        <div className="relative h-full w-full">
-          <Shimmer
-            className="absolute inset-0 z-10 h-full w-full"
-            rounded="lg"
-          />
-        </div>
-      </div>
-    </div>
-  );
-}
-
-export function HeroCarouselThumbnailShimmer({
-  count = 3,
-}: {
-  count?: number;
-}) {
-  return (
-    <ul className="fade-in my-3 flex flex-nowrap gap-2 overflow-x-auto overflow-y-hidden py-1 sm:my-7 lg:mb-0">
-      {Array.from({ length: count }).map((_, index) => (
-        <li
-          key={index}
-          className="relative aspect-square w-16 md:w-32 flex-shrink-0"
-        >
-          <Shimmer className="h-full w-full" rounded="lg" />
-        </li>
-      ))}
-    </ul>
-  );
-}

+ 0 - 2
src/components/common/slider/index.ts

@@ -1,2 +0,0 @@
-export { default as HeroCarousel } from './HeroCarousel';
-export { HeroCarouselShimmer, HeroCarouselThumbnailShimmer } from './HeroCarouselShimmer';

+ 4 - 4
src/components/layout/navbar/MobileSearch.tsx

@@ -1,7 +1,7 @@
 "use client";
-import { Suspense } from "react";
+
 import Search from "./Search";
-import { SearchSkeleton } from "@/components/common/skeleton/SearchSkeleton";
+
 
 
 
@@ -13,9 +13,9 @@ export const MobileSearchBar = ({
   return (
     <>
       <div className="block w-full justify-center md:hidden px-4 mt-3 z-10">
-        <Suspense fallback={<SearchSkeleton />}>
+ 
           <Search search={false} onClose={onClose} />
-        </Suspense>
+   
       </div>
     </>
   );

+ 0 - 17
src/components/layout/navbar/NavigationSkeleton.tsx

@@ -1,17 +0,0 @@
-export function NavigationSkeleton() {
-  return (
-    <>
-      {/* Mobile menu skeleton */}
-      <div className="h-6 w-6 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700 lg:hidden" />
-      
-      {/* Desktop navigation skeleton */}
-      <ul className="hidden gap-4 text-sm md:items-center lg:flex xl:gap-6">
-        {Array.from({ length: 4 }).map((_, i) => (
-          <li key={i}>
-            <div className="h-4 w-16 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700" />
-          </li>
-        ))}
-      </ul>
-    </>
-  );
-}

+ 2 - 4
src/components/layout/navbar/index.tsx

@@ -1,9 +1,7 @@
 import Link from "next/link";
-import { Suspense } from "react";
 import LogoIcon from "@components/common/icons/LogoIcon";
 import MobileMenuTrigger from "./MobileMenuTrigger";
 import { NavbarActions } from "./NavbarActions";
-import { NavigationSkeleton } from "./NavigationSkeleton";
 import { NavbarErrorBoundary } from "@/components/error/ErrorBoundary";
 
 import { 
@@ -59,9 +57,9 @@ export default async function Navbar() {
             {/* 1. THE STATIC SHELL (Visible Instantly) */}
             <div className="flex items-center max-w-fit gap-5 xl:gap-6">
               {/* 2. STATIC HOLE: Categories (Suspended) */}
-              <Suspense fallback={<NavigationSkeleton />}>
+        
                 <MobileMenuTrigger isGuest={isGuest} menuData={menudatas} />
-              </Suspense>
+        
               <div className="flex-1 justify-center flex">
                 {/* <Suspense fallback={<SearchSkeleton />}>
                   <Search search={false} />