Selaa lähdekoodia

个人中心部分调整

zhangzf 1 viikko sitten
vanhempi
commit
e9f56d40aa

BIN
public/image/account/accountbg.png


BIN
public/image/account/couponBg.png


BIN
public/image/navigate/completed.png


BIN
public/image/navigate/processing.png


BIN
public/image/navigate/reviews.png


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 163 - 228
src/app/(public)/customer/(has-dashboard)/account/_components/AccountHeader.tsx


+ 95 - 0
src/app/(public)/customer/(has-dashboard)/account/mycoupon/_components/CouponGiftCard.tsx

@@ -0,0 +1,95 @@
+"use client";
+
+import CouponList from "./CouponList";
+import GiftCardList from "./GiftCardList";
+
+export default function CouponGiftCard() {
+  return (
+    <div
+      className="
+    grid
+    grid-cols-2
+    gap-4.5
+    p-6
+    items-stretch
+    rounded-md bg-white shadow-[0_2px_12px_rgba(0,0,0,0.1)]
+  "
+    >
+      {/* Coupon */}
+      <section
+        className="
+      flex
+      flex-col
+      border-r
+      border-[#D9D9D9]
+      pr-4.5
+      
+    "
+      >
+        <h2
+          className="
+        mb-8
+        text-[22px]
+        font-semibold
+        text-black
+      "
+        >
+          My Coupon
+        </h2>
+
+        <CouponList />
+
+        <button
+          className="
+        mt-auto
+        h-[52px]
+        w-full
+        rounded-full
+        bg-[#036141]
+        text-[18px]
+        font-semibold
+        text-white
+      "
+        >
+          Get New Coupons
+        </button>
+      </section>
+
+      {/* Gift Card */}
+      <section
+        className="
+      flex
+      flex-col
+    "
+      >
+        <h2
+          className="
+        mb-8
+        text-[22px]
+        font-semibold
+        text-black
+      "
+        >
+          My Gift Card
+        </h2>
+
+        <GiftCardList />
+
+        <button
+          className="
+        mt-auto
+        h-[52px]
+        w-full
+        rounded-full
+        bg-[#036141]
+        text-[18px]
+        font-semibold
+        text-white
+      "
+        >
+          Get New Gift Cards
+        </button>
+      </section>
+    </div>
+  );
+}

+ 144 - 58
src/app/(public)/customer/(has-dashboard)/account/mycoupon/_components/CouponList.tsx

@@ -1,90 +1,176 @@
-// src/components/CouponList.tsx
-import React, { useState } from 'react';
-import { useInfiniteScroll } from "./UseInfiniteScroll";
+"use client";
 
-// 优惠券数据类型
+import  { useState,useEffect } from "react";
+import { useInfiniteScroll } from "./UseInfiniteScroll";
+import { clientFetch } from "@/lib/restApiClient";
 interface CouponItem {
   id: number;
-  discount: string; // 优惠金额(如 $15 OFF)
-  desc: string; // 优惠描述
-  valid: string; // 有效期
+  code: string;
+  cart_rule_id: number;
+  rule_name: string;
+  rule_description: string;
+  discount_text: string;
+  status: string;
+  expired_at: string;
+  starts_from: string;
+  ends_till: string;
+  created_at: string;
 }
 
-const CouponList: React.FC = () => {
-  // 初始化优惠券数据
+const CouponList = () => {
   const [coupons, setCoupons] = useState<CouponItem[]>([
-    { id: 1, discount: '$15 OFF', desc: 'For All Products', valid: 'Valid:6/2/2026-12/31/2026' },
-    { id: 2, discount: '$10 OFF', desc: 'For All Products', valid: 'Valid:6/2/2026-12/31/2026' },
+    {
+      id: 103,
+      code: "UFP73XEZ",
+      cart_rule_id: 1,
+      rule_name: "测试优惠券",
+      rule_description: "For All Products",
+      discount_text: "$20 OFF",
+      status: "available",
+      expired_at: "2027-03-01",
+      starts_from: "",
+      ends_till: "",
+      created_at: "",
+    },
   ]);
-  const [hasMore, setHasMore] = useState(true); // 模拟:初始有更多数据,加载2次后无更多
 
-  // 加载更多优惠券(模拟异步请求)
+  const [hasMore, setHasMore] = useState(true);
+
   const loadMoreCoupons = async () => {
-    return new Promise<void>((resolve) => {
-      setTimeout(() => {
-        if (coupons.length >= 6) { // 模拟最多加载6条
-          setHasMore(false);
-          resolve();
-          return;
-        }
-        // 模拟新增数据
-        const newCoupons = [
-          { 
-            id: coupons.length + 1, 
-            discount: `$${5 * (coupons.length + 1)} OFF`, 
-            desc: 'For All Products', 
-            valid: 'Valid:6/2/2026-12/31/2026' 
-          },
-        ];
-        setCoupons(prev => [...prev, ...newCoupons]);
-        resolve();
-      }, 800);
-    });
+    return;
   };
+  useEffect(() => {
+    const load = async () => {
+      const resp = await clientFetch("/api/customer/coupons");
+      console.log("resp------------------------:",resp);
+      if(resp.success){
+         const dataObj = resp.data||[];
+         setCoupons((prev) => [...prev, ...dataObj]);
+      }
+     
+      // console.log("完整返回:", dataObj);
+    };
 
-  // 复用懒加载Hook
+    load();
+  }, []);
   const { containerRef, isLoading } = useInfiniteScroll({
     loadMore: loadMoreCoupons,
     hasMore,
   });
 
   return (
-    <div 
+    <div
       ref={containerRef}
-      className="h-[calc(100vh-80px)] overflow-auto px-2 py-4"
+      className="
+        max-h-[420px]
+        mb-9
+      "
     >
-      {/* 优惠券列表 */}
-      <div className="space-y-4">
+      <div
+        className="
+          flex
+          flex-col
+          gap-4
+        "
+      >
         {coupons.map((item) => (
-          <div 
+          <div
             key={item.id}
-            className="flex items-center bg-pink-100 rounded-lg overflow-hidden"
+            className="
+              flex
+              items-center
+              bg-[url('/image/account/couponBg.png')]
+              bg-cover
+              bg-center
+              w-[358px]
+              h-[88px]
+              overflow-hidden
+            "
           >
-            {/* 优惠信息区 */}
-            <div className="flex-1 p-4 text-pink-600">
-              <h3 className="text-2xl font-bold">{item.discount}</h3>
-              <p className="text-sm mt-1">{item.desc}</p>
-              <p className="text-xs mt-2 text-pink-500">{item.valid}</p>
-            </div>
-            {/* 分割线 */}
-            <div className="w-0.5 bg-pink-300 h-16 relative">
-              <div className="absolute top-0 left-[-4px] w-2 h-2 bg-white border border-pink-300 rounded-full"></div>
-              <div className="absolute bottom-0 left-[-4px] w-2 h-2 bg-white border border-pink-300 rounded-full"></div>
+            {/* 左侧优惠信息 */}
+            <div
+              className="
+                flex-1
+                pl-6
+                pt-2
+              "
+            >
+              <div
+                className="
+                  text-[40px]
+                  leading-none
+                  font-bold
+                  text-[#036141]
+              
+                "
+              >
+                {item.discount_text}
+              </div>
+
+              <div
+                className="
+                mt-1
+                text-ly-12
+                font-normal
+                text-black
+              "
+              >
+                {item.rule_description || "For All Products"}
+              </div>
             </div>
-            {/* 使用按钮区 */}
-            <div className="px-6 py-4 font-bold text-black">
-              Use Now
+
+
+            {/* 右侧按钮和日期 */}
+            <div
+              className="
+                flex
+                w-[150px]
+                flex-col
+                items-center
+                justify-center
+              "
+            >
+              <button
+                className="
+                  h-[32px]
+                  w-[100px]
+                  rounded-full
+                  bg-[#008052]
+                  text-ly-14
+                  font-medium
+                  text-white
+                "
+              >
+                Use Now
+              </button>
+
+              <div
+                className="
+                  mt-2
+                  text-ly-12
+                  text-black
+                "
+              >
+                Expire In {item.expired_at}
+              </div>
             </div>
           </div>
         ))}
       </div>
 
-      {/* 加载状态/无更多提示 */}
-      <div className="text-center mt-4 text-gray-400 text-sm">
-        {isLoading ? 'Loading...' : hasMore ? '' : 'No More Data'}
-      </div>
+      {isLoading && (
+        <div
+          className="
+              mt-4
+              text-center
+              text-gray-400
+            "
+        >
+          Loading...
+        </div>
+      )}
     </div>
   );
 };
 
-export default CouponList;
+export default CouponList;

+ 12 - 12
src/app/(public)/customer/(has-dashboard)/account/mycoupon/_components/GiftCardList.tsx

@@ -16,23 +16,23 @@ const GiftCardList: React.FC = () => {
   //     status: "Unused",
   //     valid: "Valid:6/2/2026-12/31/2026",
   //   },
-  // {
-  //   expirationdate: "2026-07-04",
-  //   formatted_remaining_giftcard_amount: "$30.00",
-  //   giftcard_amount: "30.00",
-  //   giftcard_number: "CFVG-RYUD-AOXF-GSLE",
-  //   giftcard_status: "1",
-  //   id: 7,
-  //   remaining_giftcard_amount: "30.00",
-  //   used_giftcard_amount: "0.00",
-  // }
+ const data = {
+    expirationdate: "2026-07-04",
+    formatted_remaining_giftcard_amount: "$30.00",
+    giftcard_amount: "30.00",
+    giftcard_number: "CFVG-RYUD-AOXF-GSLE",
+    giftcard_status: "1",
+    id: 7,
+    remaining_giftcard_amount: "30.00",
+    used_giftcard_amount: "0.00",
+  }
   const [giftCards, setGiftCards] = useState<GiftCardItem[]>([]);
   const [hasMore, setHasMore] = useState(true);
 
   useEffect(() => {
     const load = async () => {
       const resp = await clientFetch("/api/gift/my-gift-cards");
-      const dataObj = resp.data;
+      const dataObj =[data] // resp.data||;
       setGiftCards((prev) => [...prev, ...dataObj]);
       console.log("完整返回:", dataObj);
     };
@@ -75,7 +75,7 @@ const GiftCardList: React.FC = () => {
   return (
     <div
       ref={containerRef}
-      className="h-[calc(100vh-80px)] overflow-auto px-4 py-4"
+      className=" overflow-auto "
     >
       {/* 礼品卡列表 */}
       <div className="space-y-4">

+ 0 - 42
src/app/(public)/customer/(has-dashboard)/account/mycoupon/_components/TabButton.tsx

@@ -1,42 +0,0 @@
-"use client";
-import React, { useState } from 'react';
-import CouponList from './CouponList';
-import GiftCardList from './GiftCardList';
-const TabButton: React.FC = () => {
- const [activeTab, setActiveTab] = useState<'coupon' | 'giftcard'>('coupon');
-  return (
-    <div>
-      {/* Tab 切换栏 */}
-      <div className="flex w-full">
-        {/* My Coupon Tab */}
-        <button
-          onClick={() => setActiveTab("coupon")}
-          className={`flex-1 py-3 text-center font-medium ${
-            activeTab === "coupon"
-              ? "bg-black text-white "
-              : "bg-white text-black"
-          }`}
-        >
-          My Coupon
-        </button>
-        {/* My Giftcard Tab */}
-        <button
-          onClick={() => setActiveTab("giftcard")}
-          className={`flex-1 py-3 text-center font-medium ${
-            activeTab === "giftcard"
-              ? "bg-black text-white"
-              : "bg-white text-black"
-          }`}
-        >
-          My Giftcard
-        </button>
-      </div>
-
-      {/* 内容展示区 */}
-      <div className="mt-2">
-        {activeTab === "coupon" ? <CouponList /> : <GiftCardList />}
-      </div>
-    </div>
-  );
-};
-export default TabButton;

+ 5 - 4
src/app/(public)/customer/(has-dashboard)/account/mycoupon/page.tsx

@@ -1,9 +1,9 @@
 import Link from "next/link";
-import TabButton from "./_components/TabButton"
+import CouponGiftCard from "./_components/CouponGiftCard"
 const CouponsPage: React.FC = () => {
   return (
     <div className="w-full h-full">
-       <div className="bg-[#fff] pr-2.5 pl-2.5 w-full text-center text-base h-11 leading-11 font-semibold relative text-[#0b0b0b]">
+       {/* <div className="bg-[#fff] pr-2.5 pl-2.5 w-full text-center text-base h-11 leading-11 font-semibold relative text-[#0b0b0b]">
         <Link
           className="absolute left-2.5 text-2xl inline-block top-1/2  -translate-y-1/2"
           href="/customer/account/mypoints"
@@ -26,8 +26,9 @@ const CouponsPage: React.FC = () => {
           </svg>
         </Link>
         <span className="vipReturnTitles">Accessories</span>
-      </div>
-      <TabButton/>
+      </div> */}
+      <h1 className="font-normal text-2xl leading-ly-28 mb-6">Coupon & Gifts Card</h1>
+      <CouponGiftCard/>
     </div>
   );
 };

+ 22 - 11
src/app/(public)/customer/(has-dashboard)/account/page.tsx

@@ -1,6 +1,7 @@
 import AccountSwiper from "@components/customer/accountSwiper";
 import AccountHeader from "./_components/AccountHeader"
-import AccountBottomHrefSwiper from "./_components/AccountBottomHrefSwiper"
+// import AccountBottomHrefSwiper from "./_components/AccountBottomHrefSwiper"
+import { restApiFetch } from "@utils/bagisto/index";
 // import Link from "next/link";
 const orderNavs = [
   {
@@ -10,17 +11,17 @@ const orderNavs = [
   },
   {
     href: "/customer/order/history/#processing",
-    img: "/image/navigate/202309040911.png",
+    img: "/image/navigate/processing.png",
     text: "Processing",
   },
   {
     href: "/customer/order/history/#complete",
-    img: "/image/navigate/202309040912.png",
+    img: "/image/navigate/completed.png",
     text: "Complete",
   },
   { 
     href: "/customer/order/history/#paymentreview",
-    img: "/image/navigate/202309040913.png",
+    img: "/image/navigate/reviews.png",
     text: (
       <>
         Payment
@@ -31,15 +32,25 @@ const orderNavs = [
   },
 ];
 
-const MyAccountPage = () => {
-  
+const MyAccountPage =async () => {
+ const res = await restApiFetch({
+  api: `/customer/profile`,
+  method: "GET",
+  isRoute: false,
+});
+console.log('accountres-----------------------------:',res);
+
   return (
     <div className="min-h-screen bg-white  ">
       <h1 className="font-normal text-2xl leading-ly-28 mb-6">My Account</h1>
-      <AccountHeader />
+      <AccountHeader
+        user={res.body.data.user}
+        points={res.body.data.points}
+        coupon_count={res.body.data.coupon_count}
+      />
       {/* 我的订单 */}
-      <div className="">
-        <h3 className="mt-8 ml-4 text-base">My Order</h3>
+      <div className="mt-[136px]">
+        <h3 className="mt-8 font-medium leading-ly-26 text-ly-18">My Order ({res.body.data.order_count})</h3>
         <div className="flex flex-wrap justify-between mt-5 ">
           {orderNavs.map((item, index) => (
             <a
@@ -50,7 +61,7 @@ const MyAccountPage = () => {
               <div className="w-21 flex flex-col items-center font-medium text-xs">
                 <img
                   src={item.img}
-                  className={`w-6 h-6 ${index == 3 ? "mb-0.5" : ""}`}
+                  className={`w-8 h-8 ${index == 3 ? "mb-0.5" : ""}`}
                   alt=""
                 />
                 <p className="text-center mt-2.5">{item.text}</p>
@@ -139,7 +150,7 @@ const MyAccountPage = () => {
         {/* 引入轮播组件 */}
         <AccountSwiper />
        {/* 底部跳转轮播 */}
-       <AccountBottomHrefSwiper />
+       {/* <AccountBottomHrefSwiper /> */}
       </div>
     </div>
   );

+ 32 - 0
src/app/api/customer/coupons/route.ts

@@ -0,0 +1,32 @@
+import { NextResponse } from "next/server";
+import { restApiFetch } from "@/utils/bagisto";
+
+
+
+export async function GET() {
+  try {
+
+    const response = await restApiFetch<any>({
+      api: "/customer/coupons",
+      method: "GET",
+      cache: "no-store",
+
+    });
+
+    return NextResponse.json(
+      response.body,
+      {status: response.status}
+    );
+
+  } catch (error) {
+
+
+    return NextResponse.json(
+      {
+        message: "Network error",
+        error: error instanceof Error ? error.message : error,
+      },
+      { status: 500 }
+    );
+  }
+}