Skip to content

Commit

Permalink
MEP 30/12/2022 (#435)
Browse files Browse the repository at this point in the history
* test: cdn code change

* fix: update cdn check

* feat: add rhino image (#413)

* feat: quest boost (#361)

* feat: add base layout

* feat: add contract call base

* feat: add api calls v1

* feat: park changes

* feat: api integration

* chore: add types

* feat: add build fix and expiry timer

* chore: fix types

* feat: update button text conditions

* feat: add contract in quest boost

* feat: add api calls

* feat: add updated changes

* chore: add changes

* chore: revert rpc changes

* chore: button title change

* feat: add final changes

* chore: add types

* fix: design changes

* feat: update contract

* chore: remove decimal representation on contract address

* fix: claim button copy

* fix: mobile view styling

* fix: align expired tag

* fix: expired condition change

* feat: update with new boost info and resolve pr comments

* chore: resolve pr comments

* chore: update types

* chore: fix types

* fix: sign check

* chore: update starknet js version

* test: starknet js contract call

* fix: test account call

* fix: remove extra calls

* test: add abi and test

* test: update abi

* chore: remove extra code

* fix: update abi params in account.execute

* chore: resolve pr comments

* fix: handle claimed status

* test: remove undefined

* fix: remove timer on expiry and winner check fix (#419)

* fix: remove timer on expiry

* fix: timer check

* fix: remove decimal conversion

* fix: add claim  button flag (#420)

* feat: add quests favicon (#422)

* feat: bootstrap project with absolute-import (#423)

* feat: add rich UI on boost (#421)

* feat: add rich UI

* fix: change copy

* fix: length  on word check

* fix: expiry check

* feat: add notification support

* fix: remove timer check

* feat: add title styling

* fix: add correct address check

* fix: address to send

* feat: add absolute imports

* fix: tests config

* fix: mobile responsive

* fix: number formatting

* feat: add mobile responsive button and banner fix (#427)

* feat: mobile screen redesign (#425)

* feat: redesigning popups

* improving margin

* feat: redesigning partnership page

* feat: quest page redesign for mobile

* feat: back button redesign for mobile

* improving issuer

* feat: menu redesign for mobile

* fixing land margin

* fixing land paddings

* fixing land gaps

* fixing featured quest banner on some browsers

* fixing profile margins

* removing typing mistake

* fixing profile scroll on mobile

* fix logo in nav animation

* fix margin for category subtitles

* cleaning the code

* fix: add design fixes and api calls reduce in leaderboard (#431)

* fix: add design fixes and api calls reduce in leaderboard

* feat: add ui changes

* fix: build fails

* fix: utils

* feat: add optimisations

* chore: resolve comments and resolve build issue

* chore: remove logs

* feat: add boosted quests tag (#434)

---------

Co-authored-by: ayushtom <[email protected]>
Co-authored-by: Thomas Marchand <[email protected]>
Co-authored-by: Ayush Tomar <[email protected]>
Co-authored-by: Adegbite Ademola Kelvin <[email protected]>
Co-authored-by: Nico <[email protected]>
  • Loading branch information
6 people authored Dec 30, 2023
1 parent a70e0dd commit 3a437ad
Show file tree
Hide file tree
Showing 44 changed files with 1,049 additions and 328 deletions.
164 changes: 81 additions & 83 deletions app/leaderboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,22 @@ import { isStarkDomain } from "starknetid.js/packages/core/dist/utils";
import Divider from "@mui/material/Divider";
import Blur from "@components/shapes/blur";
import RankingsTable from "@components/leaderboard/RankingsTable";
import {
rankOrder,
rankOrderMobile,
timeFrameMap,
} from "@utils/constants";
import { rankOrder, rankOrderMobile, timeFrameMap } from "@utils/constants";
import ControlsDashboard from "@components/leaderboard/ControlsDashboard";
import { hexToDecimal } from "@utils/feltService";
import { decimalToHex, hexToDecimal } from "@utils/feltService";
import Avatar from "@components/UI/avatar";
import { useMediaQuery } from "@mui/material";
import Link from "next/link";

export default function Page() {
const router = useRouter();
const { status, address } = useAccount();
const { featuredQuest } = useContext(QuestsContext);

const [duration, setDuration] = useState<string>("Last 7 Days");
const [userPercentile, setUserPercentile] = useState<number>(100);
const [userPercentile, setUserPercentile] = useState<number>();
const [searchQuery, setSearchQuery] = useState<string>("");
const [apiCallDelay, setApiCallDelay] = useState<boolean>(false);
const searchAddress = useDebounce<string>(searchQuery, 200);
const [currentSearchedAddress, setCurrentSearchedAddress] =
useState<string>("");
Expand All @@ -65,12 +63,17 @@ export default function Page() {

// set user address on wallet connect and disconnect
useEffect(() => {
setTimeout(() => {
setApiCallDelay(true);
}, 1000);
if (address === "") return;
if (address) setUserAddress(address);
if (status === "disconnected") setUserAddress("");
}, [address, status]);

useEffect(() => {
// adding a delay for the browser to automatically detect wallet and fetch connection status on component mount
if (!apiCallDelay) return;
const requestBody = {
addr:
status === "connected"
Expand All @@ -85,6 +88,8 @@ export default function Page() {
const fetchLeaderboardToppersResult = async () => {
const topperData = await fetchLeaderboardToppers({
addr: requestBody.addr,
start_timestamp: new Date().setDate(new Date().getDate() - 7),
end_timestamp: new Date().getTime(),
});
setLeaderboardToppers(topperData);
};
Expand All @@ -98,22 +103,12 @@ export default function Page() {
fetchLeaderboardToppersResult();
fetchRankingResults();
setLoading(false);
}, [userAddress, status]);
}, [userAddress, status, apiCallDelay]);

const [leaderboardToppers, setLeaderboardToppers] =
useState<LeaderboardToppersData>({
weekly: {
best_users: [],
length: 0,
},
monthly: {
best_users: [],
length: 0,
},
all_time: {
best_users: [],
length: 0,
},
best_users: [],
total_users: 0,
});

const contract = useMemo(() => {
Expand Down Expand Up @@ -243,11 +238,13 @@ export default function Page() {
const fetchLeaderboard = async () => {
const topperData = await fetchLeaderboardToppers({
addr: requestBody.addr,
start_timestamp: requestBody.start_timestamp,
end_timestamp: requestBody.end_timestamp,
});
setLeaderboardToppers(topperData);
};

if (searchAddress.length > 0) fetchLeaderboard();
fetchLeaderboard();
fetchRankings();
}, [
rowsPerPage,
Expand All @@ -271,13 +268,7 @@ export default function Page() {
// used to calculate user percentile as soon as required data is fetched
useEffect(() => {
// check if the user has position on the leaderboard
if (
!leaderboardToppers?.[
timeFrameMap[
duration as keyof typeof timeFrameMap
] as keyof typeof leaderboardToppers
]?.position
) {
if (!leaderboardToppers?.position) {
setUserPercentile(-1);
if (currentSearchedAddress.length > 0 && isCustomResult)
setShowNoresults(true);
Expand All @@ -289,20 +280,12 @@ export default function Page() {

// calculate user percentile
const res = calculatePercentile(
leaderboardToppers[
timeFrameMap[
duration as keyof typeof timeFrameMap
] as keyof typeof leaderboardToppers
]?.position ?? 0,
leaderboardToppers[
timeFrameMap[
duration as keyof typeof timeFrameMap
] as keyof typeof leaderboardToppers
]?.length ?? 0
leaderboardToppers?.position ?? 0,
leaderboardToppers?.total_users ?? 0
);
setUserPercentile(res);
setShowNoresults(false);
}, [leaderboardToppers, currentSearchedAddress]);
}, [leaderboardToppers, currentSearchedAddress, duration]);

return (
<div className={styles.leaderboard_container}>
Expand Down Expand Up @@ -363,29 +346,42 @@ export default function Page() {
</div>

{/* this will be displayed if user is present otherwise will not be displayed */}
{userPercentile >= 0 ? (
<div className={styles.percentile_container}>
{currentSearchedAddress.length > 0 || userAddress ? (
<Avatar
address={
currentSearchedAddress.length > 0
? currentSearchedAddress
: userAddress
}
/>
) : null}
<div className={styles.percentile_text_container}>
<p className={styles.percentile_text_normal}>
{currentSearchedAddress.length > 0 ? "He is" : "You are "}
</p>
<span className={styles.percentile_text_green}>
&nbsp;better than {userPercentile}%&nbsp;
</span>
{userPercentile ? (
userPercentile >= 0 ? (
<div className={styles.percentile_container}>
{currentSearchedAddress.length > 0 || userAddress ? (
<Avatar
address={
currentSearchedAddress.length > 0
? currentSearchedAddress
: userAddress
}
/>
) : null}
<div className={styles.percentile_text_container}>
<p className={styles.percentile_text_normal}>
{currentSearchedAddress.length > 0 ? "He is" : "You are "}
</p>
<span className={styles.percentile_text_green}>
&nbsp;better than {userPercentile}%&nbsp;
</span>
<p className={styles.percentile_text_normal}>
of the other players
</p>
</div>
</div>
) : (
<div className={styles.percentile_container}>
<p className={styles.percentile_text_normal}>
of the other players
You werent active this week. ready to jump back in?
</p>
<Link href="/">
<p className={styles.percentile_text_link}>
Start your quest
</p>
</Link>
</div>
</div>
)
) : null}
<Divider
orientation="horizontal"
Expand Down Expand Up @@ -447,38 +443,40 @@ export default function Page() {
? isMobile
? rankOrderMobile.map((position, index) => {
const item =
leaderboardToppers?.[
timeFrameMap[
duration as keyof typeof timeFrameMap
] as keyof typeof leaderboardToppers
]?.best_users?.[position - 1];
leaderboardToppers?.best_users?.[position - 1];
if (!item) return null;
return (
<RankCard
key={index}
name={item?.address}
experience={item?.xp}
trophy={item?.achievements}
position={position}
/>
<Link
key={item?.address}
href={`/${decimalToHex(item.address)}`}
>
<RankCard
key={index}
name={item?.address}
experience={item?.xp}
trophy={item?.achievements}
position={position}
/>
</Link>
);
})
: rankOrder.map((position, index) => {
const item =
leaderboardToppers?.[
timeFrameMap[
duration as keyof typeof timeFrameMap
] as keyof typeof leaderboardToppers
]?.best_users?.[position - 1];
leaderboardToppers?.best_users?.[position - 1];
if (!item) return null;
return (
<RankCard
key={index}
name={item?.address}
experience={item?.xp}
trophy={item?.achievements}
position={position}
/>
<Link
key={item?.address}
href={`/${decimalToHex(item.address)}`}
>
<RankCard
key={index}
name={item?.address}
experience={item?.xp}
trophy={item?.achievements}
position={position}
/>
</Link>
);
})
: null}
Expand Down
1 change: 0 additions & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import TrendingQuests from "@components/pages/home/trending";
import Blur from "@components/shapes/blur";
import { QuestsContext } from "@context/QuestsProvider";
import FeaturedQuest from "@components/UI/featured_banner/featuredQuest";
import { getBoosts } from "@services/apiService";

export default function Page() {
const router = useRouter();
Expand Down
28 changes: 14 additions & 14 deletions app/partnership/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Crosses from "@components/shapes/crosses";
import MainTitle from "@components/UI/titles/mainTitle";
import Cross from "@components/shapes/cross";
import Stats from "@components/UI/stats/stats";
import Box from "@components/UI/box";
import Dots from "@components/shapes/dots";
import OnScrollIntoView from "@components/animations/onScrollIntoView";
import Blur from "@components/shapes/blur";
Expand Down Expand Up @@ -47,6 +46,9 @@ export default function Page() {
src="/visuals/partners/partnershipHeader.webp"
className={styles.headerImg}
/>
<div className={styles.dots3}>
<Dots />
</div>
</div>
<div className={styles.cross1}>
<Cross />
Expand Down Expand Up @@ -149,19 +151,17 @@ export default function Page() {
</OnScrollIntoView>
</div>
<section className={`${styles.section} ${styles.partnerSection}`}>
<Box>
<CategoryTitle
subtitle="Our partners"
title="They worked with us"
/>
<div className={styles.partnersContainer}>
<CDNImg src="/partners/braavosLogo.svg" />
<CDNImg src="/partners/zklendLogo.svg" />
<CDNImg src="/partners/sithswapLogo.svg" />
<CDNImg src="/partners/jediswapLogo.svg" />
<CDNImg src="/partners/avnuLogo.svg" />
</div>
</Box>
<CategoryTitle
subtitle="Our partners"
title="They worked with us"
/>
<div className={styles.partners}>
<CDNImg src="/partners/braavosLogo.svg" />
<CDNImg src="/partners/zklendLogo.svg" />
<CDNImg src="/partners/sithswapLogo.svg" />
<CDNImg src="/partners/jediswapLogo.svg" />
<CDNImg src="/partners/avnuLogo.svg" />
</div>
<div className={styles.lastCrosses}>
<Crosses leftSide={false} number={2} xDecal={-50} />
</div>
Expand Down
3 changes: 2 additions & 1 deletion app/quest/[questPage]/quest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useAccount } from "@starknet-react/core";
import { starknetIdAppLink } from "@utils/links";
import BannerPopup from "@components/UI/menus/bannerPopup";
import { useDomainFromAddress } from "@hooks/naming";
import NftIssuerTag from "@components/quests/nftIssuerTag";

type QuestPageProps = {
questId: string;
Expand Down Expand Up @@ -117,7 +118,7 @@ const Quest: FunctionComponent<QuestPageProps> = ({
<RewardSkeleton />
) : (
<div className="mb-4">
<NftIssuer
<NftIssuerTag
issuer={{
name: quest.issuer,
logoFavicon: quest.logo,
Expand Down
3 changes: 3 additions & 0 deletions components/UI/changeWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ const ChangeWallet: FunctionComponent<ChangeWalletProps> = ({
}
}
})}
<p onClick={() => closeWallet()} className={styles.closeMobile}>
Close
</p>
</div>
</Modal>
);
Expand Down
14 changes: 9 additions & 5 deletions components/UI/featured_banner/featuredQuest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@ const FeaturedQuest: FunctionComponent<FeaturedQuestProps> = ({
return onClick ? (
<div className={styles.featuredQuest}>
<div className={styles.featuredQuestInfos}>
<p className="mt-2 text-start">{heading}</p>
<p className={styles.featuredQuestHeading}>{heading}</p>
<h3 className={styles.featuredQuestTitle}>{title}</h3>
<p className="text-gray-200 mt-4 text-start">{desc}</p>
<p className={styles.featuredQuestDescription}>{desc}</p>
<div className="flex mt-4 mb-4 items-center">
<CDNImg width={20} src={issuer?.logoFavicon} />
<p className="text-white ml-2">{reward}</p>
<CDNImg
width={20}
src={issuer?.logoFavicon}
className={styles.featuredQuestRewardIcon}
/>
<p className={styles.featuredQuestReward}>{reward}</p>
</div>
<div>
<div className={styles.featuredQuestButtonContainer}>
<Button onClick={onClick}>Begin</Button>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/UI/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Footer: FunctionComponent = () => {
const route = usePathname();
if (
route?.includes(".stark") ||
isHexString(route?.slice(1, route.length) as string)
(isHexString(route?.slice(1, route.length) as string) && route !== "/")
)
return null;
return (
Expand Down
Loading

1 comment on commit 3a437ad

@vercel
Copy link

@vercel vercel bot commented on 3a437ad Dec 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.