浏览代码

feat: 连续充值签到

year 3 月之前
父节点
当前提交
7d15cb84b1

二进制
public/continuous/bg1.png


二进制
public/continuous/bg2.png


二进制
public/continuous/bg_1.png


二进制
public/continuous/btn1.png


二进制
public/continuous/btn2.png


二进制
public/continuous/gou.png


二进制
public/continuous/recharge.png


二进制
public/continuous/rili.png


二进制
public/continuous/s1.png


二进制
public/continuous/s2.png


二进制
public/continuous/s3.png


二进制
public/continuous/s4.png


二进制
public/continuous/t1.png


二进制
public/continuous/title.png


二进制
public/continuous/top.png


二进制
public/continuous/v1.png


二进制
public/continuous/v2.png


二进制
public/continuous/v3.png


二进制
public/continuous/v4.png


+ 20 - 0
src/app/[locale]/(doings)/continuous/layout.tsx

@@ -0,0 +1,20 @@
+import HeaderBack from "@/components/HeaderBack";
+import { getTranslations } from "next-intl/server";
+import { ReactNode } from "react";
+import styles from "./page.module.scss";
+
+export default async function Layout({
+    children,
+    params: { locale },
+}: {
+    children: ReactNode;
+    params: { locale: string };
+}) {
+    const t = await getTranslations("Header");
+    return (
+        <div className={styles.page}>
+            <HeaderBack showBack={true} title={"Bónus Misterioso"} useBg={true} />
+            <main className={"main-header"}>{children}</main>
+        </div>
+    );
+}

+ 364 - 0
src/app/[locale]/(doings)/continuous/page.module.scss

@@ -0,0 +1,364 @@
+.page {
+    height: 100%;
+}
+.continuePage {
+    height: 100%;
+    overflow: auto;
+    background-color: #813af4;
+    .container {
+        position: relative;
+        .img {
+            width: 100%;
+        }
+        .recharge {
+            background-image: url("/continuous/recharge.png");
+            background-size: 100% 100%;
+            width: 1.1rem;
+            height: 0.4rem;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            position: absolute;
+            right: 0;
+            top: 1.5rem;
+            font-weight: 700;
+            box-sizing: border-box;
+            padding-top: 0.04rem;
+            text-shadow:
+                0.02rem 0.02rem 0.04rem #b81bac,
+                // 右下主阴影
+                -0.02rem -0.02rem 0.04rem #b81bac;
+            // 左上辅助阴影
+            // 0 0 0.08rem rgba(184, 27, 172, 0.5);
+        }
+    }
+    .content {
+        position: relative;
+        top: -0.6rem;
+        .tip {
+            height: 0.46rem;
+            width: 3rem;
+            background-image: url("/continuous/bg1.png");
+            background-size: 100% 100%;
+            margin: 0 auto;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            overflow: hidden;
+            .text {
+                white-space: nowrap;
+            }
+        }
+    }
+    .inner {
+        height: 300px;
+        position: relative;
+        // border-radius: 0.2rem 0.2rem 0 0;
+        &::before {
+            content: "";
+            position: absolute;
+            top: 0;
+            right: 0;
+            left: 0;
+            height: 1rem;
+            border-radius: 0.3rem;
+            background-color: #5db0ff;
+            z-index: 1;
+            box-shadow: 0 0 0.1rem rgba(255, 255, 255, 0.1) inset; // 添加内阴影效果,使背景更暗;
+        }
+        &::after {
+            content: "";
+            position: absolute;
+            top: 0.15rem;
+            right: 0;
+            left: 0;
+            height: 1rem;
+            border-radius: 0.3rem;
+            background-color: #ff02ea;
+            z-index: 1;
+        }
+    }
+    .innerContainer {
+        box-shadow: 0 0 0.2rem #9895d6 inset;
+        background-image: url("/continuous/bg_1.png");
+        background-size: 100% auto;
+        background-repeat: repeat-y;
+        border-radius: 0.3rem 0.3rem 0 0;
+        position: relative;
+        z-index: 2;
+        top: 0.17rem;
+        background-color: #5904ee;
+        box-sizing: border-box;
+        padding: 0.2rem 0.15rem;
+        box-shadow: 0 0 0.2rem #bfa0f9 inset; // 添加内阴影效果,使背景更暗;
+    }
+}
+
+.box {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .boxItem {
+        width: 0.8rem;
+        height: 1.1rem;
+        background-size: 100% 100%;
+        position: relative;
+    }
+    .boxItemTop {
+        height: 0.29rem;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        .boxItemTopText {
+            text-align: center;
+            word-break: break-word;
+            font-size: 0.11rem;
+            line-height: 1.1;
+            font-weight: 700;
+            background: linear-gradient(to bottom, #ffffea, #fff349); // 添加水平渐变背景
+            -webkit-background-clip: text; // 将背景裁剪到文字
+            background-clip: text;
+            -webkit-text-fill-color: transparent;
+        }
+    }
+    .boxItemBottom {
+        position: absolute;
+        left: 0;
+        bottom: 0;
+        right: 0;
+        height: 0.29rem;
+        line-height: 1.1;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        word-break: break-word;
+        font-size: 0.11rem;
+    }
+}
+.daybox {
+    margin-top: 0.14rem;
+    background: linear-gradient(to bottom, #ff03ea, #0af0ff); // 添加水平渐变背景
+    border-radius: 0.2rem;
+    box-sizing: border-box;
+    padding: 0.02rem;
+    .dayContainer {
+        background-color: #813af3;
+        box-shadow: 0 0 15px rgba(255, 5, 234, 0.5) inset;
+        min-height: 1rem;
+        padding: 0.1rem;
+        border-radius: 0.2rem;
+        background-image: url("/continuous/bg_1.png");
+        background-repeat: repeat;
+        display: flex;
+        flex-direction: row;
+        flex-wrap: wrap;
+        justify-content: flex-start;
+        gap: 0.1rem;
+    }
+    .dayItem {
+        flex: 0 0 calc(16.666% - 0.0833rem);
+        margin-bottom: 0.1rem;
+        height: 0.57rem;
+        text-align: center;
+        border-radius: 0.08rem;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        &.active {
+            background-color: #7742d4;
+            position: relative;
+            &:after {
+                content: "";
+                position: absolute;
+                left: 0;
+                top: 0;
+                right: 0;
+                bottom: 0;
+                background-image: url("/continuous/gou.png");
+                background-size: 50% auto;
+                background-repeat: no-repeat;
+                background-position: center center;
+                z-index: 1;
+            }
+            .dayItemText {
+                display: none;
+            }
+            .dayitemTextActive {
+                display: flex;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                justify-content: center;
+                font-size: 0.1rem;
+                line-height: 1;
+                img {
+                    width: 0.2rem;
+                }
+            }
+        }
+    }
+    .dayItemText {
+        font-size: 0.12rem;
+        color: #dbc6ff;
+    }
+    .dayitemTextActive {
+        display: none;
+    }
+}
+.premio {
+    margin-top: 0.2rem;
+    .premioTitle {
+        background-image: url("/continuous/t1.png");
+        margin: 0 0.32rem;
+        background-size: 100% 100%;
+        height: 0.43rem;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: #fb4862;
+        font-size: 0.15rem;
+        font-weight: 700;
+        box-sizing: border-box;
+        padding-top: 0.06rem;
+
+        .premioTitleText {
+            -webkit-background-clip: text; // 将背景裁剪到文字
+            background-clip: text;
+            filter: drop-shadow(0 2px 1px #fff);
+        }
+    }
+    .premioContainer {
+        border-radius: 0.2rem;
+        background: linear-gradient(to bottom, #ff03ea, #0af0ff); // 添加水平渐变背景
+        padding: 0.02rem;
+    }
+    .premioContent {
+        background-color: #942ef7;
+        box-shadow: 0 0 15px rgba(255, 5, 234, 0.5) inset;
+        min-height: 1rem;
+        padding: 0.1rem;
+        border-radius: 0.2rem;
+        background-image: url("/continuous/bg_1.png");
+        padding: 0.15rem 0.1rem;
+    }
+    .premioItem {
+        border-radius: 0.1rem;
+        display: flex;
+        padding: 0.08rem;
+        box-shadow: 0 0 0.1rem rgba(242, 142, 254, 1) inset; // 添加内阴影效果,使背景更暗;
+        background-color: rgba(242, 142, 254, 0.4);
+        margin-bottom: 0.15rem;
+    }
+    .premioItemDay {
+        width: 0.6rem;
+        height: 0.6rem;
+        border-radius: 0.1rem;
+        background: url("/continuous/rili.png") no-repeat;
+        background-size: 50% auto;
+        background-position: center center;
+        background-color: #fff;
+        perspective: 100px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-size: 0.18rem;
+        font-weight: 700;
+        margin-right: 0.1rem;
+        span {
+            position: relative;
+            top: 0.07rem;
+            left: -0.04rem;
+            transform: rotateY(-46deg) rotateX(6deg);
+        }
+    }
+    .premioItemBtn {
+        width: 0.95rem;
+        height: 0.25rem;
+        background-image: url("/continuous/btn2.png");
+        background-size: 100% 100%;
+        font-size: 0.11rem;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        &.disabled {
+            background-image: url("/continuous/btn1.png");
+        }
+    }
+}
+.canGet {
+    width: 2.27rem;
+    height: 0.3rem;
+    background-image: url("/continuous/bg2.png");
+    background-size: 100% 100%;
+    text-align: center;
+    line-height: 0.3rem;
+    color: #fff;
+    font-size: 0.14rem;
+    font-weight: 700;
+}
+.introbox {
+    margin-top: 0.3rem;
+    border-radius: 0.2rem;
+    background: linear-gradient(to bottom, #ff03ea, #0af0ff); // 添加水平渐变背景
+    padding: 0.02rem;
+    .introContainer {
+        background-color: #942ef7;
+        box-shadow: 0 0 15px rgba(255, 5, 234, 0.5) inset;
+        min-height: 1rem;
+        padding: 0.1rem;
+        border-radius: 0.2rem;
+        background-image: url("/continuous/bg_1.png");
+        padding: 0.15rem 0.1rem;
+        position: relative;
+    }
+    .introTitle {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        position: absolute;
+        top: -0.1rem;
+        left: 0;
+        right: 0;
+        .introTitleText {
+            width: 2.7rem;
+            height: 0.4rem;
+            background-image: url("/continuous/title.png");
+            background-size: 100% 100%;
+            text-align: center;
+            font-size: 0.16rem;
+            font-weight: 700;
+            text-shadow: 0 0 0.02rem red; // 添加文字阴影效果,使文字更清晰;
+            padding-top: 0.06rem;
+        }
+    }
+    .introboxDesc {
+        padding-top: 0.2rem;
+        font-size: 0.12rem;
+        line-height: 1.5;
+    }
+}
+.introItem {
+    display: flex;
+    flex-direction: row;
+    font-size: 0.12rem;
+    align-items: stretch;
+    background-color: #8e28e0;
+    &.odd {
+        background-color: #7622bb;
+    }
+    div {
+        flex: 1 0;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        padding: 0.1rem 0;
+
+        &.idx1 {
+            flex: 0 0 0.4rem;
+        }
+    }
+}

+ 220 - 0
src/app/[locale]/(doings)/continuous/page.tsx

@@ -0,0 +1,220 @@
+"use client";
+import CutDown from "@/components/CutDown";
+import { useRouter } from "@/i18n/routing";
+import clsx from "clsx";
+import React from "react";
+import styles from "./page.module.scss";
+
+const DayItem = () => {
+    return (
+        <div>
+            <div className="mb-[.1rem] flex flex-row justify-center">
+                <div className={styles.canGet}>Grande Prêmio Disponível</div>
+            </div>
+            <div className="item-center mb-[.1rem] flex flex-row justify-center">
+                <CutDown endTime={232323} itemBgColor="rgba(255,255,255,.4)"></CutDown>
+            </div>
+            <div className={styles.premioItem}>
+                <div className={styles.premioItemDay}>
+                    <span style={{ color: "#12950f" }}>17</span>
+                </div>
+                <div>
+                    <div className="text-[.16rem] font-bold">Recarga contínua por 7 dias</div>
+                    <div className="flrx-row flex items-center justify-between">
+                        <div>Recompensa de login Platinum 1R</div>
+                        <div className={styles.premioItemBtn}>Recebido</div>
+                        {/* Receber */}
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
+
+const Page = () => {
+    const router = useRouter();
+    const dayContainer = React.useRef<HTMLDivElement>(null);
+
+    const itemInfo = React.useMemo(() => {
+        if (!dayContainer.current) return 47;
+        return dayContainer.current?.getBoundingClientRect().width / 6 - 10;
+    }, []);
+
+    const cfg1 = React.useMemo(() => {
+        return [
+            {
+                text: "LOGIN ",
+                text2: "PLATINUM",
+                key: 1,
+                footer: "Alcançou",
+            },
+            {
+                text: "LOGIN",
+                text2: "GOLD",
+                key: 2,
+                footer: "Alcançou",
+                footer2: "5R",
+            },
+            {
+                text: "LOGIN",
+                text2: "DIAMANTE",
+                key: 3,
+                footer: "Alcançou",
+                footer2: "5R",
+            },
+            {
+                text: "ENTRAR NO",
+                text2: "MONOPOLY",
+                key: 4,
+                footer: "Ainda preciso",
+                footer2: "5R",
+            },
+        ];
+    }, []);
+
+    const data = [1, 2, 3, 4, 5, 6, 7, , 8, 9, 0, 11, 12, 13, 14, 15, 16, 17];
+
+    return (
+        <div className={clsx(styles.continuePage)}>
+            <div className={styles.container}>
+                <div className={styles.top}>
+                    <img className={styles.img} src="/continuous/top.png" alt="" />
+                    <div className={styles.recharge}>RECARGA</div>
+                </div>
+                <div className={styles.content}>
+                    <div className={styles.tip}>
+                        <div className={styles.text}>Check-in 5 dias consecutivos</div>
+                    </div>
+
+                    <div className={styles.inner}>
+                        <div className={styles.innerContainer}>
+                            <div className={styles.box}>
+                                {cfg1.map((item) => {
+                                    return (
+                                        <div
+                                            key={item.key}
+                                            className={styles.boxItem}
+                                            style={{
+                                                backgroundImage: `url('/continuous/v${item.key}.png')`,
+                                            }}
+                                        >
+                                            <div className={styles.boxItemTop}>
+                                                <div className={styles.boxItemTopText}>
+                                                    {item.text}
+                                                </div>
+                                                <div className={styles.boxItemTopText}>
+                                                    {item.text2}
+                                                </div>
+                                            </div>
+                                            <div className={styles.boxItemBottom}>
+                                                <div>{item.footer}</div>
+                                                <div>{item.footer2}</div>
+                                            </div>
+                                        </div>
+                                    );
+                                })}
+                            </div>
+                            <div className={styles.daybox}>
+                                <div className={styles.dayContainer} ref={dayContainer}>
+                                    {data.map((item) => {
+                                        return (
+                                            <div
+                                                key={item}
+                                                className={clsx(styles.dayItem, styles.active)}
+                                            >
+                                                <div className={styles.dayItemText}>{item} dia</div>
+                                                <div className={styles.dayitemTextActive}>
+                                                    <img src="/continuous/s1.png" alt="" />
+                                                    <div className="flex flex-row items-end text-[#dbc6ff]">
+                                                        <span className="relative top-[1px] mt-[2px] text-[.13rem]">
+                                                            {item}
+                                                        </span>
+                                                        <span>dia</span>
+                                                    </div>
+                                                    <div>recarga</div>
+                                                    <div className="text-[#ffb400]">10000</div>
+                                                </div>
+                                            </div>
+                                        );
+                                    })}
+                                </div>
+                            </div>
+                            <div className={styles.premio}>
+                                <div className={styles.premioTitle}>
+                                    <span className={styles.premioTitleText}>
+                                        Prévia do Grande Prêmio
+                                    </span>
+                                </div>
+                                <div className={styles.premioContainer}>
+                                    <div className={styles.premioContent}>
+                                        <DayItem></DayItem>
+                                        <DayItem></DayItem>
+                                        <DayItem></DayItem>
+                                    </div>
+                                </div>
+                            </div>
+                            <div className={styles.introbox}>
+                                <div className={styles.introContainer}>
+                                    <div className={styles.introTitle}>
+                                        <span className={styles.introTitleText}>
+                                            Regras de Atividade
+                                        </span>
+                                    </div>
+                                    <div className={styles.introboxDesc}>
+                                        1. Jogadores que atendem aos requisitos podem receber o
+                                        bônus diretamente.
+                                        <br />
+                                        2. Solicite o bônus desta promoção dentro do período
+                                        promocional. Não se inscrever após o prazo limite será
+                                        considerado como desistência automática.
+                                        <br />
+                                        3. Ao participar desta promoção, você concorda em cumprir as
+                                        &quot;Regras e Termos da Promoção&quot;.
+                                    </div>
+                                    <div className="mt-[.1rem]">
+                                        <div className={clsx(styles.introItem, styles.odd)}>
+                                            <div className={styles.idx1}></div>
+                                            {cfg1.map((item) => {
+                                                return (
+                                                    <div key={item.key}>
+                                                        <img
+                                                            src={`/continuous/s${item.key}.png`}
+                                                            alt=""
+                                                            className="w-[.3rem]"
+                                                        />
+                                                        <span className="text-[.1rem]">
+                                                            {item.text}
+                                                        </span>
+                                                        <span className="text-[.1rem]">
+                                                            {item.text2}
+                                                        </span>
+                                                    </div>
+                                                );
+                                            })}
+                                        </div>
+                                        <div className={clsx(styles.introItem)}>
+                                            <div className={styles.idx1}>dia5</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                        </div>
+                                        <div className={clsx(styles.introItem, styles.odd)}>
+                                            <div className={styles.idx1}>dia5</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                            <div>2323</div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
+
+export default Page;

+ 65 - 0
src/components/CutDown/index.tsx

@@ -0,0 +1,65 @@
+"use client";
+import useCountDown from "@/hooks/useCountdown";
+
+const TimeLeft = ({
+    endTime,
+    itemBgColor = "#4c546e",
+}: {
+    endTime: number;
+    itemBgColor: string;
+}) => {
+    const [countdown, time] = useCountDown({
+        leftTime: endTime * 1000,
+    });
+
+    console.log(time);
+
+    return (
+        <div className={"flex text-[0.1389rem]"}>
+            <div className={"text-center"}>
+                <div className={"flex items-center text-[#fff]"}>
+                    <div
+                        className={
+                            `flex items-center justify-center rounded-[0.0347rem]` +
+                            " h-[0.2083rem] w-[0.2083rem]"
+                        }
+                        style={{ backgroundColor: itemBgColor }}
+                    >
+                        {`${time.days}`.padStart(2, "0")}
+                    </div>
+                    <span className={"mx-[0.0247rem]"}>:</span>
+                    <div
+                        className={
+                            `flex items-center justify-center rounded-[0.0347rem]` +
+                            " h-[0.2083rem] w-[0.2083rem]"
+                        }
+                        style={{ backgroundColor: itemBgColor }}
+                    >
+                        {`${time.hours}`.padStart(2, "0")}
+                    </div>
+                    <span className={"mx-[0.0247rem]"}>:</span>
+                    <div
+                        className={
+                            `flex items-center justify-center rounded-[0.0347rem]` +
+                            " h-[0.2083rem] w-[0.2083rem]"
+                        }
+                        style={{ backgroundColor: itemBgColor }}
+                    >
+                        {`${time.minutes}`.padStart(2, "0")}
+                    </div>
+                    <span className={"mx-[0.0247rem]"}>:</span>
+                    <div
+                        className={
+                            `flex items-center justify-center rounded-[0.0347rem]` +
+                            " h-[0.2083rem] w-[0.2083rem]"
+                        }
+                        style={{ backgroundColor: itemBgColor }}
+                    >
+                        {`${time.seconds}`.padStart(2, "0")}
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
+export default TimeLeft;

+ 1 - 1
src/components/ModalPopup/GlobalNotifyModal/index.tsx

@@ -96,7 +96,7 @@ const GlobalNotify: FC<Prop> = ({ amount, visible = false, onChange, deraction =
                             alt={""}
                             width={750}
                             className={
-                                "animate-slow-bounce absolute -top-[0.5rem] left-0 h-[3.2rem]"
+                                "absolute -top-[0.5rem] left-0 h-[3.2rem] animate-slow-bounce"
                             }
                             height={512}
                         />

+ 0 - 0
src/hooks/useDialog.ts