From a49cecc2db04ebab3839f260b90e08be48d88531 Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Tue, 23 Jan 2024 15:32:24 +0800 Subject: [PATCH 1/7] en: explore query --- src/router/index.js | 3 +- src/state/explore/challenge.js | 11 +++++++ src/views/Explore/index.jsx | 56 ++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/state/explore/challenge.js create mode 100644 src/views/Explore/index.jsx diff --git a/src/router/index.js b/src/router/index.js index 4a01a932..ab236bf1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,5 +1,6 @@ import Index from "@/views/Index" import Explore from "@/views/Explore" +import ExploreNew from "@/views/Explore/index" import NewPublish from "@/views/Publish/index" import Question from "@/views/Question/index"; import Challenge from "@/views/Challenge/index"; @@ -21,7 +22,7 @@ const routes = [ }, { path: "/challenges", - element: , + element: , }, { path: "/collection/:id", diff --git a/src/state/explore/challenge.js b/src/state/explore/challenge.js new file mode 100644 index 00000000..5598b796 --- /dev/null +++ b/src/state/explore/challenge.js @@ -0,0 +1,11 @@ +import { getQuests } from "@/request/api/public"; + +export const getChallengeList = async (pageParam) => { + try { + const res = await getQuests({pageSize: 10, page: pageParam}); + return res.data?.list || [] + } catch (error) { + console.log(error); + return null; + } +}; diff --git a/src/views/Explore/index.jsx b/src/views/Explore/index.jsx new file mode 100644 index 00000000..263f62f6 --- /dev/null +++ b/src/views/Explore/index.jsx @@ -0,0 +1,56 @@ +import { Spin } from "antd"; +import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import InfiniteScroll from "react-infinite-scroll-component"; +import PageLoader from "@/components/Loader/PageLoader"; +import ChallengeItem from "@/components/User/ChallengeItem"; +import ChallengeItems from "@/components/User/ChallengeItems"; +import { getChallengeList } from "@/state/explore/challenge"; + +export default function Explore(params) { + const navigateTo = useNavigate(); + const { t } = useTranslation(["explore", "translation"]); + const { data, fetchNextPage, hasNextPage, status } = useInfiniteQuery({ + queryKey: ["challenges"], + queryFn: ({ pageParam }) => getChallengeList(pageParam), + initialPageParam: 1, + getNextPageParam: (lastPage, allPages) => { + return lastPage.length > 0 ? allPages.length + 1 : undefined; + }, + }); + + return ( +
+
+

{t("title")}

+ } + > + {status === "pending" ? ( + + ) : ( + data.pages + .flat() + .map((item) => + item.style === 1 ? ( + + ) : ( + + navigateTo(`/collection/${id}`) + } + /> + ) + ) + )} + +
+ ); +} From 00af15bf3a76289c0b49d325967fa7295bf13003 Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Fri, 26 Jan 2024 10:31:37 +0800 Subject: [PATCH 2/7] en: stash --- .../styles/mobile/view-style/explore.scss | 2 +- src/assets/styles/view-style/explore.scss | 2 +- .../ChallengeItem/ChallengeItemIcons.jsx | 57 +++++++++++++++ src/components/ChallengeItem/index.jsx | 69 +++++++++++++++++++ .../Explore/components/ChallengeList.jsx | 9 +++ src/views/Explore/index.jsx | 3 + src/views/Explore/style/index.scss | 44 ++++++++++++ src/views/Explore/style/mobile.scss | 41 +++++++++++ 8 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 src/components/ChallengeItem/ChallengeItemIcons.jsx create mode 100644 src/components/ChallengeItem/index.jsx create mode 100644 src/views/Explore/components/ChallengeList.jsx create mode 100644 src/views/Explore/style/index.scss create mode 100644 src/views/Explore/style/mobile.scss diff --git a/src/assets/styles/mobile/view-style/explore.scss b/src/assets/styles/mobile/view-style/explore.scss index d0096d88..0018ba24 100644 --- a/src/assets/styles/mobile/view-style/explore.scss +++ b/src/assets/styles/mobile/view-style/explore.scss @@ -17,7 +17,6 @@ } // title h3 { - margin-bottom: 1.25rem; font-size: 1.125rem; font-weight: 600; line-height: 1.5625rem; @@ -34,6 +33,7 @@ // challenges .challenges { padding: 0; + padding-top: 1.25rem; padding-bottom: 9.375rem; gap: .625rem; } diff --git a/src/assets/styles/view-style/explore.scss b/src/assets/styles/view-style/explore.scss index 9b202538..70163248 100644 --- a/src/assets/styles/view-style/explore.scss +++ b/src/assets/styles/view-style/explore.scss @@ -18,7 +18,6 @@ } // title h3 { - margin-bottom: 80px; font-size: 32px; font-weight: 600; line-height: 38px; @@ -35,6 +34,7 @@ // challenges .challenges { padding: 0; + padding-top: 80px; padding-bottom: 150px; display: flex; flex-wrap: wrap; diff --git a/src/components/ChallengeItem/ChallengeItemIcons.jsx b/src/components/ChallengeItem/ChallengeItemIcons.jsx new file mode 100644 index 00000000..a02d230a --- /dev/null +++ b/src/components/ChallengeItem/ChallengeItemIcons.jsx @@ -0,0 +1,57 @@ +import { Tooltip } from "antd"; + + +/* +hasNft: Boolean +hasVc: Boolean +*/ +export default function ChallengeItemIcons({ + hasNft, + hasVc +}) { + + function name(params) { + + } + + return ( +
+ { + hasNft && + <> + {/* 链 */} +
event.stopPropagation()}> + +
+ {/* opensea */} +
+ +
+ + } + { + hasVc && + // zk + +
{ + event.stopPropagation(); + showZk({address: profile.address, token_id: info.tokenId}) + }}> + +
+
+ } +
+ ) +} \ No newline at end of file diff --git a/src/components/ChallengeItem/index.jsx b/src/components/ChallengeItem/index.jsx new file mode 100644 index 00000000..b21c99e0 --- /dev/null +++ b/src/components/ChallengeItem/index.jsx @@ -0,0 +1,69 @@ +import { LazyLoadImage } from "react-lazy-load-image-component"; +import ChallengeItemIcons from "./ChallengeItemIcons"; + +/* +info: { + img, + title, + description, + difficulty, + time +} +hasNft: Boolean +hasVc: Boolean +*/ + +export default function ChallengeItem({ + info, + hasNft, + hasVc +}) { + + + + return ( +
+
+
+ +
+ +
+
+
+

+ {info.title} +

+

+ {info.description} +

+
+
+
+ { + info.metadata?.attributes?.difficulty !== null && + <> + {t("translation:diff")} +
+ { + arr.map((e,i) => { + if (i >= info.metadata?.attributes?.difficulty+1) { + return + }else{ + return + } + }) + } +
+ + } +
+
+ + {info?.time} +
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/views/Explore/components/ChallengeList.jsx b/src/views/Explore/components/ChallengeList.jsx new file mode 100644 index 00000000..d724fe63 --- /dev/null +++ b/src/views/Explore/components/ChallengeList.jsx @@ -0,0 +1,9 @@ + + + +export default function ChallengeList(params) { + + + + +} \ No newline at end of file diff --git a/src/views/Explore/index.jsx b/src/views/Explore/index.jsx index 263f62f6..5a2c0750 100644 --- a/src/views/Explore/index.jsx +++ b/src/views/Explore/index.jsx @@ -7,6 +7,9 @@ import PageLoader from "@/components/Loader/PageLoader"; import ChallengeItem from "@/components/User/ChallengeItem"; import ChallengeItems from "@/components/User/ChallengeItems"; import { getChallengeList } from "@/state/explore/challenge"; +import "./style/index.scss"; +import "./mobile.scss"; + export default function Explore(params) { const navigateTo = useNavigate(); diff --git a/src/views/Explore/style/index.scss b/src/views/Explore/style/index.scss new file mode 100644 index 00000000..70163248 --- /dev/null +++ b/src/views/Explore/style/index.scss @@ -0,0 +1,44 @@ +.Explore { + width: 1440px; + padding-top: 170px; + margin: 0 auto; + font-family: Source; + position: relative; + .back{ + position: absolute; + display: flex; + align-items: center; + top: 95px; + font-size: 20px; + cursor: pointer; + .anticon{ + margin-right: 11px; + font-size: 30px; + } + } + // title + h3 { + font-size: 32px; + font-weight: 600; + line-height: 38px; + } + // depass + .depass { + margin-top: 63px; + h4 { + font-size: 20px; + font-weight: 800; + color: #3d3d3d; + } + } + // challenges + .challenges { + padding: 0; + padding-top: 80px; + padding-bottom: 150px; + display: flex; + flex-wrap: wrap; + gap: 36px 40px; + } +} + \ No newline at end of file diff --git a/src/views/Explore/style/mobile.scss b/src/views/Explore/style/mobile.scss new file mode 100644 index 00000000..0018ba24 --- /dev/null +++ b/src/views/Explore/style/mobile.scss @@ -0,0 +1,41 @@ +.Mobile{ + .Explore { + width: 21.875rem; + min-height: 100vh; + padding-top: 5.625rem; + .back{ + position: absolute; + display: flex; + align-items: center; + top: 4.3375rem; + font-size: .75rem; + cursor: pointer; + .anticon{ + margin-right: .3125rem; + font-size: 1rem; + } + } + // title + h3 { + font-size: 1.125rem; + font-weight: 600; + line-height: 1.5625rem; + } + // depass + .depass { + margin-top: 3.9375rem; + h4 { + font-size: 1.25rem; + font-weight: 800; + color: #3d3d3d; + } + } + // challenges + .challenges { + padding: 0; + padding-top: 1.25rem; + padding-bottom: 9.375rem; + gap: .625rem; + } + } +} \ No newline at end of file From cf89e13558bc5cc9d728fbe03d3d7c6634c1ffce Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Fri, 26 Jan 2024 16:32:40 +0800 Subject: [PATCH 3/7] =?UTF-8?q?en:=20=E8=B0=83=E6=95=B4challengeItem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChallengeItem/ChallengeItemIcons.jsx | 112 ++++++++---- .../ChallengeItem/ChallengeItemImg.jsx | 23 +++ .../ChallengeItem/ChallengeItemStatus.jsx | 32 ++++ src/components/ChallengeItem/index.jsx | 171 +++++++++++++----- src/views/Explore/index.jsx | 6 +- 5 files changed, 262 insertions(+), 82 deletions(-) create mode 100644 src/components/ChallengeItem/ChallengeItemImg.jsx create mode 100644 src/components/ChallengeItem/ChallengeItemStatus.jsx diff --git a/src/components/ChallengeItem/ChallengeItemIcons.jsx b/src/components/ChallengeItem/ChallengeItemIcons.jsx index a02d230a..dd900147 100644 --- a/src/components/ChallengeItem/ChallengeItemIcons.jsx +++ b/src/components/ChallengeItem/ChallengeItemIcons.jsx @@ -1,57 +1,101 @@ import { Tooltip } from "antd"; - +import { + CONTRACT_ADDR_1155, + CONTRACT_ADDR_1155_TESTNET, + CONTRACT_ADDR_721, + CONTRACT_ADDR_721_TESTNET, +} from "@/config"; +import { useAddress } from "@/hooks/useAddress"; +import { constans } from "@/utils/constans"; /* hasNft: Boolean hasVc: Boolean +info: { + nft_address, + badge_chain_id, + badge_token_id, + tokenId +} */ -export default function ChallengeItemIcons({ - hasNft, - hasVc -}) { - function name(params) { - +export default function ChallengeItemIcons({ hasNft, hasVc, info }) { + const isDev = process.env.REACT_APP_IS_DEV; + const contract721 = isDev ? CONTRACT_ADDR_721_TESTNET : CONTRACT_ADDR_721; + const contract1155 = isDev + ? CONTRACT_ADDR_1155_TESTNET + : CONTRACT_ADDR_1155; + const { openseaLink, openseaSolanaLink } = constans(); + const { walletType } = useAddress(); + + function toOpensea(event) { + event.stopPropagation(); + const { nft_address, badge_chain_id, badge_token_id, tokenId } = info; + let evmLink = openseaLink; + const solanaLink = `${openseaSolanaLink}/${nft_address}`; + if (!badge_token_id) { + evmLink = `${evmLink}/${isDev ? "mumbai" : "matic"}/${contract1155.Badge}/${tokenId}`; + } else { + const chainAddr = contract721[badge_chain_id]; + evmLink = `${evmLink}/${chainAddr.opensea}/${chainAddr.Badge}/${badge_token_id}`; + } + window.open(walletType === "evm" ? evmLink : solanaLink, "_blank"); } - + return ( -
- { - hasNft && +
+ {hasNft && ( <> {/* 链 */} -
event.stopPropagation()}> - +
event.stopPropagation()} + > +
{/* opensea */} -
- +
+
- } - { - hasVc && + )} + {hasVc && ( // zk -
{ - event.stopPropagation(); - showZk({address: profile.address, token_id: info.tokenId}) - }}> - +
{ + event.stopPropagation(); + // showZk({address: profile.address, token_id: info.tokenId}) + }} + > +
- } + )}
- ) -} \ No newline at end of file + ); +} diff --git a/src/components/ChallengeItem/ChallengeItemImg.jsx b/src/components/ChallengeItem/ChallengeItemImg.jsx new file mode 100644 index 00000000..459d2216 --- /dev/null +++ b/src/components/ChallengeItem/ChallengeItemImg.jsx @@ -0,0 +1,23 @@ +import { LazyLoadImage } from "react-lazy-load-image-component"; +import ChallengeItemIcons from "./ChallengeItemIcons"; + + + +export default function ChallengeItemImg({img, claimedInfo}) { + + return ( +
+
+ +
+ { + claimedInfo && + + } +
+ ) +} \ No newline at end of file diff --git a/src/components/ChallengeItem/ChallengeItemStatus.jsx b/src/components/ChallengeItem/ChallengeItemStatus.jsx new file mode 100644 index 00000000..13f9240d --- /dev/null +++ b/src/components/ChallengeItem/ChallengeItemStatus.jsx @@ -0,0 +1,32 @@ +import { useTranslation } from "react-i18next"; + +/** + * + * @param {Boolean} claimable - 可领取状态 + * @param {Boolean} claimed - 已领取状态 + * @param {Boolean} review - 待打分状态 + * @returns + */ + +export default function ChallengeItemStatus({ + claimable, + claimed, + review, +}) { + const { t } = useTranslation(["profile"]); + + return ( + <> + {claimable &&
{t("claimble")}
} + {claimed &&
{t("explore:pass")}
} + {review && ( +
+ {t("explore:review")} +
+ )} + + ); +} diff --git a/src/components/ChallengeItem/index.jsx b/src/components/ChallengeItem/index.jsx index b21c99e0..1cf8b890 100644 --- a/src/components/ChallengeItem/index.jsx +++ b/src/components/ChallengeItem/index.jsx @@ -1,69 +1,150 @@ +import { useTranslation } from "react-i18next"; +import { ClockCircleFilled, EditOutlined } from "@ant-design/icons"; import { LazyLoadImage } from "react-lazy-load-image-component"; import ChallengeItemIcons from "./ChallengeItemIcons"; +import ChallengeItemStatus from "./ChallengeItemStatus"; +import { message } from "antd"; +import { useEffect, useState } from "react"; +import { convertTime } from "@/utils/convert"; +import { constans } from "@/utils/constans"; +import { useNavigate } from "react-router-dom"; +import ChallengeItemImg from "./ChallengeItemImg"; /* +isMe: Boolean, info: { - img, - title, - description, - difficulty, - time + tokenId: String, + img: String, + title: String, + description: String, + difficulty: Number, + time: timestamp, + claimable: Boolean, + claimed: Boolean, + editable: Boolean, + has_claim: Boolean, + review: Boolean, +} +claimedInfo: { + hasNft: Boolean, + hasVc: Boolean, + info: { + nft_address, + badge_chain_id, + badge_token_id, + } } -hasNft: Boolean -hasVc: Boolean */ -export default function ChallengeItem({ - info, - hasNft, - hasVc -}) { - +export default function ChallengeItem({ info, claimedInfo }) { + const navigateTo = useNavigate(); + const { t } = useTranslation(["profile", "explore"]); + const { ipfsPath, defaultImg, openseaLink, openseaSolanaLink } = constans(); + let [itemInfo, setItemInfo] = useState(); + + function toQuest() { + if (itemInfo?.claimable || itemInfo?.claimed || itemInfo?.review) { + // 个人查看完成的挑战 + navigateTo(`/claim/${info.uuid}`); + } else { + navigateTo(`/quests/${info.uuid}`); + } + } + + function editChallenge(event) { + event.stopPropagation(); + // 已有人claim,终止 + if (itemInfo?.has_claim) { + message.warning(t("edit.error")); + return; + } + window.open(`/publish?${itemInfo.tokenId}`, "_blank"); + } + + function getTimeDiff(time) { + const { type, time: num } = convertTime(time, "all"); + return t(`translation:${type}`, { time: Math.round(num) }); + } + + function init() { + const img = + info.metadata.image.indexOf("https://") !== -1 + ? info.metadata.image + : info.metadata.image.split("//")[1] + ? `${ipfsPath}/${info.metadata.image.split("//")[1]}` + : info.metadata?.properties?.media.split("//")[1] + ? `${ipfsPath}/${ + info.metadata?.properties?.media.split("//")[1] + }` + : defaultImg; + itemInfo = { + ...info, + difficulty: info.metadata?.attributes?.difficulty, + time: info.quest_data?.estimateTime + ? getTimeDiff(info.quest_data?.estimateTime) + : null, + review: info?.open_quest_review_status === 1, + img, + }; + setItemInfo({ ...itemInfo }); + } + + useEffect(() => { + init(); + }, []); return ( -
-
-
- +
+ {/* 挑战状态 */} + + {/* 编辑挑战 */} + {itemInfo?.editable && ( +
+
- -
+ )} + {/* 挑战Img */} + + {/* 挑战详情 */}
-

- {info.title} -

+

{itemInfo?.title}

- {info.description} + {itemInfo?.description}

-
- { - info.metadata?.attributes?.difficulty !== null && - <> + {itemInfo?.difficulty !== null && ( +
{t("translation:diff")}
- { - arr.map((e,i) => { - if (i >= info.metadata?.attributes?.difficulty+1) { - return - }else{ - return - } - }) - } + {new Array(3).fill(0).map((e, i) => ( + = itemInfo?.difficulty + 1 + ? "line" + : "full" + }.png`)} + /> + ))}
- - } -
-
- - {info?.time} -
+
+ )} + {itemInfo?.time && ( +
+ + {itemInfo?.time} +
+ )}
- ) -} \ No newline at end of file + ); +} diff --git a/src/views/Explore/index.jsx b/src/views/Explore/index.jsx index 5a2c0750..c01c7acb 100644 --- a/src/views/Explore/index.jsx +++ b/src/views/Explore/index.jsx @@ -4,11 +4,11 @@ import { useTranslation } from "react-i18next"; import { useInfiniteQuery } from "@tanstack/react-query"; import InfiniteScroll from "react-infinite-scroll-component"; import PageLoader from "@/components/Loader/PageLoader"; -import ChallengeItem from "@/components/User/ChallengeItem"; +import ChallengeItem from "@/components/ChallengeItem"; import ChallengeItems from "@/components/User/ChallengeItems"; import { getChallengeList } from "@/state/explore/challenge"; import "./style/index.scss"; -import "./mobile.scss"; +import "./style/mobile.scss"; export default function Explore(params) { @@ -41,7 +41,7 @@ export default function Explore(params) { .flat() .map((item) => item.style === 1 ? ( - + ) : ( Date: Tue, 30 Jan 2024 09:51:35 +0800 Subject: [PATCH 4/7] =?UTF-8?q?en:=20=E6=8C=91=E6=88=98=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChallengeItem/ChallengeItemImg.jsx | 22 +++- .../ChallengeItem/ChallengeItems.jsx | 117 ++++++++++++++++++ src/components/ChallengeItem/index.jsx | 18 +-- src/components/User/ChallengeItem.js | 10 +- src/state/explore/challenge.js | 28 ++++- src/views/Explore/index.jsx | 22 +++- 6 files changed, 191 insertions(+), 26 deletions(-) create mode 100644 src/components/ChallengeItem/ChallengeItems.jsx diff --git a/src/components/ChallengeItem/ChallengeItemImg.jsx b/src/components/ChallengeItem/ChallengeItemImg.jsx index 459d2216..572da0e1 100644 --- a/src/components/ChallengeItem/ChallengeItemImg.jsx +++ b/src/components/ChallengeItem/ChallengeItemImg.jsx @@ -3,13 +3,33 @@ import ChallengeItemIcons from "./ChallengeItemIcons"; -export default function ChallengeItemImg({img, claimedInfo}) { +export default function ChallengeItemImg({img, claimedInfo, questNum}) { return (
+ {/* 阴影文本: ERC-721展示 */} + { + claimedInfo?.info.version === "2" && !claimedInfo?.hasNft && +
+

{claimedInfo?.info.title}

+
+ } + {/* 挑战集合信息 */} + { + questNum && +
+
+ +
+
+ +

{questNum}

+
+
+ } { claimedInfo && getCollection(Number(info.id)), + }); + + const { ipfsPath, imgPath } = constans(); + const { t } = useTranslation(["profile", "explore"]); + let [timestamp, setTimeStamp] = useState(); + let [collectionInfo, setCollectionInfo] = useState({ + questNum: 0, + claimable: false, + claimed: false, + }); + + function getTimeDiff(time) { + const { type, time: num } = convertTime(time, "all") + return t(`translation:${type}`, {time: Math.round(num)}) + } + + async function init() { + try { + let tokenId = data.collection.tokenId; + collectionInfo.questNum = data.list.length; + timestamp = info.quest_data?.estimateTime + ? getTimeDiff(info?.estimateTime) + : null; + setTimeStamp(timestamp); + if (tokenId && tokenId !== "0") { + collectionInfo.claimable = !list.some((e) => !e.claimed); + collectionInfo.claimed = data.status; + } + setCollectionInfo({ ...collectionInfo }); + } catch (error) { + console.log(error); + } + } + + useUpdateEffect(() => { + data && init(); + }, [data]); + + return ( +
goCollection(info.id)}> + {/* 挑战状态 */} + + +
+
+

{info.title}

+

{info.description}

+
+
+ {info.author_info.avatar && ( +
+ +
+ )} +

{info.author_info.nickname}

+
+
+
+ {info?.difficulty !== null && ( + <> + {t("translation:diff")} +
+ {new Array(3).fill(0).map((e, i) => ( + = info?.difficulty + 1 + ? "line" + : "full" + }.png`)} + /> + ))} +
+ + )} +
+
+ {info?.estimate_time !== null && ( + <> + + {timestamp} + + )} +
+
+
+
+ ); +} diff --git a/src/components/ChallengeItem/index.jsx b/src/components/ChallengeItem/index.jsx index 1cf8b890..62fa0bc9 100644 --- a/src/components/ChallengeItem/index.jsx +++ b/src/components/ChallengeItem/index.jsx @@ -1,13 +1,11 @@ +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { ClockCircleFilled, EditOutlined } from "@ant-design/icons"; -import { LazyLoadImage } from "react-lazy-load-image-component"; -import ChallengeItemIcons from "./ChallengeItemIcons"; -import ChallengeItemStatus from "./ChallengeItemStatus"; import { message } from "antd"; -import { useEffect, useState } from "react"; -import { convertTime } from "@/utils/convert"; +import { ClockCircleFilled, EditOutlined } from "@ant-design/icons"; import { constans } from "@/utils/constans"; -import { useNavigate } from "react-router-dom"; +import { convertTime } from "@/utils/convert"; +import ChallengeItemStatus from "./ChallengeItemStatus"; import ChallengeItemImg from "./ChallengeItemImg"; /* @@ -29,6 +27,8 @@ claimedInfo: { hasNft: Boolean, hasVc: Boolean, info: { + version, + title, nft_address, badge_chain_id, badge_token_id, @@ -66,7 +66,7 @@ export default function ChallengeItem({ info, claimedInfo }) { return t(`translation:${type}`, { time: Math.round(num) }); } - function init() { + function initInfo() { const img = info.metadata.image.indexOf("https://") !== -1 ? info.metadata.image @@ -91,7 +91,7 @@ export default function ChallengeItem({ info, claimedInfo }) { } useEffect(() => { - init(); + initInfo(); }, []); return ( diff --git a/src/components/User/ChallengeItem.js b/src/components/User/ChallengeItem.js index a72198c2..8afbabd9 100644 --- a/src/components/User/ChallengeItem.js +++ b/src/components/User/ChallengeItem.js @@ -20,7 +20,6 @@ export default function ChallengeItem(props) { const navigateTo = useNavigate(); const [messageApi, contextHolder] = message.useMessage(); const { ipfsPath, defaultImg, openseaLink, openseaSolanaLink } = constans(profile?.checkType); - const arr = [0, 1, 2]; const toQuest = () => { @@ -95,12 +94,7 @@ export default function ChallengeItem(props) { function getTimeDiff(time) { const { type, time: num } = convertTime(time, "all") - - return ( - <> - {t(`translation:${type}`, {time: Math.round(num)})} - - ) + return t(`translation:${type}`, {time: Math.round(num)}) } return ( @@ -221,7 +215,7 @@ export default function ChallengeItem(props) { {t("translation:diff")}
{ - arr.map((e,i) => { + new Array(3).map((e,i) => { if (i >= info.metadata?.attributes?.difficulty+1) { return }else{ diff --git a/src/state/explore/challenge.js b/src/state/explore/challenge.js index 5598b796..7ab65a61 100644 --- a/src/state/explore/challenge.js +++ b/src/state/explore/challenge.js @@ -1,9 +1,31 @@ -import { getQuests } from "@/request/api/public"; +import { getQuests, hasClaimed } from "@/request/api/public"; +import { getCollectionQuest } from "@/request/api/quests"; export const getChallengeList = async (pageParam) => { try { - const res = await getQuests({pageSize: 10, page: pageParam}); - return res.data?.list || [] + const res = await getQuests({ pageSize: 10, page: pageParam }); + return res.data?.list || []; + } catch (error) { + console.log(error); + return null; + } +}; + +export const getCollection = async (pageParam) => { + try { + const res = await getCollectionQuest({ id: pageParam }); + const tokenId = res.data.collection.tokenId; + let status = false; + if (tokenId && tokenId !== "0") { + await hasClaimed({ id: tokenId }).then((res) => { + status = res.data?.status === 2; + }); + } + return { + list: res.data.list || [], + collection: res.data.collection, + status, + }; } catch (error) { console.log(error); return null; diff --git a/src/views/Explore/index.jsx b/src/views/Explore/index.jsx index c01c7acb..902f8323 100644 --- a/src/views/Explore/index.jsx +++ b/src/views/Explore/index.jsx @@ -5,7 +5,7 @@ import { useInfiniteQuery } from "@tanstack/react-query"; import InfiniteScroll from "react-infinite-scroll-component"; import PageLoader from "@/components/Loader/PageLoader"; import ChallengeItem from "@/components/ChallengeItem"; -import ChallengeItems from "@/components/User/ChallengeItems"; +import ChallengeItems from "@/components/ChallengeItem/ChallengeItems"; import { getChallengeList } from "@/state/explore/challenge"; import "./style/index.scss"; import "./style/mobile.scss"; @@ -41,14 +41,26 @@ export default function Explore(params) { .flat() .map((item) => item.style === 1 ? ( - + ) : ( - navigateTo(`/collection/${id}`) - } + goCollection={(id) => navigateTo(`/collection/${id}`)} /> ) ) From dfbe3cd49b3ed9056dc699ffdc70e90f98522642 Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Sun, 18 Feb 2024 15:32:12 +0800 Subject: [PATCH 5/7] en: update style --- .../mobile/component-style/user/challengeItem.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/assets/styles/mobile/component-style/user/challengeItem.scss b/src/assets/styles/mobile/component-style/user/challengeItem.scss index b36aaf2f..db43202c 100644 --- a/src/assets/styles/mobile/component-style/user/challengeItem.scss +++ b/src/assets/styles/mobile/component-style/user/challengeItem.scss @@ -6,6 +6,16 @@ border-width: .0625rem; border-radius: .625rem; transition: none; + .edit{ + width: 1.75rem; + height: 1.75rem; + border-radius: .3125rem; + right: .3125rem; + top: .3125rem; + font-size: .625rem; + z-index: 1; + background-color: #fff; + } .item-claimed, .item-claimable{ width: 2.8125rem; height: 1.125rem; From 8426b4b32663bcd86123c7c96c78ec1b99950d17 Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Thu, 22 Feb 2024 10:02:06 +0800 Subject: [PATCH 6/7] en: update router config --- src/router/index.js | 9 ++- src/views/Explore.js | 129 ------------------------------------------- 2 files changed, 4 insertions(+), 134 deletions(-) delete mode 100644 src/views/Explore.js diff --git a/src/router/index.js b/src/router/index.js index ab236bf1..84fea61a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,6 @@ import Index from "@/views/Index" -import Explore from "@/views/Explore" -import ExploreNew from "@/views/Explore/index" -import NewPublish from "@/views/Publish/index" +import Explore from "@/views/Explore/index" +import Publish from "@/views/Publish/index" import Question from "@/views/Question/index"; import Challenge from "@/views/Challenge/index"; import Claim from "@/views/Claim/index"; @@ -22,7 +21,7 @@ const routes = [ }, { path: "/challenges", - element: , + element: , }, { path: "/collection/:id", @@ -30,7 +29,7 @@ const routes = [ }, { path: "/publish", - element: , + element: , }, { path: "/quests/:questId", diff --git a/src/views/Explore.js b/src/views/Explore.js deleted file mode 100644 index 61a1da73..00000000 --- a/src/views/Explore.js +++ /dev/null @@ -1,129 +0,0 @@ -import { useEffect, useState } from "react" -import { getQuests } from "../request/api/public" -import "@/assets/styles/view-style/explore.scss" -import "@/assets/styles/mobile/view-style/explore.scss" -import { useTranslation } from "react-i18next"; -import store from "@/redux/store"; -import ChallengeItem from "@/components/User/ChallengeItem"; -import ChallengeItems from "@/components/User/ChallengeItems"; -import { useLocation, useNavigate, useParams } from "react-router-dom"; -import { getCollectionQuest } from "@/request/api/quests"; -import { - ArrowLeftOutlined, - } from '@ant-design/icons'; -import InfiniteScroll from "react-infinite-scroll-component"; -import { Spin } from "antd"; - -export default function Explore(params) { - - const { t } = useTranslation(["explore", "translation"]); - const { id } = useParams(); - const location = useLocation(); - const navigateTo = useNavigate(); - - let [page, setPage] = useState(0); - - let [isOver, setIsOver] = useState(); - let [challenges, setChallenges] = useState([]); - let [isMobile, setIsMobile] = useState(store.getState().isMobile); - let [loading, setLoading] = useState(false); - - function handleMobileChange() { - isMobile = store.getState().isMobile; - setIsMobile(isMobile); - } - - store.subscribe(handleMobileChange); - - const goCollection = (id) => { - navigateTo(`/collection/${id}`) - } - - const getChallenge = async() => { - if (loading) { - return - } - setLoading(true); - const cache = localStorage.getItem("decert.cache"); - - page += 1; - setPage(page); - let res - if (id) { - res = await getCollectionQuest({id: Number(id)}); - }else{ - res = await getQuests({pageSize: 10, page: page}); - } - challenges = challenges.concat(res.data.list); - if (challenges.length === res.data.total || id) { - setIsOver(true); - } - if (cache) { - const claimable = JSON.parse(cache)?.claimable; - if (claimable && claimable.length > 0) { - challenges.map(e => { - claimable.map((ele,index) => { - if (e.uuid == ele.uuid && e.claimed) { - const newCache = JSON.parse(cache); - newCache.claimable.splice(index,1); - localStorage.setItem("decert.cache", JSON.stringify(newCache)); - }else if (e.uuid == ele.uuid) { - e.claimable = true; - } - }) - }) - } - } - setChallenges([...challenges]); - setLoading(false); - } - - useEffect(() => { - challenges = []; - setChallenges([...challenges]); - page = 0; - setPage(page); - isOver = false; - setIsOver(isOver); - getChallenge() - },[location]) - - return ( -
-
- { - id && -
navigateTo("/challenges")}> - -

返回

-
- } - {/* title */} -

{t("title")}

- {/* Challenge */} - } - > - { - challenges.map(item => ( - item.style === 1 ? - - : - - )) - } - -
- ) -} \ No newline at end of file From 17ddb44f37a70d9212751843204c276a5cca945c Mon Sep 17 00:00:00 2001 From: Caoqizhi <2391580279@qq.com> Date: Thu, 22 Feb 2024 10:03:13 +0800 Subject: [PATCH 7/7] del: test code --- src/views/Explore/components/ChallengeList.jsx | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/views/Explore/components/ChallengeList.jsx diff --git a/src/views/Explore/components/ChallengeList.jsx b/src/views/Explore/components/ChallengeList.jsx deleted file mode 100644 index d724fe63..00000000 --- a/src/views/Explore/components/ChallengeList.jsx +++ /dev/null @@ -1,9 +0,0 @@ - - - -export default function ChallengeList(params) { - - - - -} \ No newline at end of file