|
@@ -0,0 +1,223 @@
|
|
|
+/* eslint-disable @next/next/no-img-element */
|
|
|
+'use client'
|
|
|
+import { FC, forwardRef, memo, useImperativeHandle, useRef, useState } from "react"
|
|
|
+import { Mask } from "antd-mobile"
|
|
|
+import { useRouter } from "@/i18n/routing";
|
|
|
+import styles from './style.module.scss'
|
|
|
+
|
|
|
+export interface SignInModalProps {
|
|
|
+ onClose: () => void;
|
|
|
+ onOpen: () => void
|
|
|
+}
|
|
|
+interface BoxParams {
|
|
|
+ startDays?: number;
|
|
|
+ num: number;
|
|
|
+ type?: 'page' | 'modal';
|
|
|
+}
|
|
|
+interface BoxList {
|
|
|
+ handleOpening: (index: number) => void
|
|
|
+}
|
|
|
+export const BoxListCom = forwardRef<BoxList, BoxParams>(function BoxListCom({ startDays = 1, num, type = 'modal' }: BoxParams, ref) {
|
|
|
+ const handleOpening = (index: number) => {
|
|
|
+ const box: any = document.getElementById(`box${index}`)
|
|
|
+ box.src = '/sign/box/box-open.png'
|
|
|
+ const img = document.getElementById(`opened${index}`)
|
|
|
+ img ? img.style.visibility = 'visible' : null
|
|
|
+ }
|
|
|
+ useImperativeHandle(ref, (): BoxList => {
|
|
|
+ return {
|
|
|
+ handleOpening
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <div className={`w-[100%] ${type === 'page' ? styles.page : styles.modal}`}>
|
|
|
+ <div className="flex flex-wrap w-[100%] h-[100%] justify-start">
|
|
|
+ {Array.from({ length: num }).map((item, index) => {
|
|
|
+ return (
|
|
|
+ <div className="h-[100%] w-[20%]" key={index}>
|
|
|
+ <div className="h-[100%] w-[100%]">
|
|
|
+ <div className={`relative text-center ${styles.text} text-[white]`}>
|
|
|
+ <p>Day{startDays + index}</p>
|
|
|
+ </div>
|
|
|
+ <div className={`relative ${styles.box} w-[100%]`} onClick={(e) => handleOpening(startDays + index)}>
|
|
|
+ <img
|
|
|
+ id={'box' + (startDays + index)}
|
|
|
+ src={index >= 5 ? '/sign/box_pay/gift.png' : '/sign/box/box.png'}
|
|
|
+ className={"h-[100%] z-50 mx-[auto]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <div className="flex justify-center">
|
|
|
+ <img
|
|
|
+ id={'opened' + (startDays + index)}
|
|
|
+ src="/sign/opened.png"
|
|
|
+ className={"absolute h-[0.34rem] z-50 bottom-[0.035rem] invisible"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ {
|
|
|
+ index >= 5 ? <div className="h-[30%] absolute w-[90%] bottom-0 bg-[black] rounded mx-auto left-0 right-0 border-[0.02rem] border-[green]">
|
|
|
+ <p className={`${styles.green} text-[green] font-bold text-center`}>Extra +50R</p>
|
|
|
+ </div> : null
|
|
|
+ }
|
|
|
+ </div>
|
|
|
+ {
|
|
|
+ index >= 5 ? <div className={`${styles.lock} relative text-center text-[yellow] font-bold flex justify-center mt-[0.05rem]`}>
|
|
|
+ <img
|
|
|
+ id={'opened' + (startDays + index)}
|
|
|
+ src="/sign/lock.png"
|
|
|
+ className={"h-[100%] block"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <span className="block">+5R</span>
|
|
|
+ </div> : null
|
|
|
+ }
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+})
|
|
|
+
|
|
|
+interface PayProps {
|
|
|
+ type?: 'page' | 'modal'
|
|
|
+}
|
|
|
+export const PayBoxList: FC<PayProps> = ({ type = 'modal' }) => {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <div className="flex justify-center">
|
|
|
+ {Array.from({ length: 4 }).map((item, index) => {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <div className={`relative h-[100%] ${type === 'page' ? styles.payPage : styles.payModal}`}>
|
|
|
+ <div className="relative h-[0.89rem] flex justify-center font-bold">
|
|
|
+ <span className="absolute z-50 top-[0.005rem] text-[white] leading-[]">5R</span>
|
|
|
+ <img
|
|
|
+ src="/sign/box_pay/bg.png"
|
|
|
+ className={"h-[100%] z-10"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="/sign/box_pay/bg2.png"
|
|
|
+ className={"absolute h-[0.355rem] z-30 bottom-0"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="/sign/box_pay/gift.png"
|
|
|
+ className={"absolute h-[0.505rem] z-20 top-[0.18rem]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ id={'lock' + index}
|
|
|
+ src="/sign/box_pay/lock.png"
|
|
|
+ className={"absolute h-[0.315rem] z-40 bottom-[0.17rem]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ id={'opened' + index}
|
|
|
+ src="/sign/opened.png"
|
|
|
+ className={"absolute h-[0.34rem] z-40 bottom-[0.3rem]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <span className="absolute z-50 bottom-[0.005rem] text-[white]">50R</span>
|
|
|
+ </div>
|
|
|
+ <div className={`${styles.text} text-center font-bold text-[white]`}>
|
|
|
+ <span>Day{index === 3 ? 10 + index * 5 + 5 : 10 + index * 5}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const SignInModal = forwardRef(function SignInModal(props, ref) {
|
|
|
+ const [visible, setVisible] = useState(false)
|
|
|
+
|
|
|
+ const router = useRouter()
|
|
|
+
|
|
|
+ const boxRef = useRef(null)
|
|
|
+
|
|
|
+ useImperativeHandle(ref, () => {
|
|
|
+ return {
|
|
|
+ onClose: () => setVisible(false),
|
|
|
+ onOpen: () => setVisible(true)
|
|
|
+ };
|
|
|
+ })
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Mask visible={visible} destroyOnClose={true} onMaskClick={() => setVisible(false)}>
|
|
|
+ <div
|
|
|
+ className={"absolute right-[0.2083rem] top-[18%] z-50"}
|
|
|
+ onClick={() => setVisible(false)}
|
|
|
+ >
|
|
|
+ <span className={"iconfont icon-guanbi"}></span>
|
|
|
+ </div>
|
|
|
+ <div className="absolute top-[5%] w-[100%]">
|
|
|
+ <div className={"relative w-[100%] h-[6.25rem]"}>
|
|
|
+ <div className={'h-[100%]'}>
|
|
|
+ <div className="absolute h-[100%] w-[100%] overflow-hidden flex justify-center">
|
|
|
+ <img
|
|
|
+ src="/sign/light2.png"
|
|
|
+ className={"absolute h-[7.5rem] max-w-[none] top-[-1.215rem]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src="/sign/light.png"
|
|
|
+ className={"absolute h-[5.07rem] max-w-[none]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ {/* 主题背景图 */}
|
|
|
+ <div className="relative flex justify-center h-[3rem] w-[100%]">
|
|
|
+ <img
|
|
|
+ src="/sign/theme.png"
|
|
|
+ className={"absolute h-[100%]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className="absolute h-[3.95rem] top-[30%] w-[100%]">
|
|
|
+ <div className="flex justify-center h-[100%]">
|
|
|
+ {/* 宽度自动填充适应活动背景图宽度 */}
|
|
|
+ <div className="relative h-[100%]">
|
|
|
+ <img
|
|
|
+ src="/sign/bg2.png"
|
|
|
+ className={"h-[100%]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ {/* 右上角倒计时 */}
|
|
|
+ <div className="absolute w-[20%] h-[0.3rem] right-[0.15rem] top-0 z-50 text-center text-[0.1rem] font-bold text-[white]">
|
|
|
+ <p className={"h-[0.15rem]"}>CountDown</p>
|
|
|
+ <p className={"text-[yellow] h-[0.15rem]"}>Day 20</p>
|
|
|
+ </div>
|
|
|
+ {/* 签到body */}
|
|
|
+ <div className="absolute top-0 left-0 w-[100%]">
|
|
|
+ <div className="relative w-[100%] mt-[0.51rem]">
|
|
|
+ <BoxListCom num={15} ref={boxRef} />
|
|
|
+ <div className="flex justify-center h-[0.62rem] mt-[0.25rem]" onClick={() => { router.push('/signIn') }}>
|
|
|
+ <img
|
|
|
+ src="/sign/button_signed.png"
|
|
|
+ className={"h-[100%]"}
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <span className="absolute leading-[0.375rem] text-[0.16rem] font-bold">Sign-in</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Mask>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+})
|
|
|
+
|
|
|
+export default memo(SignInModal)
|