✨ feat:
This commit is contained in:
parent
c1a8cfd6d6
commit
a58b225544
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-17 18:25:10
|
* @Date: 2024-06-17 18:25:10
|
||||||
* @LastEditTime: 2024-06-19 16:14:06
|
* @LastEditTime: 2024-06-28 17:46:23
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
|
@ -11,7 +11,7 @@ export default {
|
||||||
rootValue: 37.5,
|
rootValue: 37.5,
|
||||||
propList: ["*"],
|
propList: ["*"],
|
||||||
exclude: (e) => {
|
exclude: (e) => {
|
||||||
if (/.*-m\.css$/.test(e) || /.module\.css$/.test(e)) {
|
if (/.*-m\.css$/.test(e) || /.*-m.module\.css$/.test(e)) {
|
||||||
// console.log(e);
|
// console.log(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
28
src/App.tsx
28
src/App.tsx
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-17 17:20:03
|
* @Date: 2024-06-17 17:20:03
|
||||||
* @LastEditTime: 2024-06-26 16:00:00
|
* @LastEditTime: 2024-06-28 17:44:02
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import { Route, Routes } from "react-router-dom";
|
import { Route, Routes } from "react-router-dom";
|
||||||
|
@ -16,7 +16,7 @@ import InvitationList from "./pages/InvitationList";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import useUserStore from "./store/User";
|
import useUserStore from "./store/User";
|
||||||
import { getUrlQueryParam } from "./utils";
|
import { getUrlQueryParam, isMobile } from "./utils";
|
||||||
import { UrlQueryParamsKey } from "./constants";
|
import { UrlQueryParamsKey } from "./constants";
|
||||||
import { signAndLogin } from "./utils/wallet";
|
import { signAndLogin } from "./utils/wallet";
|
||||||
import { useAccount } from "wagmi";
|
import { useAccount } from "wagmi";
|
||||||
|
@ -45,12 +45,30 @@ function App() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RouterLogProvider>
|
<RouterLogProvider>
|
||||||
<Header />
|
{isMobile ? (
|
||||||
|
<>
|
||||||
|
<Header.Mobile />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Home />} />
|
<>
|
||||||
|
<Route path="/" element={<Home.Mobile />} />
|
||||||
<Route path="/mint" element={<Mint />} />
|
<Route path="/mint" element={<Mint />} />
|
||||||
<Route path="/invitationlist" element={<InvitationList />}></Route>
|
<Route
|
||||||
|
path="/invitationlist"
|
||||||
|
element={<InvitationList />}
|
||||||
|
></Route>
|
||||||
|
</>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Header.Desktop />
|
||||||
|
<Routes>
|
||||||
|
<>
|
||||||
|
<Route path="/" element={<Home.Desktop />} />
|
||||||
|
</>
|
||||||
|
</Routes>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</RouterLogProvider>
|
</RouterLogProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-18 15:16:31
|
* @Date: 2024-06-18 15:16:31
|
||||||
* @LastEditTime: 2024-06-27 15:29:00
|
* @LastEditTime: 2024-06-28 14:05:29
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import Picker, {
|
import Picker, {
|
||||||
|
@ -11,7 +11,7 @@ import Picker, {
|
||||||
import { useContext, useEffect, useMemo, useState } from "react";
|
import { useContext, useEffect, useMemo, useState } from "react";
|
||||||
import IconFont from "./iconfont";
|
import IconFont from "./iconfont";
|
||||||
import logo from "@/assets/logo.svg";
|
import logo from "@/assets/logo.svg";
|
||||||
import classes from "./Header.module.css";
|
import classes from "./Header-m.module.css";
|
||||||
import { useLocation, useNavigate, useNavigation } from "react-router-dom";
|
import { useLocation, useNavigate, useNavigation } from "react-router-dom";
|
||||||
import { RouterLogContext } from "@/context/RouterContext";
|
import { RouterLogContext } from "@/context/RouterContext";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
@ -27,7 +27,7 @@ const langColums: Action[] = [
|
||||||
{ text: "日本語", key: Lang.jp },
|
{ text: "日本語", key: Lang.jp },
|
||||||
{ text: "DEUTSCH", key: Lang.de },
|
{ text: "DEUTSCH", key: Lang.de },
|
||||||
];
|
];
|
||||||
export default function () {
|
function Mobile() {
|
||||||
const { UpdateLang } = useUserStore();
|
const { UpdateLang } = useUserStore();
|
||||||
|
|
||||||
const route = useContext(RouterLogContext);
|
const route = useContext(RouterLogContext);
|
||||||
|
@ -79,3 +79,12 @@ export default function () {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Desktop() {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Mobile,
|
||||||
|
Desktop,
|
||||||
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-19 10:49:42
|
* @Date: 2024-06-19 10:49:42
|
||||||
* @LastEditTime: 2024-06-19 10:52:32
|
* @LastEditTime: 2024-06-28 14:05:45
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import classes from "./RecordsItem.module.css";
|
import classes from "./RecordsItem-m.module.css";
|
||||||
export default function RecordsItem({
|
export default function RecordsItem({
|
||||||
itemList,
|
itemList,
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* @LastEditors: John
|
||||||
|
* @Date: 2024-06-28 14:09:55
|
||||||
|
* @LastEditTime: 2024-06-28 14:14:29
|
||||||
|
* @Author: John
|
||||||
|
*/
|
||||||
|
import useUserStore from "@/store/User";
|
||||||
|
import { useWeb3Modal } from "@web3modal/wagmi/react";
|
||||||
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useAccount } from "wagmi";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { Dialog } from "antd-mobile";
|
||||||
|
import {
|
||||||
|
api_get_homepage_user_data,
|
||||||
|
api_query_user_invitation_code,
|
||||||
|
} from "@/server/api";
|
||||||
|
import { UserHomeData } from "@/server/module";
|
||||||
|
import { UrlQueryParamsKey } from "@/constants";
|
||||||
|
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
|
||||||
|
import { ToastHandler } from "antd-mobile/es/components/toast";
|
||||||
|
import { PullStatus } from "antd-mobile/es/components/pull-to-refresh";
|
||||||
|
export default function () {
|
||||||
|
const { Token, UpdateToken } = useUserStore();
|
||||||
|
const { open } = useWeb3Modal();
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { address } = useAccount();
|
||||||
|
|
||||||
|
const [tabIndex, setTabIndex] = useState(0);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [userData, setUserData] = useState<UserHomeData>();
|
||||||
|
const [inviteCode, setInviteCode] = useState("");
|
||||||
|
|
||||||
|
const userInviteLink = useMemo(
|
||||||
|
() =>
|
||||||
|
`${location.origin}/#/?${UrlQueryParamsKey.INVITE_CODE}=${inviteCode}`,
|
||||||
|
[inviteCode]
|
||||||
|
);
|
||||||
|
const receiveLoadingToast = useRef<ToastHandler>();
|
||||||
|
const {
|
||||||
|
transcationStatus,
|
||||||
|
startPollingCheckBuyStatus,
|
||||||
|
stopPollingCheckBuyStatus,
|
||||||
|
} = usePollingCheckBuyStatus("NORMAL");
|
||||||
|
|
||||||
|
const statusRecord: Record<PullStatus, string> = {
|
||||||
|
pulling: "Pull down to refresh",
|
||||||
|
canRelease: "Release to refresh immediately",
|
||||||
|
refreshing: "Loading...",
|
||||||
|
complete: "Refresh complete",
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (Token) {
|
||||||
|
getHomeData();
|
||||||
|
getInviteCode();
|
||||||
|
}
|
||||||
|
return () => {};
|
||||||
|
}, [Token]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (transcationStatus == "success") {
|
||||||
|
receiveLoadingToast.current?.close();
|
||||||
|
stopPollingCheckBuyStatus();
|
||||||
|
Dialog.alert({
|
||||||
|
content: `${t("领取成功,前往钱包查看")}`,
|
||||||
|
confirmText: "OK",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, [transcationStatus]);
|
||||||
|
|
||||||
|
async function getHomeData() {
|
||||||
|
const { data } = await api_get_homepage_user_data().send({});
|
||||||
|
setUserData(data?.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getInviteCode() {
|
||||||
|
const { data } = await api_query_user_invitation_code().send({});
|
||||||
|
setInviteCode(data?.data.invitationCode || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("user token:", Token);
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, [Token]);
|
||||||
|
return {
|
||||||
|
getHomeData,
|
||||||
|
statusRecord,
|
||||||
|
Token,
|
||||||
|
address,
|
||||||
|
setUserData,
|
||||||
|
userData,
|
||||||
|
tabIndex,
|
||||||
|
t,
|
||||||
|
setTabIndex,
|
||||||
|
navigate,
|
||||||
|
userInviteLink,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import usePagination from "@/hook/usePagination";
|
||||||
|
import { api_recommended_list } from "@/server/api";
|
||||||
|
import { RecommendedListItem } from "@/server/module";
|
||||||
|
import { Empty, InfiniteScroll } from "antd-mobile";
|
||||||
|
import DataTable, { TableColumn } from "react-data-table-component";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const columns: TableColumn<RecommendedListItem>[] = [
|
||||||
|
{
|
||||||
|
name: t("地址"),
|
||||||
|
selector: (row) => row.walletAddress,
|
||||||
|
grow: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Node",
|
||||||
|
selector: (row) => row.nodeNumber,
|
||||||
|
grow: 1,
|
||||||
|
// @ts-ignore
|
||||||
|
right: "true",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { list, hasMore, loadMore } = usePagination<RecommendedListItem>({
|
||||||
|
service({ pageNum, pageSize }) {
|
||||||
|
return new Promise(async (reslove) => {
|
||||||
|
const { data } = await api_recommended_list().send({
|
||||||
|
queryParams: { pageNum, pageSize },
|
||||||
|
});
|
||||||
|
reslove(data?.data.records || []);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
columns,
|
||||||
|
list,
|
||||||
|
loadMore,
|
||||||
|
hasMore,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
import { cn, filterAddressBeforeZero, filterAmountBeforeZero } from "@/utils";
|
||||||
|
import classes from "./Mint-m.module.css";
|
||||||
|
import nft_bg from "@/assets/nft_bg.svg";
|
||||||
|
import Button from "antd-mobile/es/components/button";
|
||||||
|
import Space from "antd-mobile/es/components/space";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
import {
|
||||||
|
api_get_homepage_user_data,
|
||||||
|
api_get_nft_configuration_data,
|
||||||
|
api_node_order,
|
||||||
|
api_users_cancel_orders,
|
||||||
|
} from "@/server/api";
|
||||||
|
import {
|
||||||
|
NftConfigurationData,
|
||||||
|
NftOrder,
|
||||||
|
NodeOrder,
|
||||||
|
UserHomeData,
|
||||||
|
} from "@/server/module";
|
||||||
|
import {
|
||||||
|
authorizedU,
|
||||||
|
getApproveUsdt,
|
||||||
|
getBalance,
|
||||||
|
payByContract,
|
||||||
|
} from "@/contract/utils";
|
||||||
|
import { Dialog, Modal, Stepper, Toast } from "antd-mobile";
|
||||||
|
import useUserStore from "@/store/User";
|
||||||
|
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
|
||||||
|
import { ToastHandler } from "antd-mobile/es/components/toast";
|
||||||
|
import { BaseError } from "wagmi";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { toWei } from "web3-utils";
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { Token } = useUserStore();
|
||||||
|
const [nodeConfig, setNodeConfig] = useState<UserHomeData>();
|
||||||
|
const [approveUsdt, setApproveUsdt] = useState<bigint>(0n);
|
||||||
|
const [balance, setBalance] = useState<bigint>(0n);
|
||||||
|
const orderInfo = useRef<NodeOrder>();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [num, setNum] = useState(1);
|
||||||
|
|
||||||
|
const buyLoadingToast = useRef<ToastHandler>();
|
||||||
|
const approveLoadingToast = useRef<ToastHandler>();
|
||||||
|
const {
|
||||||
|
transcationStatus,
|
||||||
|
startPollingCheckBuyStatus,
|
||||||
|
stopPollingCheckBuyStatus,
|
||||||
|
} = usePollingCheckBuyStatus("NORMAL");
|
||||||
|
|
||||||
|
const costNum = useMemo(
|
||||||
|
() =>
|
||||||
|
BigInt(
|
||||||
|
toWei(`${parseFloat(`${nodeConfig?.nodePrice || "0"}`) * num}`, "ether")
|
||||||
|
),
|
||||||
|
[nodeConfig?.nodePrice, num]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateNodeConfig();
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
Toast.show({ icon: "loading", content: t("正在获取已授权金额") });
|
||||||
|
setBalance(await getBalance());
|
||||||
|
setApproveUsdt(await getApproveUsdt());
|
||||||
|
Toast.clear();
|
||||||
|
})();
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, [Token]);
|
||||||
|
|
||||||
|
async function updateNodeConfig() {
|
||||||
|
const { data } = await api_get_homepage_user_data().send({});
|
||||||
|
setNodeConfig(data?.data);
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
if (transcationStatus == "success") {
|
||||||
|
buyLoadingToast.current?.close();
|
||||||
|
stopPollingCheckBuyStatus();
|
||||||
|
Dialog.alert({
|
||||||
|
content: `${t(
|
||||||
|
"Buy successful. Please return to the homepage to view."
|
||||||
|
)}`,
|
||||||
|
confirmText: "OK",
|
||||||
|
onConfirm() {
|
||||||
|
navigate("/");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {};
|
||||||
|
}, [transcationStatus]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodeConfig,
|
||||||
|
num,
|
||||||
|
setNum,
|
||||||
|
approveUsdt,
|
||||||
|
t,
|
||||||
|
balance,
|
||||||
|
approveLoadingToast,
|
||||||
|
costNum,
|
||||||
|
setApproveUsdt,
|
||||||
|
buyLoadingToast,
|
||||||
|
orderInfo,
|
||||||
|
updateNodeConfig,
|
||||||
|
startPollingCheckBuyStatus,
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,98 +1,35 @@
|
||||||
import classes from "./Home.module.css";
|
/*
|
||||||
import useUserStore from "@/store/User";
|
* @LastEditors: John
|
||||||
|
* @Date: 2024-06-26 15:04:10
|
||||||
|
* @LastEditTime: 2024-06-28 14:36:37
|
||||||
|
* @Author: John
|
||||||
|
*/
|
||||||
|
import classes from "./Home-m.module.css";
|
||||||
import { cn, copyText, getLevelName, shortenString } from "@/utils";
|
import { cn, copyText, getLevelName, shortenString } from "@/utils";
|
||||||
import { useWeb3Modal } from "@web3modal/wagmi/react";
|
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import logo from "@/assets/logo.svg";
|
import logo from "@/assets/logo.svg";
|
||||||
import nftBg from "@/assets/nft_bg.svg";
|
import nftBg from "@/assets/nft_bg.svg";
|
||||||
import usdtBg from "@/assets/usdt_bg.svg";
|
|
||||||
import IconFont from "@/components/iconfont";
|
import IconFont from "@/components/iconfont";
|
||||||
import { BaseError, useAccount } from "wagmi";
|
import { PullToRefresh } from "antd-mobile";
|
||||||
import { config } from "@/components/WalletProvider";
|
|
||||||
import { createSearchParams, useNavigate } from "react-router-dom";
|
|
||||||
import { Button, Dialog, Empty, PullToRefresh, Toast } from "antd-mobile";
|
|
||||||
import { loginOut } from "@/utils/wallet";
|
import { loginOut } from "@/utils/wallet";
|
||||||
import {
|
import useHome from "./Feature/useHome";
|
||||||
api_claim_income,
|
import useMint from "./Feature/useMint";
|
||||||
api_get_homepage_user_data,
|
import useInvitationList from "./Feature/useInvitationList";
|
||||||
api_query_user_invitation_code,
|
function Mobile() {
|
||||||
} from "@/server/api";
|
|
||||||
import { UserHomeData } from "@/server/module";
|
|
||||||
import { UrlQueryParamsKey } from "@/constants";
|
|
||||||
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
|
|
||||||
import { ToastHandler } from "antd-mobile/es/components/toast";
|
|
||||||
import { disconnect, getAccount } from "@wagmi/core";
|
|
||||||
import { PullStatus } from "antd-mobile/es/components/pull-to-refresh";
|
|
||||||
export default function () {
|
|
||||||
const { Token, UpdateToken } = useUserStore();
|
|
||||||
const { open } = useWeb3Modal();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { address } = useAccount();
|
|
||||||
|
|
||||||
const [tabIndex, setTabIndex] = useState(0);
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [userData, setUserData] = useState<UserHomeData>();
|
|
||||||
const [inviteCode, setInviteCode] = useState("");
|
|
||||||
|
|
||||||
const userInviteLink = useMemo(
|
|
||||||
() =>
|
|
||||||
`${location.origin}/#/?${UrlQueryParamsKey.INVITE_CODE}=${inviteCode}`,
|
|
||||||
[inviteCode]
|
|
||||||
);
|
|
||||||
const receiveLoadingToast = useRef<ToastHandler>();
|
|
||||||
const {
|
const {
|
||||||
transcationStatus,
|
getHomeData,
|
||||||
startPollingCheckBuyStatus,
|
statusRecord,
|
||||||
stopPollingCheckBuyStatus,
|
Token,
|
||||||
} = usePollingCheckBuyStatus("NORMAL");
|
address,
|
||||||
|
setUserData,
|
||||||
const statusRecord: Record<PullStatus, string> = {
|
userData,
|
||||||
pulling: "Pull down to refresh",
|
tabIndex,
|
||||||
canRelease: "Release to refresh immediately",
|
t,
|
||||||
refreshing: "Loading...",
|
setTabIndex,
|
||||||
complete: "Refresh complete",
|
navigate,
|
||||||
};
|
userInviteLink,
|
||||||
|
} = useHome();
|
||||||
useEffect(() => {
|
|
||||||
if (Token) {
|
|
||||||
getHomeData();
|
|
||||||
getInviteCode();
|
|
||||||
}
|
|
||||||
return () => {};
|
|
||||||
}, [Token]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (transcationStatus == "success") {
|
|
||||||
receiveLoadingToast.current?.close();
|
|
||||||
stopPollingCheckBuyStatus();
|
|
||||||
Dialog.alert({
|
|
||||||
content: `${t("领取成功,前往钱包查看")}`,
|
|
||||||
confirmText: "OK",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {};
|
|
||||||
}, [transcationStatus]);
|
|
||||||
|
|
||||||
async function getHomeData() {
|
|
||||||
const { data } = await api_get_homepage_user_data().send({});
|
|
||||||
setUserData(data?.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getInviteCode() {
|
|
||||||
const { data } = await api_query_user_invitation_code().send({});
|
|
||||||
setInviteCode(data?.data.invitationCode || "");
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log("user token:", Token);
|
|
||||||
|
|
||||||
return () => {};
|
|
||||||
}, [Token]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<PullToRefresh
|
<PullToRefresh
|
||||||
onRefresh={async () => {
|
onRefresh={async () => {
|
||||||
await getHomeData();
|
await getHomeData();
|
||||||
|
@ -309,6 +246,42 @@ export default function () {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PullToRefresh>
|
</PullToRefresh>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Desktop() {
|
||||||
|
const {
|
||||||
|
getHomeData,
|
||||||
|
statusRecord,
|
||||||
|
Token,
|
||||||
|
address,
|
||||||
|
setUserData,
|
||||||
|
userData,
|
||||||
|
tabIndex,
|
||||||
|
t,
|
||||||
|
setTabIndex,
|
||||||
|
navigate,
|
||||||
|
userInviteLink,
|
||||||
|
} = useHome();
|
||||||
|
const {
|
||||||
|
nodeConfig,
|
||||||
|
num,
|
||||||
|
setNum,
|
||||||
|
approveUsdt,
|
||||||
|
balance,
|
||||||
|
approveLoadingToast,
|
||||||
|
costNum,
|
||||||
|
setApproveUsdt,
|
||||||
|
buyLoadingToast,
|
||||||
|
orderInfo,
|
||||||
|
updateNodeConfig,
|
||||||
|
startPollingCheckBuyStatus,
|
||||||
|
} = useMint();
|
||||||
|
const { columns, list, loadMore, hasMore } = useInvitationList();
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Mobile,
|
||||||
|
Desktop,
|
||||||
|
};
|
||||||
|
|
|
@ -4,40 +4,12 @@
|
||||||
* @LastEditTime: 2024-06-27 15:33:01
|
* @LastEditTime: 2024-06-27 15:33:01
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import usePagination from "@/hook/usePagination";
|
|
||||||
import { api_recommended_list } from "@/server/api";
|
|
||||||
import { RecommendedListItem } from "@/server/module";
|
|
||||||
import { Empty, InfiniteScroll } from "antd-mobile";
|
import { Empty, InfiniteScroll } from "antd-mobile";
|
||||||
import DataTable, { TableColumn } from "react-data-table-component";
|
import DataTable from "react-data-table-component";
|
||||||
import { useTranslation } from "react-i18next";
|
import useInvitationList from "./Feature/useInvitationList";
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const { t } = useTranslation();
|
const { columns, list, loadMore, hasMore } = useInvitationList();
|
||||||
const columns: TableColumn<RecommendedListItem>[] = [
|
|
||||||
{
|
|
||||||
name: t("地址"),
|
|
||||||
selector: (row) => row.walletAddress,
|
|
||||||
grow: 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Node",
|
|
||||||
selector: (row) => row.nodeNumber,
|
|
||||||
grow: 1,
|
|
||||||
// @ts-ignore
|
|
||||||
right: "true",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const { list, hasMore, loadMore } = usePagination<RecommendedListItem>({
|
|
||||||
service({ pageNum, pageSize }) {
|
|
||||||
return new Promise(async (reslove) => {
|
|
||||||
const { data } = await api_recommended_list().send({
|
|
||||||
queryParams: { pageNum, pageSize },
|
|
||||||
});
|
|
||||||
reslove(data?.data.records || []);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,110 +1,36 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-18 15:28:03
|
* @Date: 2024-06-18 15:28:03
|
||||||
* @LastEditTime: 2024-06-27 17:17:09
|
* @LastEditTime: 2024-06-28 14:33:02
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import { cn, filterAddressBeforeZero, filterAmountBeforeZero } from "@/utils";
|
import { cn, filterAddressBeforeZero, filterAmountBeforeZero } from "@/utils";
|
||||||
import classes from "./Mint.module.css";
|
import classes from "./Mint-m.module.css";
|
||||||
import nft_bg from "@/assets/nft_bg.svg";
|
import nft_bg from "@/assets/nft_bg.svg";
|
||||||
import Button from "antd-mobile/es/components/button";
|
import Button from "antd-mobile/es/components/button";
|
||||||
import Space from "antd-mobile/es/components/space";
|
import Space from "antd-mobile/es/components/space";
|
||||||
import { useTranslation } from "react-i18next";
|
import { api_node_order } from "@/server/api";
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { authorizedU, getApproveUsdt, payByContract } from "@/contract/utils";
|
||||||
import {
|
import { Stepper, Toast } from "antd-mobile";
|
||||||
api_get_homepage_user_data,
|
|
||||||
api_get_nft_configuration_data,
|
|
||||||
api_node_order,
|
|
||||||
api_users_cancel_orders,
|
|
||||||
} from "@/server/api";
|
|
||||||
import {
|
|
||||||
NftConfigurationData,
|
|
||||||
NftOrder,
|
|
||||||
NodeOrder,
|
|
||||||
UserHomeData,
|
|
||||||
} from "@/server/module";
|
|
||||||
import {
|
|
||||||
authorizedU,
|
|
||||||
getApproveUsdt,
|
|
||||||
getBalance,
|
|
||||||
payByContract,
|
|
||||||
} from "@/contract/utils";
|
|
||||||
import { Dialog, Modal, Stepper, Toast } from "antd-mobile";
|
|
||||||
import useUserStore from "@/store/User";
|
|
||||||
import usePollingCheckBuyStatus from "@/hook/usePollingCheckBuyStatus";
|
|
||||||
import { ToastHandler } from "antd-mobile/es/components/toast";
|
|
||||||
import { BaseError } from "wagmi";
|
import { BaseError } from "wagmi";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import { toWei } from "web3-utils";
|
import { toWei } from "web3-utils";
|
||||||
|
import useMint from "./Feature/useMint";
|
||||||
export default function () {
|
export default function () {
|
||||||
const { t } = useTranslation();
|
|
||||||
const { Token } = useUserStore();
|
|
||||||
const [nodeConfig, setNodeConfig] = useState<UserHomeData>();
|
|
||||||
const [approveUsdt, setApproveUsdt] = useState<bigint>(0n);
|
|
||||||
const [balance, setBalance] = useState<bigint>(0n);
|
|
||||||
const orderInfo = useRef<NodeOrder>();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const [num, setNum] = useState(1);
|
|
||||||
|
|
||||||
const buyLoadingToast = useRef<ToastHandler>();
|
|
||||||
const approveLoadingToast = useRef<ToastHandler>();
|
|
||||||
const {
|
const {
|
||||||
transcationStatus,
|
nodeConfig,
|
||||||
|
num,
|
||||||
|
setNum,
|
||||||
|
approveUsdt,
|
||||||
|
t,
|
||||||
|
balance,
|
||||||
|
approveLoadingToast,
|
||||||
|
costNum,
|
||||||
|
setApproveUsdt,
|
||||||
|
buyLoadingToast,
|
||||||
|
orderInfo,
|
||||||
|
updateNodeConfig,
|
||||||
startPollingCheckBuyStatus,
|
startPollingCheckBuyStatus,
|
||||||
stopPollingCheckBuyStatus,
|
} = useMint();
|
||||||
} = usePollingCheckBuyStatus("NORMAL");
|
|
||||||
|
|
||||||
const costNum = useMemo(
|
|
||||||
() =>
|
|
||||||
BigInt(
|
|
||||||
toWei(`${parseFloat(`${nodeConfig?.nodePrice || "0"}`) * num}`, "ether")
|
|
||||||
),
|
|
||||||
[nodeConfig?.nodePrice, num]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
updateNodeConfig();
|
|
||||||
|
|
||||||
return () => {};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
Toast.show({ icon: "loading", content: t("正在获取已授权金额") });
|
|
||||||
setBalance(await getBalance());
|
|
||||||
setApproveUsdt(await getApproveUsdt());
|
|
||||||
Toast.clear();
|
|
||||||
})();
|
|
||||||
|
|
||||||
return () => {};
|
|
||||||
}, [Token]);
|
|
||||||
|
|
||||||
async function updateNodeConfig() {
|
|
||||||
const { data } = await api_get_homepage_user_data().send({});
|
|
||||||
setNodeConfig(data?.data);
|
|
||||||
}
|
|
||||||
useEffect(() => {
|
|
||||||
if (transcationStatus == "success") {
|
|
||||||
buyLoadingToast.current?.close();
|
|
||||||
stopPollingCheckBuyStatus();
|
|
||||||
Dialog.alert({
|
|
||||||
content: `${t(
|
|
||||||
"Buy successful. Please return to the homepage to view."
|
|
||||||
)}`,
|
|
||||||
confirmText: "OK",
|
|
||||||
onConfirm() {
|
|
||||||
navigate("/");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {};
|
|
||||||
}, [transcationStatus]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={cn(classes.Mint, classes.container)}>
|
<div className={cn(classes.Mint, classes.container)}>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* @LastEditors: John
|
* @LastEditors: John
|
||||||
* @Date: 2024-06-17 18:19:27
|
* @Date: 2024-06-17 18:19:27
|
||||||
* @LastEditTime: 2024-06-27 11:40:59
|
* @LastEditTime: 2024-06-28 15:32:57
|
||||||
* @Author: John
|
* @Author: John
|
||||||
*/
|
*/
|
||||||
import { type ClassValue, clsx } from "clsx";
|
import { type ClassValue, clsx } from "clsx";
|
||||||
|
|
Loading…
Reference in New Issue