Compare commits
3 Commits
173048e8b2
...
66bc4cd97d
Author | SHA1 | Date |
---|---|---|
john | 66bc4cd97d | |
john | 9ce033624f | |
john | cb5f785a24 |
|
@ -0,0 +1,11 @@
|
|||
###
|
||||
# @LastEditors: John
|
||||
# @Date: 2024-07-19 17:45:49
|
||||
# @LastEditTime: 2024-07-20 10:45:15
|
||||
# @Author: John
|
||||
###
|
||||
VITE_BASE_URL=
|
||||
VITE_BASE_API_URL=
|
||||
VITE_TG_COMMUNITY=sctSCT_bot
|
||||
VITE_TG_BOT_NAME=sctSCT_bot
|
||||
VITE_TG_BOT_WEBAPP_NAME=STC
|
|
@ -6,6 +6,7 @@
|
|||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
"build:test": "tsc -b && vite build --mode test",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
"iconfont": "npx iconfont-h5"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
body,
|
||||
html,
|
||||
#root {
|
||||
height: var(--tg-viewport-height);
|
||||
min-height: var(--tg-viewport-height);
|
||||
background-image: url("./assets/home_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
@ -12,6 +12,11 @@ html,
|
|||
src: url("./assets/font/Roboto-Medium.ttf") format("truetype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "YouSheBiaoTiHei";
|
||||
src: url("./assets/font/YouSheBiaoTiHei.ttf") format("truetype");
|
||||
}
|
||||
|
||||
* {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 10:21:58
|
||||
* @LastEditTime: 2024-07-18 18:25:39
|
||||
* @LastEditTime: 2024-07-19 19:10:34
|
||||
* @Author: John
|
||||
*/
|
||||
import { MemoryRouter, Route, Routes } from "react-router-dom";
|
||||
|
@ -54,7 +54,7 @@ function App() {
|
|||
|
||||
return (
|
||||
<>
|
||||
{!Token ? (
|
||||
{Token ? (
|
||||
<MemoryRouter>
|
||||
<Routes>
|
||||
<Route path="/*" element={<Index />} />
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="345.0001220703125" height="48" viewBox="0 0 345.0001220703125 48"><g><path d="M0,34L13.6896,48L345,48L345,14L331.31,0L0,0L0,34Z" fill="#FFFFFF" fill-opacity="1"/></g></svg>
|
After Width: | Height: | Size: 288 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="86" height="30" viewBox="0 0 86 30"><g><path d="M0,21.25L8.59347,30L86,30L86,8.75L77.4065,0L0,0L0,21.25Z" fill="#5858FF" fill-opacity="1"/></g></svg>
|
After Width: | Height: | Size: 265 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="86" height="30" viewBox="0 0 86 30"><g><path d="M0,21.25L8.59347,30L86,30L86,8.75L77.4065,0L0,0L0,21.25Z" fill="#8D8B8B" fill-opacity="1"/></g></svg>
|
After Width: | Height: | Size: 265 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="215" height="157" viewBox="0 0 215 157"><g><g><path d="M0,0L0,15.5L1,15.5L1,1L15.5,1L15.5,0L0,0Z" fill-rule="evenodd" fill="#D8D8D8" fill-opacity="1"/></g><g transform="matrix(-1,0,0,1,429,0)"><path d="M214,0L214,15.5L215,15.5L215,1L229.5,1L229.5,0L214,0Z" fill-rule="evenodd" fill="#D8D8D8" fill-opacity="1"/></g><g transform="matrix(1,0,0,-1,0,313)"><path d="M0,156L0,171.5L1,171.5L1,157L15.5,157L15.5,156L0,156Z" fill-rule="evenodd" fill="#D8D8D8" fill-opacity="1"/></g><g transform="matrix(-1,0,0,-1,429,313)"><path d="M214,156L214,171.5L215,171.5L215,157L229.5,157L229.5,156L214,156Z" fill-rule="evenodd" fill="#D8D8D8" fill-opacity="1"/></g></g></svg>
|
After Width: | Height: | Size: 773 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="346" height="779" viewBox="0 0 346 779"><g><g><g><path d="M0.5,778.5L12.8582,778.5L0.5,766.5L0.5,778.5Z" fill="#5858FF" fill-opacity="1"/><path d="M0,765.31756L0,778.5L0,779L14.0909,779L0,765.31756ZM1,778L11.6255,778L1,767.68244L1,778Z" fill-rule="evenodd" fill="#5858FF" fill-opacity="1"/></g><g transform="matrix(-1,-5.2146120310681e-8,5.2146120310681e-8,-1,690.9999993481736,25.000018016484567)"><path d="M345.5,24.5L357.8582,24.5L345.5,12.5L345.5,24.5Z" fill="#5858FF" fill-opacity="1"/><path d="M345,11.31756L345,24.5L345,25L359.0909,25L345,11.31756ZM346,24L356.6255,24L346,13.68244L346,24Z" fill-rule="evenodd" fill="#5858FF" fill-opacity="1"/></g></g><g><path d="M346,17.789L327.734,0L327.531,0L0,0L0,760.711L18.2655,778.5L346,778.5L346,17.789ZM327.328,1L1,1L1,760.289L18.672,777.5L345,777.5L345,18.211L327.328,1Z" fill-rule="evenodd" fill="#5858FF" fill-opacity="1"/></g></g></svg>
|
After Width: | Height: | Size: 1005 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="30" height="30" viewBox="0 0 30 30"><defs><clipPath id="master_svg0_5_4502"><rect x="6" y="6" width="18" height="18" rx="0"/></clipPath></defs><g><g><rect x="0" y="0" width="30" height="30" rx="15" fill="#FFFFFF" fill-opacity="1"/></g><g clip-path="url(#master_svg0_5_4502)"><g><path d="M13.32553,20.5048L13.53979,17.35537L19.3052,12.21589C19.558500000000002,11.98404,19.2468,11.86811,18.9157,12.080639999999999L11.80626,16.524549999999998L8.728749,15.558489999999999C8.0665,15.365269999999999,8.0665,14.92088,8.884572,14.59242L20.844,10.0132582C21.389400000000002,9.762081,21.915300000000002,10.148508,21.701,10.979330000000001L19.6753,20.5048C19.539,21.180999999999997,19.1299,21.3549,18.5456,21.026400000000002L15.44862,18.74651L13.948820000000001,20.1956C13.773520000000001,20.369500000000002,13.63718,20.5048,13.32553,20.5048Z" fill="#000000" fill-opacity="1"/></g></g></g></svg>
|
After Width: | Height: | Size: 1000 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="30" height="30" viewBox="0 0 30 30"><g><g><rect x="0" y="0" width="30" height="30" rx="15" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M9.0316328,9L14.05078,15.61869L9,21L10.13682,21L14.558869999999999,16.28847L18.13163,21L22,21L16.69834,14.00909L21.3996,9L20.2628,9L16.19047,13.339089999999999L12.9,9L9.0316328,9ZM10.70337,9.825776L12.48048,9.825776L20.328,20.1742L18.55093,20.1742L10.70337,9.825776Z" fill="#000000" fill-opacity="1"/></g></g></svg>
|
After Width: | Height: | Size: 571 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="345.0001220703125" height="68" viewBox="0 0 345.0001220703125 68"><g><path d="M0,54L13.6897,68L345,68L345,14L331.31,0L0,0L0,54Z" fill="#5858FF" fill-opacity="1"/></g></svg>
|
After Width: | Height: | Size: 288 B |
|
@ -6,13 +6,14 @@
|
|||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 83px;
|
||||
padding: 0 39px;
|
||||
background-color: #000000;
|
||||
z-index: 999;
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
span {
|
||||
/* 自动布局子元素 */
|
||||
opacity: 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 18:07:43
|
||||
* @LastEditTime: 2024-07-15 15:36:30
|
||||
* @LastEditTime: 2024-07-19 15:42:36
|
||||
* @Author: John
|
||||
*/
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
@ -27,6 +27,16 @@ export default function () {
|
|||
Home
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li onClick={() => navigate("/friends")}>
|
||||
<TeamFill
|
||||
color={currentpathname == "/friends" ? "#ffffff" : "#adadad"}
|
||||
/>
|
||||
<span className={currentpathname == "/friends" ? classes.active : ""}>
|
||||
Friends
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<li onClick={() => navigate("/leaderboard")}>
|
||||
<HistogramOutline
|
||||
color={currentpathname == "/leaderboard" ? "#ffffff" : "#adadad"}
|
||||
|
@ -37,14 +47,6 @@ export default function () {
|
|||
Leaderboard
|
||||
</span>
|
||||
</li>
|
||||
<li onClick={() => navigate("/frends")}>
|
||||
<TeamFill
|
||||
color={currentpathname == "/frends" ? "#ffffff" : "#adadad"}
|
||||
/>
|
||||
<span className={currentpathname == "/frends" ? classes.active : ""}>
|
||||
Frends
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
/* width: 141px; */
|
||||
height: 149px;
|
||||
margin-top: 31px;
|
||||
background-image: url("../assets/kuang.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
.tip {
|
||||
/* 自动布局子元素 */
|
||||
|
@ -53,18 +56,25 @@
|
|||
gap: 30px;
|
||||
margin-top: 17px;
|
||||
padding-bottom: 165px;
|
||||
.frends_list_title {
|
||||
opacity: 1;
|
||||
.frends_list_tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
.frends_list_title {
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0em;
|
||||
font-family: Roboto;
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #ffffff;
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #adadad;
|
||||
&.frends_list_title_active {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.frends_list_item {
|
||||
|
@ -119,14 +129,16 @@
|
|||
padding: 17px 15px;
|
||||
position: fixed;
|
||||
bottom: 83px;
|
||||
background-color: #000000;
|
||||
/* background-color: #000000; */
|
||||
z-index: 999;
|
||||
button {
|
||||
width: 345px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
border-radius: 0px;
|
||||
opacity: 1;
|
||||
background: #ffffff;
|
||||
background-image: url("../assets/big_buttom_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
> span {
|
||||
opacity: 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 16:08:30
|
||||
* @LastEditTime: 2024-07-18 18:29:05
|
||||
* @LastEditTime: 2024-07-19 19:06:35
|
||||
* @Author: John
|
||||
*/
|
||||
/*
|
||||
|
@ -18,35 +18,72 @@ import useUserStore from "@/store/User";
|
|||
import { useEffect, useState } from "react";
|
||||
import { api_homepage_subordinates_users } from "@/server/api";
|
||||
import { subordinatesUsers } from "@/server/module";
|
||||
import { cn } from "@/utils";
|
||||
export default function () {
|
||||
const WebApp = useWebApp();
|
||||
const { InvitationCode } = useUserStore();
|
||||
const [frends, setFrends] = useState<subordinatesUsers[]>();
|
||||
const [currentLevel, setCurrentLevel] = useState(1);
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const { data } = await api_homepage_subordinates_users().send({});
|
||||
setFrends(data?.data);
|
||||
updateFriends(1);
|
||||
})();
|
||||
|
||||
return () => {};
|
||||
}, []);
|
||||
|
||||
async function updateFriends(level: number) {
|
||||
const { data } = await api_homepage_subordinates_users().send({
|
||||
queryParams: { level },
|
||||
});
|
||||
setFrends(data?.data);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.frends}>
|
||||
<span className={classes.top_title}>
|
||||
Invite friends and get more PIONEER
|
||||
Invite friends and get more SCTT
|
||||
</span>
|
||||
<img className={classes.logo} src={logo} alt="" />
|
||||
<span className={classes.tip}>
|
||||
Tap on the button to invite your friends
|
||||
</span>
|
||||
<ul className={classes.frends_list}>
|
||||
<span className={classes.frends_list_title}>0 friends</span>
|
||||
{frends?.map((v, i) => (
|
||||
<FrendsItem key={i} userName={v.account} point={v.amount} />
|
||||
))}
|
||||
</ul>
|
||||
{frends?.length == 0 ? (
|
||||
<span className={classes.tip}>
|
||||
Tap on the button to invite your friends
|
||||
</span>
|
||||
) : (
|
||||
<ul className={classes.frends_list}>
|
||||
<div className={classes.frends_list_tabs}>
|
||||
<span
|
||||
className={cn(
|
||||
classes.frends_list_title,
|
||||
currentLevel == 1 ? classes.frends_list_title_active : ""
|
||||
)}
|
||||
onClick={() => {
|
||||
setCurrentLevel(1);
|
||||
updateFriends(1);
|
||||
}}
|
||||
>
|
||||
Level 1 friends
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
classes.frends_list_title,
|
||||
currentLevel == 2 ? classes.frends_list_title_active : ""
|
||||
)}
|
||||
onClick={() => {
|
||||
setCurrentLevel(2);
|
||||
updateFriends(2);
|
||||
}}
|
||||
>
|
||||
Level 2 friends
|
||||
</span>
|
||||
</div>
|
||||
{frends?.map((v, i) => (
|
||||
<FrendsItem key={i} userName={v.account} point={v.amount} />
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
||||
<div className={classes.bottom_btn}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
|
@ -55,6 +92,7 @@ export default function () {
|
|||
}?startapp=${InvitationCode}`;
|
||||
WebApp.openTelegramLink(`https://t.me/share/url?url=${url}`);
|
||||
}}
|
||||
fill="none"
|
||||
>
|
||||
Invite friends
|
||||
</Button>
|
||||
|
@ -69,7 +107,7 @@ function FrendsItem({ userName, point }: { userName: string; point: string }) {
|
|||
<li className={classes.frends_list_item}>
|
||||
<Avatar src="" />
|
||||
<span>{userName}</span>
|
||||
<span>+{point} PIONEER</span>
|
||||
<span>+{point} SCTT</span>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.guide {
|
||||
height: 100%;
|
||||
height: var(--tg-viewport-height);
|
||||
background-image: url("../assets/guide_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-18 14:42:58
|
||||
* @LastEditTime: 2024-07-18 17:07:14
|
||||
* @LastEditTime: 2024-07-19 19:13:27
|
||||
* @Author: John
|
||||
*/
|
||||
import {
|
||||
|
@ -15,7 +15,7 @@ import guide_icon from "@/assets/guide_icon.svg";
|
|||
import dianbao from "@/assets/dianbao.svg";
|
||||
import youguang from "@/assets/youguang.svg";
|
||||
import tuite from "@/assets/tuite.svg";
|
||||
import { api_login } from "@/server/api";
|
||||
import { api_get_user_information, api_login } from "@/server/api";
|
||||
import useUserStore from "@/store/User";
|
||||
|
||||
export default function () {
|
||||
|
@ -66,6 +66,9 @@ export default function () {
|
|||
},
|
||||
});
|
||||
if (data?.data.token) UpdateToken(data?.data.token);
|
||||
|
||||
const { data: userData } = await api_get_user_information().send({});
|
||||
UpdateInvitationCode(userData?.data.shareCode || "");
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -59,6 +59,155 @@
|
|||
margin-top: 14px;
|
||||
}
|
||||
|
||||
.social_task {
|
||||
background-image: url("../assets/social_task_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
width: 345px;
|
||||
height: 778px;
|
||||
margin-top: 28px;
|
||||
|
||||
padding: 0 19px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> span {
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #9292ff;
|
||||
|
||||
margin-top: 21px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
> ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: auto;
|
||||
gap: 8px;
|
||||
margin-top: 16px;
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
width: 315px;
|
||||
/* height: 108px; */
|
||||
border-radius: 12px;
|
||||
opacity: 1;
|
||||
background: rgba(132, 132, 144, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 0 10px;
|
||||
.social_task_item_top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-bottom: 1px solid #2b2b2e;
|
||||
height: 59px;
|
||||
> img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
> span {
|
||||
/* 自动布局子元素 */
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #ffffff;
|
||||
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
> button {
|
||||
background-image: url("../assets/buttom_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
width: 86px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: auto;
|
||||
> span {
|
||||
opacity: 1;
|
||||
|
||||
font-family: YouSheBiaoTiHei;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
text-transform: capitalize;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
&.button_disable {
|
||||
background-image: url("../assets/buttom_disable.svg");
|
||||
> span {
|
||||
color: #2a2a2a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.social_task_item_bottom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 49px;
|
||||
> span {
|
||||
&:nth-of-type(1) {
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #adadad;
|
||||
}
|
||||
|
||||
&:nth-of-type(2) {
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
text-align: right;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.join_card {
|
||||
width: 345px;
|
||||
height: 132px;
|
||||
|
@ -162,14 +311,14 @@
|
|||
|
||||
opacity: 1;
|
||||
|
||||
font-family: Roboto;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
font-family: YouSheBiaoTiHei;
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0em;
|
||||
|
||||
font-variation-settings: "opsz" auto;
|
||||
font-feature-settings: "kern" on;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 10:50:24
|
||||
* @LastEditTime: 2024-07-18 18:45:32
|
||||
* @LastEditTime: 2024-07-19 19:03:45
|
||||
* @Author: John
|
||||
*/
|
||||
import classes from "./Home-m.module.css";
|
||||
import { Routes, useNavigate } from "react-router-dom";
|
||||
import home_top_bg from "@/assets/home_top_bg.svg";
|
||||
import tg_white from "@/assets/tg_white.svg";
|
||||
import tuite_white from "@/assets/tuite_white.svg";
|
||||
import logo from "@/assets/logo.png";
|
||||
import {
|
||||
CheckOutline,
|
||||
|
@ -19,37 +21,48 @@ import { useEffect, useState } from "react";
|
|||
import {
|
||||
api_follow_twitter,
|
||||
api_homepage_query_user_income,
|
||||
api_query_task_configuration_list,
|
||||
api_query_whether_the_user_receives_the_registration_reward,
|
||||
api_start_task,
|
||||
} from "@/server/api";
|
||||
import { useWebApp } from "@vkruglikov/react-telegram-web-app";
|
||||
import IconFont from "@/components/iconfont";
|
||||
import { taskConfigurationListItem } from "@/server/module";
|
||||
export default function () {
|
||||
const WebApp = useWebApp();
|
||||
const navigate = useNavigate();
|
||||
const [totalPoint, setTotalPoint] = useState<string | undefined>();
|
||||
const [totalPoint, setTotalPoint] = useState(0);
|
||||
const [signReward, setSignReward] = useState<string | undefined>();
|
||||
const [tgReward, setTgReward] = useState<string | undefined>();
|
||||
const [xReward, setXReward] = useState<string | undefined>();
|
||||
|
||||
const [myReward, setMyReward] = useState<string | undefined>();
|
||||
const [inviteReward, setInviteReward] = useState<string | undefined>();
|
||||
|
||||
const [tasksList, setTasksList] = useState<taskConfigurationListItem[]>();
|
||||
useEffect(() => {
|
||||
WebApp.setHeaderColor("#000000");
|
||||
(async () => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
})();
|
||||
|
||||
return () => {};
|
||||
}, []);
|
||||
|
||||
async function UpdateHomeData() {
|
||||
const { data: totalDataRes } =
|
||||
await api_query_whether_the_user_receives_the_registration_reward().send(
|
||||
{}
|
||||
);
|
||||
setTotalPoint(totalDataRes?.data);
|
||||
const { data: incomeRes } = await api_homepage_query_user_income().send({});
|
||||
const list = incomeRes?.data || [];
|
||||
setSignReward(list.find((v) => v.opType == 4)?.opValue);
|
||||
setTgReward(list.find((v) => v.opType == 5)?.opValue);
|
||||
setXReward(list.find((v) => v.opType == 6)?.opValue);
|
||||
setMyReward(incomeRes?.data.wordRewar);
|
||||
setInviteReward(incomeRes?.data.teamRewar);
|
||||
setTotalPoint(
|
||||
parseInt(`${incomeRes?.data.wordRewar || 0}`) +
|
||||
parseInt(`${incomeRes?.data.teamRewar || 0}`)
|
||||
);
|
||||
}
|
||||
|
||||
async function UpdateTaskList() {
|
||||
const { data } = await api_query_task_configuration_list().send({});
|
||||
setTasksList(data?.data);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
|
@ -60,36 +73,109 @@ export default function () {
|
|||
</div>
|
||||
|
||||
<img src={logo} alt="" className={classes.logo} />
|
||||
<span className={classes.pepes}>{totalPoint || 0} PIONEER</span>
|
||||
<span className={classes.pepes}>{totalPoint || 0} SCTT</span>
|
||||
|
||||
<div className={classes.join_card}>
|
||||
<span>PIONEER COMMUNITY</span>
|
||||
<span>Home for Telegram OGs</span>
|
||||
<Button
|
||||
fill="none"
|
||||
onClick={() => {
|
||||
WebApp.openTelegramLink(
|
||||
`https://t.me/${import.meta.env.VITE_TG_COMMUNITY}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
join
|
||||
</Button>
|
||||
</div>
|
||||
<div className={classes.social_task}>
|
||||
<span>
|
||||
Complete social media tasks to increase your chances in the raffle.
|
||||
</span>
|
||||
|
||||
<div className={classes.join_card}>
|
||||
<span>Follow X @PioneerPortal</span>
|
||||
<span>Follow X To Get Reward</span>
|
||||
<Button
|
||||
fill="none"
|
||||
onClick={async () => {
|
||||
await api_follow_twitter().send({});
|
||||
WebApp.openLink(`https://x.com/pioneerportal`);
|
||||
UpdateHomeData();
|
||||
}}
|
||||
>
|
||||
Follow
|
||||
</Button>
|
||||
<ul className={classes.social_task_list}>
|
||||
{tasksList?.map((v, i) => (
|
||||
<>
|
||||
{v.type == 1 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Follow starcraft Telegram"
|
||||
buttom_text="Follow"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{v.type == 2 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Join starcraft Telegram"
|
||||
buttom_text="Joined"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{v.type == 5 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Follow @starcraft Twitter"
|
||||
buttom_text="Follow"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{v.type == 6 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Like on @starcraft Twitter"
|
||||
buttom_text="Like"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{v.type == 7 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Retweet @starcraft Twitter"
|
||||
buttom_text="Follow"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{v.type == 8 && (
|
||||
<TaskItem
|
||||
task_id={v.id}
|
||||
task_url={v.taskUrl}
|
||||
type={v.type}
|
||||
title="Quote @starcraft Twitter"
|
||||
buttom_text="Quote"
|
||||
button_disable={v.taskType == 1}
|
||||
reward={v.opValue}
|
||||
onTaskSuccess={() => {
|
||||
UpdateHomeData();
|
||||
UpdateTaskList();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className={classes.rewards}>
|
||||
|
@ -98,31 +184,64 @@ export default function () {
|
|||
<div className={classes.reward_list}>
|
||||
<StarOutline color="#ffffff" />
|
||||
<span>Your rewards</span>
|
||||
<span>+{signReward || 0} PIONEER</span>
|
||||
<span>+{myReward || 0} SCTT</span>
|
||||
</div>
|
||||
|
||||
<div className={classes.reward_list}>
|
||||
{/* <CheckOutline color="#ffffff" /> */}
|
||||
<IconFont name="dianbao" color="#ffffff" />
|
||||
<span>Join Telegram</span>
|
||||
<span>{tgReward || 0}</span>
|
||||
</div>
|
||||
|
||||
<div className={classes.reward_list}>
|
||||
{/* <CheckOutline color="#ffffff" /> */}
|
||||
<IconFont name="tuite" color="#ffffff" />
|
||||
<span>Follow X @PioneerPortal</span>
|
||||
<span>{xReward || 0}</span>
|
||||
</div>
|
||||
|
||||
<div className={classes.reward_list}>
|
||||
{/* <CheckOutline color="#ffffff" /> */}
|
||||
<UserAddOutline color="#ffffff" />
|
||||
<span>Invite friends</span>
|
||||
<span>{0}</span>
|
||||
<span>{inviteReward || 0}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function TaskItem({
|
||||
title,
|
||||
task_id,
|
||||
task_url,
|
||||
type,
|
||||
buttom_text,
|
||||
reward,
|
||||
button_disable,
|
||||
onTaskSuccess,
|
||||
}: {
|
||||
task_id: string;
|
||||
task_url: string;
|
||||
title: string;
|
||||
type: taskConfigurationListItem["type"];
|
||||
buttom_text: string;
|
||||
reward: string;
|
||||
button_disable?: boolean;
|
||||
onTaskSuccess?: () => void;
|
||||
}) {
|
||||
const WebApp = useWebApp();
|
||||
return (
|
||||
<li>
|
||||
<div className={classes.social_task_item_top}>
|
||||
{(type == 1 || type == 2) && <img src={tg_white} alt="" />}
|
||||
{(type == 5 || type == 6 || type == 7 || type == 8) && (
|
||||
<img src={tuite_white} alt="" />
|
||||
)}
|
||||
<span>{title}</span>
|
||||
<Button
|
||||
fill="none"
|
||||
className={button_disable ? classes.button_disable : ""}
|
||||
onClick={async () => {
|
||||
await api_start_task().send({ queryParams: { id: task_id } });
|
||||
WebApp.openLink(task_url);
|
||||
onTaskSuccess?.();
|
||||
}}
|
||||
>
|
||||
{buttom_text}
|
||||
</Button>
|
||||
</div>
|
||||
<div className={classes.social_task_item_bottom}>
|
||||
<span>Reward</span>
|
||||
<span>+{reward} SCTT</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ const tabs = [
|
|||
},
|
||||
{
|
||||
key: "2",
|
||||
title: "Frends",
|
||||
title: "friends",
|
||||
icon: <MessageOutline />,
|
||||
},
|
||||
];
|
||||
|
@ -38,7 +38,7 @@ export default function () {
|
|||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/leaderboard" element={<Leaderboard />} />
|
||||
<Route path="/frends" element={<Frends />} />
|
||||
<Route path="/friends" element={<Frends />} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -30,7 +30,11 @@
|
|||
align-items: center;
|
||||
padding: 13px 15px;
|
||||
|
||||
background: #1e1e1e;
|
||||
/* background: #1e1e1e; */
|
||||
background-image: url("../assets/user_rank_bg.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
border-radius: 0px;
|
||||
gap: 12px;
|
||||
margin-top: 38px;
|
||||
> div {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 16:08:04
|
||||
* @LastEditTime: 2024-07-17 09:51:09
|
||||
* @LastEditTime: 2024-07-19 14:55:57
|
||||
* @Author: John
|
||||
*/
|
||||
import { Avatar, Button } from "antd-mobile";
|
||||
|
@ -37,15 +37,11 @@ export default function () {
|
|||
<Avatar src="" />
|
||||
<div>
|
||||
<span>{userRank?.tgName}</span>
|
||||
<span>{userRank?.amount} PIONEER</span>
|
||||
<span>{userRank?.amount || 0} SCTT</span>
|
||||
</div>
|
||||
<span>#{userRank?.ranking}</span>
|
||||
</div>
|
||||
|
||||
<Button block fill="none">
|
||||
<StarOutline color="#ffffff" />
|
||||
<span>Boost score</span>
|
||||
</Button>
|
||||
<span className={classes.rank_title}>{totalUser || 0} holders</span>
|
||||
<ul className={classes.rank_list}>
|
||||
{ranks?.map((v, i) => (
|
||||
|
@ -76,7 +72,7 @@ function RankItem({
|
|||
<Avatar src="" />
|
||||
<div>
|
||||
<span>{userName}</span>
|
||||
<span>{point} PIONEER</span>
|
||||
<span>{point} SCTT</span>
|
||||
</div>
|
||||
{index == 1 && (
|
||||
<img className={classes.rank_item_icon} src={rank1} alt="" />
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-15 10:35:20
|
||||
* @LastEditTime: 2024-07-16 16:04:49
|
||||
* @LastEditTime: 2024-07-19 15:50:19
|
||||
* @Author: John
|
||||
*/
|
||||
import { GET, POST } from "./client";
|
||||
import { RewardVo, subordinatesUsers, userBenefits } from "./module";
|
||||
import {
|
||||
RewardVo,
|
||||
subordinatesUsers,
|
||||
taskConfigurationListItem,
|
||||
userBenefits,
|
||||
} from "./module";
|
||||
|
||||
// 登录
|
||||
export function api_login() {
|
||||
|
@ -50,7 +55,7 @@ export function api_ranking() {
|
|||
|
||||
// 首页查询用户收益
|
||||
export function api_homepage_query_user_income() {
|
||||
return GET<any, userBenefits[]>({
|
||||
return GET<any, { wordRewar: string; teamRewar: string }>({
|
||||
url: "/api/reward/userBenefits",
|
||||
});
|
||||
}
|
||||
|
@ -90,7 +95,7 @@ export function api_get_user_information() {
|
|||
|
||||
// 首页下级用户
|
||||
export function api_homepage_subordinates_users() {
|
||||
return GET<any, subordinatesUsers[]>({
|
||||
return GET<{ level: number }, subordinatesUsers[]>({
|
||||
url: "/api/reward/subordinateUsers",
|
||||
});
|
||||
}
|
||||
|
@ -101,3 +106,17 @@ export function api_follow_twitter() {
|
|||
url: "/api/reward/followTwitter",
|
||||
});
|
||||
}
|
||||
|
||||
// 查询任务配置列表
|
||||
|
||||
export function api_query_task_configuration_list() {
|
||||
return GET<any, taskConfigurationListItem[]>({
|
||||
url: "/api/task-config",
|
||||
});
|
||||
}
|
||||
|
||||
export function api_start_task() {
|
||||
return POST<any, {}, { id: string }>({
|
||||
url: "/api/task-config",
|
||||
});
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ export type userBenefits = {
|
|||
|
||||
export type subordinatesUsers = {
|
||||
account: string;
|
||||
amount: string;
|
||||
accountType: number;
|
||||
allPid: string;
|
||||
amount: string;
|
||||
chainType: number;
|
||||
codePrompt: number;
|
||||
createTime: string;
|
||||
|
@ -53,3 +53,16 @@ export type subordinatesUsers = {
|
|||
userImg: string;
|
||||
userType: number;
|
||||
};
|
||||
|
||||
export type taskConfigurationListItem = {
|
||||
createTime: string;
|
||||
externalId: string;
|
||||
flag: 0 | 1; // 标记删除,0 / 1
|
||||
id: string;
|
||||
opValue: string;
|
||||
status: 0 | 1 | 2; // 0:已下架(前端不在显示) 1:进行中 2:已结束
|
||||
taskType: 0 | 1; // 0:任务为完成 1:任务已完成
|
||||
taskUrl: string;
|
||||
type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; // 1:加入TG频道 2:加入TG群 3:直推积分 4:间推积分 5:关注推特 6:推特点赞 7:转发推特 8:引用推特
|
||||
updateTime: string;
|
||||
};
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
"include": ["./vite.config.ts"]
|
||||
}
|
||||
|
|
|
@ -9,24 +9,24 @@ import react from "@vitejs/plugin-react";
|
|||
import path from "path";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: "192.168.10.167",
|
||||
port: 8082,
|
||||
proxy: {
|
||||
"/dev": {
|
||||
target: "http://192.168.10.100:8096",
|
||||
changeOrigin: true,
|
||||
rewrite: function (path) {
|
||||
return path.replace(/^\/dev/, "");
|
||||
server: {
|
||||
host: "192.168.10.167",
|
||||
port: 8082,
|
||||
proxy: {
|
||||
"/dev": {
|
||||
target: "http://192.168.10.100:8096",
|
||||
changeOrigin: true,
|
||||
rewrite: function (path) {
|
||||
return path.replace(/^\/dev/, "");
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
},
|
||||
css: {},
|
||||
css: {},
|
||||
});
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* @LastEditors: John
|
||||
* @Date: 2024-07-13 10:21:58
|
||||
* @LastEditTime: 2024-07-18 14:47:48
|
||||
* @Author: John
|
||||
*/
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import path from "path";
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: "192.168.10.167",
|
||||
port: 8082,
|
||||
proxy: {
|
||||
"/dev": {
|
||||
target: "http://192.168.10.100:8096",
|
||||
changeOrigin: true,
|
||||
rewrite: function (path) {
|
||||
return path.replace(/^\/dev/, "");
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
},
|
||||
},
|
||||
css: {},
|
||||
});
|