|
@@ -1,12 +1,15 @@
|
|
|
"use client";
|
|
|
-import { getNewVip, LevelInfoItem, RewardInfoItem } from "@/api/user";
|
|
|
+import { claimVip, getNewVip, LevelInfoItem, RewardInfoItem, RewordItem } from "@/api/user";
|
|
|
import CustomButton from "@/components/CustomButton";
|
|
|
import HeaderBack from "@/components/HeaderBack";
|
|
|
import VipProgress from "@/components/VipProgress";
|
|
|
import feedback from "@/feedback";
|
|
|
+import useCountdown from "@/hooks/useCountdown";
|
|
|
import { formatAmount } from "@/utils";
|
|
|
import { useRequest } from "ahooks";
|
|
|
+import { Toast } from "antd-mobile";
|
|
|
import clsx from "clsx";
|
|
|
+import { useTranslations } from "next-intl";
|
|
|
import React from "react";
|
|
|
import List from "./List";
|
|
|
import styles from "./page.module.scss";
|
|
@@ -18,14 +21,42 @@ export interface RewardItemData extends RewardInfoItem {
|
|
|
img?: string;
|
|
|
endTime?: number;
|
|
|
typeStr?: string;
|
|
|
+ interval?: number;
|
|
|
}
|
|
|
|
|
|
const renderType1 = [2, 3, 4];
|
|
|
|
|
|
+const TimeDown = ({
|
|
|
+ endTime,
|
|
|
+ type,
|
|
|
+ interval = 1000,
|
|
|
+}: {
|
|
|
+ endTime: number;
|
|
|
+ type?: string;
|
|
|
+ interval?: number;
|
|
|
+}) => {
|
|
|
+ const [_, time] = useCountdown({ leftTime: endTime, interval });
|
|
|
+ return (
|
|
|
+ <div className="flex items-center">
|
|
|
+ {type !== "day" && <span>{time.days > 9 ? time.days : `0${time.days}`}d</span>}
|
|
|
+ <span>{time.hours > 9 ? time.hours : `0${time.hours}`}:</span>
|
|
|
+ <span>{time.minutes > 9 ? time.minutes : `0${time.minutes}`}</span>
|
|
|
+ {type === "day" && (
|
|
|
+ <>
|
|
|
+ :<span>{time.seconds > 9 ? time.seconds : `0${time.seconds}`}</span>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ {type}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
const Page = () => {
|
|
|
const [actLevel, setActLevel] = React.useState<number>(0);
|
|
|
const [opacity, setOpacity] = React.useState<number>(0);
|
|
|
const containerRef = React.useRef<HTMLDivElement | null>(null);
|
|
|
+ const curReward = React.useRef<RewardItemData | any>(null);
|
|
|
+ const t = useTranslations();
|
|
|
|
|
|
const { data: userVip, run: runVip } = useRequest<any, any>(getNewVip, {
|
|
|
pollingErrorRetryCount: 1,
|
|
@@ -74,16 +105,19 @@ const Page = () => {
|
|
|
title: "Bônus Diária",
|
|
|
typeStr: "day",
|
|
|
img: "/vip/vip_bs_icon.webp",
|
|
|
+ interval: 1000,
|
|
|
},
|
|
|
3: {
|
|
|
title: "Bônus Semanal",
|
|
|
typeStr: "week",
|
|
|
img: "/vip/vip_bs_icon.webp",
|
|
|
+ interval: 60 * 1000,
|
|
|
},
|
|
|
4: {
|
|
|
title: "Bônus Mensal",
|
|
|
typeStr: "month",
|
|
|
img: "/vip/vip_bm_icon.webp",
|
|
|
+ interval: 60 * 1000,
|
|
|
},
|
|
|
5: {
|
|
|
title: "Auxílio de falência",
|
|
@@ -127,34 +161,158 @@ const Page = () => {
|
|
|
return result;
|
|
|
}, [vipInfo, actVipInfo]);
|
|
|
|
|
|
- const doClaim = async () => {
|
|
|
- const res = await feedback.showModal({
|
|
|
- content: (props) => {
|
|
|
- return (
|
|
|
- <div className="relative">
|
|
|
- <div>23232</div>
|
|
|
- <div onClick={() => props.doClose({ sdsds: 123123 })}>点击</div>
|
|
|
- <div></div>
|
|
|
+ const multClick = (dialogProps: any) => {
|
|
|
+ console.log(dialogProps);
|
|
|
+ };
|
|
|
+
|
|
|
+ const multRender = (dialogProps: any) => {
|
|
|
+ return (
|
|
|
+ <div className="relative">
|
|
|
+ <div className="mb-[.1rem] text-center text-[.12rem] text-[var(--textColor1)]">
|
|
|
+ <i className="iconfont icon-gantanhao text-[.14rem] text-[#ecc720]"></i> ocê
|
|
|
+ está quase lá! Recarregue{" "}
|
|
|
+ <span className="text-[#11de68]">R${curReward.current?.double_pay}</span>
|
|
|
+ (progresso:{" "}
|
|
|
+ <span className="text-[#11de68]">
|
|
|
+ R${curReward.current?.cur_pay}/R${curReward.current?.double_pay}
|
|
|
+ </span>
|
|
|
+ )para desbloquear recompensas incríveis!
|
|
|
+ </div>
|
|
|
+ <div className="relative flex justify-between rounded-[.1rem] bg-[var(--main-background)] p-[.1rem]">
|
|
|
+ <div>
|
|
|
+ <div className="font-bold">Sem upgrade e resgatar</div>
|
|
|
+ {!!curReward.current?.reward?.length &&
|
|
|
+ curReward.current?.reward.map((item: RewordItem) => {
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ key={item.coin_type}
|
|
|
+ className="mt-[.06rem] text-[.18rem] font-black text-[var(--textColor4)]"
|
|
|
+ >
|
|
|
+ R$ {formatAmount(item.amount)}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ <CustomButton
|
|
|
+ onClick={doRealClaim}
|
|
|
+ disabled={
|
|
|
+ (curReward.current?.cur_pay || 0) >=
|
|
|
+ (curReward.current?.double_pay || 0)
|
|
|
+ }
|
|
|
+ className="!min-w-[120px] !px-[12px] !py-[6px] !text-[12px]"
|
|
|
+ >
|
|
|
+ check in
|
|
|
+ </CustomButton>
|
|
|
</div>
|
|
|
- );
|
|
|
- },
|
|
|
+ <img
|
|
|
+ src="/vip/d1.webp"
|
|
|
+ className="absolute right-[.1rem] top-[50%] !h-[auto] w-[.9rem] translate-y-[-50%] transform"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className="relative mt-[.1rem] flex justify-between rounded-[.1rem] bg-[var(--main-background)] p-[.1rem]">
|
|
|
+ <div>
|
|
|
+ <div className="font-bold">Deposite e ganhe upgrade</div>
|
|
|
+ {!!curReward.current?.reward?.length &&
|
|
|
+ curReward.current?.reward.map((item: RewordItem) => {
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ key={item.coin_type}
|
|
|
+ className="mt-[.06rem] text-[.32rem] font-black text-[var(--textColor4)]"
|
|
|
+ >
|
|
|
+ {formatAmount(
|
|
|
+ (item.amount || 0) * (curReward.current?.multiple || 0)
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ <CustomButton
|
|
|
+ onClick={() => multClick(dialogProps)}
|
|
|
+ className="!min-w-[120px] !px-[12px] !py-[6px] !text-[12px]"
|
|
|
+ >
|
|
|
+ {(curReward.current?.cur_pay || 0) >=
|
|
|
+ (curReward.current?.double_pay || 0)
|
|
|
+ ? "check in"
|
|
|
+ : `R$ ${formatAmount((curReward.current?.double_pay || 0) - (curReward.current?.cur_pay || 0))} Ativa`}
|
|
|
+ </CustomButton>
|
|
|
+ </div>
|
|
|
+ <img
|
|
|
+ src="/vip/d2.webp"
|
|
|
+ className="absolute right-[.1rem] top-[50%] !h-[auto] w-[1.2rem] translate-y-[-50%] transform"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className="absolute right-[.05rem] top-[60%] translate-y-[-50%] transform">
|
|
|
+ <img src="/vip/d3.webp" className="w-[1.1rem]" alt="" />
|
|
|
+ <div
|
|
|
+ className="absolute right-[.15rem] top-[55%] translate-y-[-50%] text-[.12rem] text-[.3rem] font-black leading-[1] text-[#e8ed08]"
|
|
|
+ style={{
|
|
|
+ textShadow: `2px 0 #11de68,0 2px #11de68,-2px 0 #11de68,-2px -2px #11de68`,
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ x10
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const doClaim = async (rewardData: RewardItemData) => {
|
|
|
+ curReward.current = rewardData;
|
|
|
+ const res = await feedback.showModal({
|
|
|
+ content: multRender,
|
|
|
width: "80%",
|
|
|
useDefaultFooter: false,
|
|
|
});
|
|
|
};
|
|
|
+
|
|
|
+ const doRealClaim = async () => {
|
|
|
+ if (!curReward.current) return;
|
|
|
+ try {
|
|
|
+ const res = await claimVip({ type: curReward.current?.type });
|
|
|
+ if (res.code === 200) {
|
|
|
+ runVip();
|
|
|
+ Toast.show(t(`code.200`));
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ throw new Error(`${res?.code || 400}`);
|
|
|
+ } catch (err) {
|
|
|
+ Toast.show({
|
|
|
+ icon: "fail",
|
|
|
+ content: t(`code.${err}`),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
const getBtn = (data: RewardItemData) => {
|
|
|
if (data.status === 2) {
|
|
|
return <img src="/vip/vip_claimed_icon.webp" alt="" className="w-[80px]" />;
|
|
|
}
|
|
|
- let text = data.status === 1 ? "Unopened" : "Receber";
|
|
|
+ let text: any = data.status === 1 ? "Unopened" : "Receber";
|
|
|
+ let status: any = data.status !== 1 ? "disable2" : "primary";
|
|
|
+ if (data.renderType === 1) {
|
|
|
+ if (data?.endTime && data.endTime > 0) {
|
|
|
+ text = (
|
|
|
+ <TimeDown
|
|
|
+ endTime={data.endTime}
|
|
|
+ type={data.typeStr}
|
|
|
+ interval={data.interval || 1000}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (Date.now() > data.end_time * 1000) {
|
|
|
+ text = "Expired";
|
|
|
+ status = "disable2";
|
|
|
+ }
|
|
|
+ }
|
|
|
return (
|
|
|
<CustomButton
|
|
|
className={clsx("!py-[8px] !text-[12px]", {
|
|
|
"w-[157px]": data.renderType === 1,
|
|
|
"w-full": data.renderType === 2,
|
|
|
})}
|
|
|
- onClick={doClaim}
|
|
|
- type={data.status !== 1 ? "disable2" : "primary"}
|
|
|
+ onClick={() => doClaim(data)}
|
|
|
+ type={status}
|
|
|
>
|
|
|
{text}
|
|
|
</CustomButton>
|
|
@@ -186,6 +344,19 @@ const Page = () => {
|
|
|
<div className={styles.giftBox}>
|
|
|
{!!rewardsList?.length &&
|
|
|
rewardsList.map((item) => {
|
|
|
+ let isGray = false;
|
|
|
+
|
|
|
+ if ([5, 6].includes(item.type)) {
|
|
|
+ let hasAmount = false;
|
|
|
+ item.reward.forEach((citem) => {
|
|
|
+ if (citem.amount > 0) {
|
|
|
+ hasAmount = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!hasAmount) {
|
|
|
+ isGray = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
return (
|
|
|
<div
|
|
|
key={item.title}
|
|
@@ -196,9 +367,7 @@ const Page = () => {
|
|
|
"w-full": item.renderType === 1,
|
|
|
"col-span-2": item.renderType === 1,
|
|
|
[styles.claimed]: item.status === 2,
|
|
|
- [styles.gray]:
|
|
|
- vipInfo.vip_level <= 0 &&
|
|
|
- [5, 6].includes(item.type),
|
|
|
+ [styles.gray]: isGray,
|
|
|
}
|
|
|
)}
|
|
|
>
|