Procházet zdrojové kódy

Merge branch 'feature-Before' into dev

# Conflicts:
#	src/app/[locale]/providers.tsx
Ansoni před 5 měsíci
rodič
revize
731b517a88

+ 0 - 15
src/app/[locale]/(TabBar)/[[...share]]/@actionWidget/Scroll.tsx

@@ -1,25 +1,10 @@
 "use client";
-import { usePathname } from "@/i18n/routing";
-import { useEffect } from "react";
 
 const Scroll = () => {
     const scrollToTop = () => {
         const parentEle = document.querySelector("#maincontainer");
         parentEle!.scrollTo({ top: 0, behavior: "smooth" });
     };
-    // 获取分享id
-    const pathname = usePathname();
-    useEffect(() => {
-        localStorage.setItem("channel_code", window.location.href);
-
-        const [, shareId] = pathname.split("/");
-        if (!shareId || shareId === "xxxxxx") return;
-        if (shareId.length !== 8) {
-            sessionStorage.removeItem("shareId");
-            return;
-        }
-        sessionStorage.setItem("shareId", shareId);
-    }, []);
     return (
         <div className={"mt-[0.1rem] flex items-center justify-around pb-[0.5rem] text-[#fff]"}>
             <div

+ 28 - 0
src/app/[locale]/(TabBar)/[[...share]]/@clientWidget/page.tsx

@@ -0,0 +1,28 @@
+"use client";
+import { useEventPoint } from "@/hooks/useEventPoint";
+import { usePathname } from "@/i18n/routing";
+import { useEffect } from "react";
+
+/**
+ * @description 主页初始化
+ */
+const Page = () => {
+    useEventPoint();
+
+    // 获取分享id
+    const pathname = usePathname();
+    useEffect(() => {
+        localStorage.setItem("channel_code", window.location.href);
+
+        const [, shareId] = pathname.split("/");
+        if (!shareId || shareId === "xxxxxx") return;
+        if (shareId.length !== 8) {
+            sessionStorage.removeItem("shareId");
+            return;
+        }
+        sessionStorage.setItem("shareId", shareId);
+    }, []);
+    return null;
+};
+
+export default Page;

+ 1 - 1
src/app/[locale]/(TabBar)/[[...share]]/@mediaWidget/page.tsx

@@ -3,7 +3,7 @@ import { Media } from "@/components/Media";
 
 const Page = async () => {
     const socials = await getSocialsApi();
-    if (socials.length === 0) return null;
+    if (socials && socials.length === 0) return null;
     return (
         <div className={"mb-[0.0694rem] px-[0.4167rem]"}>
             <Media socials={socials} />

+ 49 - 0
src/app/[locale]/(TabBar)/[[...share]]/@sportSwiperWidget/SportSwiper.tsx

@@ -0,0 +1,49 @@
+"use client";
+import { FC } from "react";
+
+import { BannerRep } from "@/api/home";
+import { Link } from "@/i18n/routing";
+import { useTranslations } from "next-intl";
+import { Autoplay } from "swiper/modules";
+import { Swiper, SwiperSlide } from "swiper/react";
+interface Props {
+    banners: BannerRep[];
+}
+const SportSwiper: FC<Props> = (props) => {
+    const { banners = [] } = props;
+    const t = useTranslations();
+    return (
+        <div className={"mt-[0.05rem]"}>
+            <h2 className={"mb-[0.05rem]"}>{t("Sidebar.esportes")}</h2>
+            <Swiper
+                spaceBetween={30}
+                speed={5000}
+                className={"sport-banner"}
+                slidesPerView={3}
+                autoplay={{
+                    delay: 0,
+                    disableOnInteraction: false,
+                    pauseOnMouseEnter: true,
+                }}
+                modules={[Autoplay]}
+            >
+                {banners.map((banner, index) => (
+                    <SwiperSlide key={index}>
+                        {/*<Box none action={banner.action_type} actionData={banner.action_params}>*/}
+                        <Link href={"/sports"}>
+                            <img
+                                src={banner.content}
+                                alt={"banner"}
+                                className={"h-[1.1rem] w-[1.1rem] object-contain"}
+                            />
+                        </Link>
+
+                        {/*</Box>*/}
+                    </SwiperSlide>
+                ))}
+            </Swiper>
+        </div>
+    );
+};
+
+export default SportSwiper;

+ 29 - 0
src/app/[locale]/(TabBar)/[[...share]]/@sportSwiperWidget/page.tsx

@@ -0,0 +1,29 @@
+import { BannerRep } from "@/api/home";
+import SportSwiper from "@/app/[locale]/(TabBar)/[[...share]]/@sportSwiperWidget/SportSwiper";
+import { server } from "@/utils/server";
+
+/**
+ * 获取体育轮播图
+ *   POST /v1/api/front/sport
+ *   接口ID:260132799
+ *   接口地址:https://app.apifox.com/link/project/4790544/apis/api-260132799
+ */
+const getSportBannerApi = async () => {
+    return server
+        .request<BannerRep[]>({
+            url: "/v1/api/front/sport",
+            method: "post",
+        })
+        .then((res) => {
+            if (res.code === 200) return res.data;
+            return [];
+        });
+};
+
+const Page = async () => {
+    const banners = await getSportBannerApi();
+    if (banners.length === 0) return null;
+    return <SportSwiper banners={banners} />;
+};
+
+export default Page;

+ 7 - 0
src/app/[locale]/(TabBar)/[[...share]]/layout.tsx

@@ -11,6 +11,7 @@ export const generateMetadata = async () => {
     };
 };
 type Props = {
+    clientWidget: ReactNode;
     swiperWidget: ReactNode;
     popupWidget: ReactNode;
     cardWidget: ReactNode;
@@ -19,6 +20,7 @@ type Props = {
     prizeWidget: ReactNode;
     actionWidget: ReactNode;
     mediaWidget: ReactNode;
+    sportSwiperWidget: ReactNode;
 };
 const Layout: FC<PropsWithChildren<Props>> = (props) => {
     const {
@@ -31,10 +33,13 @@ const Layout: FC<PropsWithChildren<Props>> = (props) => {
         prizeWidget,
         actionWidget,
         mediaWidget,
+        sportSwiperWidget,
+        clientWidget,
     } = props;
 
     return (
         <>
+            {clientWidget}
             <DownloadSection />
             <Header></Header>
             <main id="maincontainer" className={"main-header"}>
@@ -51,6 +56,8 @@ const Layout: FC<PropsWithChildren<Props>> = (props) => {
                     {mediaWidget}
                     {/* 搜索组件 */}
                     {searchWidget}
+                    {/*体育轮播*/}
+                    {sportSwiperWidget}
                     {/* 搜索下面的大奖展示 */}
                     {prizeWidget}
                 </Box>

+ 5 - 3
src/app/[locale]/(TabBar)/profile/ProfileHeader.tsx

@@ -31,7 +31,7 @@ const VipCard = (props: { userVip: UserVipInfo }) => {
 
     // Vip 图标
     const vipIconElement = vipImages.map((item, index) => {
-        if (item.leve === userVip.vip_level) {
+        if (item.leve === userVip?.vip_level) {
             return (
                 <Fragment key={index}>
                     <Image src={item.src} alt={"vip"} height={110} width={100} />
@@ -42,6 +42,8 @@ const VipCard = (props: { userVip: UserVipInfo }) => {
             );
         }
     });
+
+    if (!userVip) return null;
     return (
         <div className={"vip-card"}>
             <div className={"vip-card__icon"}>{vipIconElement}</div>
@@ -49,7 +51,7 @@ const VipCard = (props: { userVip: UserVipInfo }) => {
                 {/*<div className={"process-top"}>{userVip.vip_exp}xp</div>*/}
                 <div>
                     <ProgressBar
-                        percent={percentage(userVip.vip_exp, userVip.vip_score_exp)}
+                        percent={percentage(userVip?.vip_exp, userVip?.vip_score_exp)}
                         style={{
                             "--fill-color": "#fb8b05",
                             "--track-width": "0.0694rem",
@@ -57,7 +59,7 @@ const VipCard = (props: { userVip: UserVipInfo }) => {
                     />
                 </div>
                 <div className={"process-bottom"}>
-                    <span>VIP{userVip.vip_level}</span>
+                    <span>VIP{userVip?.vip_level}</span>
                     <span className={"process-bottom-desc"}>
                         {t("expTips", {
                             exp: flatPoint(userVip.vip_score_exp - userVip.vip_exp),

+ 1 - 1
src/app/[locale]/(TabBar)/profile/page.tsx

@@ -65,7 +65,7 @@ const Profile = async () => {
     const userMoney = await getMoneyApi();
     const userVip = await getVipApi();
     const cashback = await getCashBackApi();
-    const max = cashback.rules.reduce(
+    const max = cashback?.rules.reduce(
         (acc, item) => (acc > item.cashback ? acc : item.cashback),
         0
     );

+ 0 - 1
src/app/[locale]/(enter)/login/page.tsx

@@ -8,7 +8,6 @@ import GoogleCom from "../components/GoogleCom";
 const Login = async () => {
     const t = await getTranslations("LoginPage");
     const services = await getServicesApi();
-    console.log(`🚀🚀🚀🚀🚀-> in page.tsx on 11`, services);
     const defaultService = services?.filter((item) => item.register_show === 1);
     return (
         <>

+ 18 - 1
src/app/[locale]/providers.tsx

@@ -12,7 +12,7 @@ import { setupFontSize } from "@/utils";
 import { useDebounceEffect } from "ahooks";
 import { initializeApp } from "firebase/app";
 import { getMessaging, getToken, onMessage } from "firebase/messaging";
-
+import Script from "next/script";
 export interface ProvidersProps {
     children: ReactNode;
     themeProps?: Omit<ThemeProviderProps, "children">;
@@ -85,6 +85,23 @@ const Layout = ({ children, themeProps }: ProvidersProps) => {
 
     return (
         <div id="app" className="bg-black">
+            <Script
+                id={"feback"}
+                dangerouslySetInnerHTML={{
+                    __html: `<!-- Meta Pixel Code -->
+            !function(f,b,e,v,n,t,s)
+            {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
+            n.callMethod.apply(n,arguments):n.queue.push(arguments)};
+            if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
+            n.queue=[];t=b.createElement(e);t.async=!0;
+            t.src=v;s=b.getElementsByTagName(e)[0];
+            s.parentNode.insertBefore(t,s)}(window, document,'script',
+            'https://connect.facebook.net/en_US/fbevents.js');
+            fbq('init', '625811426763645');
+            fbq('track', 'PageView');
+<!-- End Meta Pixel Code -->`,
+                }}
+            ></Script>
             <Swiper
                 resistanceRatio={10}
                 initialSlide={2}

+ 4 - 0
src/app/globals.scss

@@ -27,6 +27,10 @@
   --swiper-pagination-bullet-height: 0.0833rem;
   //--swiper-pagination-bottom: 0;
 }
+
+.sport-banner {
+  --swiper-wrapper-transition-timing-function: linear;
+}
 /// antd-mobile
 :root:root{
   --adm-color-background: transparent ;

+ 4 - 2
src/components/Card/SwiperGroup.tsx

@@ -60,7 +60,9 @@ const HomeSwiper: FC<PropsWithChildren<SwiperGroupProps>> = (props) => {
         .map((_, index) => {
             return {
                 key: index,
-                data: gameList.slice(index * lineNum, index * lineNum + lineNum).map(subItem => ({ ...subItem, category_name: group.category_name }))
+                data: gameList
+                    .slice(index * lineNum, index * lineNum + lineNum)
+                    .map((subItem) => ({ ...subItem, category_name: group.category_name })),
             };
         });
     const prev = () => {
@@ -121,7 +123,7 @@ const HomeSwiper: FC<PropsWithChildren<SwiperGroupProps>> = (props) => {
                                     <GroupCard
                                         data={data.data}
                                         {...other}
-                                        groupType={group.bet_type}
+                                        groupType={1}
                                     ></GroupCard>
                                 )}
                             </SwiperSlide>

+ 58 - 0
src/hooks/useEventPoint.tsx

@@ -0,0 +1,58 @@
+import { useSearchParams } from "next/navigation";
+import { useEffect } from "react";
+
+type SourceType = "facebook" | "Kwai";
+
+/**
+ * @description
+ *
+  1、查看内容 - ViewContent   打开首页
+  2.完成注册 - CompleteRegistration
+  3.登陆 - SubmitApplication
+  4.开始试用游戏 - StartTrial    启动一次游戏就触发
+  5.加入购物车 - AddToCart    付费一次就回传一次,包含复充
+  6.拉起订单 - InitiateCheckout    用户发起充值,调出第三方充值二维码
+  7.首充事件 - Purchase   新用户第一次完成首充回传一次,之后复充不在回传
+ */
+const useEventPoint = () => {
+    const pathname = useSearchParams();
+    const a = pathname.get("source");
+    console.log(`🚀🚀🚀🚀🚀-> in useEventPoint.tsx on 20`, a);
+    const source: SourceType = "facebook";
+    useEffect(() => {
+        console.log(`🚀🚀🚀🚀🚀-> in useEventPoint.tsx on 6`, window.fbq("ViewContent"));
+    });
+    // 查看内容
+    const eventView = () => {
+        console.log(`🚀🚀🚀🚀🚀-> in useEventPoint.tsx on 10`, window.fbq);
+    };
+    // 注册
+    const eventRegister = () => {};
+
+    // 登录
+    const eventLogin = () => {};
+
+    // 开始试用游戏
+    const eventStartTrial = () => {};
+
+    // 加入购物车
+    const eventPurchase = () => {};
+
+    //拉起订单
+    const eventInitiate = () => {};
+
+    //首充事件
+    const eventFirstDeposit = () => {};
+
+    return {
+        eventView,
+        eventRegister,
+        eventLogin,
+        eventStartTrial,
+        eventPurchase,
+        eventInitiate,
+        eventFirstDeposit,
+    };
+};
+
+export { useEventPoint };