Skip to content

Commit

Permalink
feat: add nft view in profile (#190)
Browse files Browse the repository at this point in the history
* feat: update profile view

* fix: remove unecessary comments

* fix: achievement building size

* fix: typings

* fix: image fills cards

* fix: styles

* fix: font size

* fix: center addr in profile
  • Loading branch information
irisdv authored Oct 5, 2023
1 parent 0f6a4a9 commit 74f4ce6
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 111 deletions.
19 changes: 7 additions & 12 deletions components/lands/land.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ type LandProps = {
address: string;
isOwner: boolean;
isMobile: boolean;
setSinceDate: (s: string | null) => void;
setTotalNfts: (nb: number) => void;
setAchievementCount: (n: number) => void;
setSinceDate: (date: string | null) => void;
setAchievements: (achievements: BuildingsInfo[]) => void;
setSoloBuildings: (buildings: BuildingsInfo[]) => void;
};

export const Land = ({
address,
isOwner,
isMobile,
setSinceDate,
setTotalNfts,
setAchievementCount,
setAchievements,
setSoloBuildings,
}: LandProps) => {
const [userNft, setUserNft] = useState<BuildingsInfo[]>();
const [hasNFTs, setHasNFTs] = useState<boolean>(false);
Expand Down Expand Up @@ -68,7 +68,6 @@ export const Land = ({

// Fetch achievements from database and add building id from highest achievement level
const getBuildingsFromAchievements = async (filteredAssets: number[]) => {
let count = 0;
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_LINK}/achievements/fetch?addr=${address}`
Expand All @@ -79,13 +78,11 @@ export const Land = ({
for (let i = result.achievements.length - 1; i >= 0; i--) {
if (result.achievements[i].completed) {
filteredAssets.push(result.achievements[i].id);
if (i === result.achievements.length - 1) count++;
if (result.category_type === "levels") break;
}
}
});
}
setAchievementCount(count);
} catch (error) {
console.error("An error occurred while fetching achievements", error);
}
Expand All @@ -103,6 +100,8 @@ export const Land = ({
if (results && results.length > 0) {
setUserNft(results);
setHasNFTs(true);
setSoloBuildings(results.filter((x) => x.id >= 64000));
setAchievements(results.filter((x) => x.id < 64000));
} else setHasNFTs(false);
} catch (error) {
console.error("An error occurred while fetching buildings info", error);
Expand All @@ -114,7 +113,6 @@ export const Land = ({
const filteredAssets: number[] = [];
const starkFighter: number[] = [];
let sinceDate = 0;
let nftCounter = 0;

assets.forEach((asset: StarkscanNftProps) => {
if (asset.minted_at_timestamp < sinceDate || sinceDate === 0)
Expand All @@ -123,8 +121,6 @@ export const Land = ({
if (
asset.contract_address === process.env.NEXT_PUBLIC_QUEST_NFT_CONTRACT
) {
nftCounter++;

if (asset.name && Object.values(SoloBuildings).includes(asset.name)) {
filteredAssets.push(
SoloBuildings[asset.name as keyof typeof SoloBuildings]
Expand Down Expand Up @@ -156,7 +152,6 @@ export const Land = ({
await getBuildingsInfo(filteredAssets);

setIsReady(true);
setTotalNfts(nftCounter);
setSinceDate(memberSince(sinceDate));
};

Expand Down
138 changes: 70 additions & 68 deletions pages/[addressOrDomain].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { minifyAddress } from "../utils/stringService";
import { utils } from "starknetid.js";
import ErrorScreen from "../components/UI/screens/errorScreen";
import ProfileCard from "../components/UI/profileCard";
import TrophyIcon from "../components/UI/iconsComponents/icons/trophyIcon";
import { Land } from "../components/lands/land";
import { hasVerifiedSocials } from "../utils/profile";
import { useMediaQuery } from "@mui/material";
Expand All @@ -22,7 +21,7 @@ import CopyIcon from "../components/UI/iconsComponents/icons/copyIcon";
const AddressOrDomain: NextPage = () => {
const router = useRouter();
const { addressOrDomain } = router.query;
const { address, connector } = useAccount();
const { address } = useAccount();
const { connectors, connect } = useConnectors();
const { starknetIdNavigator } = useContext(StarknetIdJsContext);
const [initProfile, setInitProfile] = useState(false);
Expand All @@ -31,12 +30,11 @@ const AddressOrDomain: NextPage = () => {
const [copied, setCopied] = useState(false);
const [isOwner, setIsOwner] = useState(false);
const dynamicRoute = useRouter().asPath;
const isBraavosWallet = connector && connector.id === "braavos";
const [braavosScore, setBraavosScore] = useState<number>(0);
const isMobile = useMediaQuery("(max-width:768px)");
const [sinceDate, setSinceDate] = useState<string | null>(null);
const [totalNFTs, setTotalNfts] = useState<number>(0);
const [achievementCount, setAchievementCount] = useState<number>(0);
const [achievements, setAchievements] = useState<BuildingsInfo[]>([]);
const [soloBuildings, setSoloBuildings] = useState<BuildingsInfo[]>([]);
const [selectedTab, setSelectedTab] = useState<LandTabs>("nfts");

useEffect(() => setNotFound(false), [dynamicRoute]);

Expand Down Expand Up @@ -193,20 +191,6 @@ const AddressOrDomain: NextPage = () => {
}
}, [addressOrDomain, address, dynamicRoute]);

useEffect(() => {
// connector is of type Connector<any> in starknet-react
// but _wallet which is supposed to be of type IStarknetWindowObject is set as private
if (connector && connector.id === "braavos") {
(connector as any)._wallet
.request({ type: "wallet_getStarknetProScore" })
.then((score: BraavosScoreProps) => {
setBraavosScore(score.score);
});
} else {
setBraavosScore(0);
}
}, [connector, addressOrDomain, address]);

const copyToClipboard = () => {
setCopied(true);
navigator.clipboard.writeText(identity?.addr as string);
Expand Down Expand Up @@ -241,8 +225,8 @@ const AddressOrDomain: NextPage = () => {
isOwner={isOwner}
isMobile={isMobile}
setSinceDate={setSinceDate}
setTotalNfts={setTotalNfts}
setAchievementCount={setAchievementCount}
setAchievements={setAchievements}
setSoloBuildings={setSoloBuildings}
/>
<div className={styles.profiles}>
<ProfileCard
Expand Down Expand Up @@ -296,60 +280,78 @@ const AddressOrDomain: NextPage = () => {
</div>
}
/>
{hasVerifiedSocials(identity) ? (
<ProfileCard
title="Social network"
content={<SocialMediaActions identity={identity} />}
/>
) : null}
<ProfileCard
title="Progress"
content={
<div className={styles.progress}>
{/* We do not have xp yet */}
{/* <div className="flex flex-col gap-1">
<div className={styles.polygonContainer}>
<img src="/icons/polygon.svg" alt="polygon icon" />
<span className={styles.xp}>XP</span>
</div>
<span>12</span>
</div> */}
<Tooltip
title="Number of NFTs owned from starknet quest"
arrow
>
<div className="flex flex-col gap-1">
<span className={styles.trophy}>
<TrophyIcon width="20" color="#696045" />
</span>
<span>{totalNFTs}</span>
<>
<div className={styles.tabs}>
<div
className={`${styles.tab} ${
selectedTab === "nfts" ? styles.selectedTab : ""
}`}
onClick={() => setSelectedTab("nfts")}
>
NFTs unlocked ({soloBuildings.length})
</div>
</Tooltip>
<Tooltip title="Number of achievements completed" arrow>
<div className="flex flex-col gap-1">
<img
src="/icons/verifyBadge.svg"
alt="verfy badge icon"
width={25}
/>
<span>{achievementCount}</span>
<div
className={`${styles.tab} ${
selectedTab === "achievements" ? styles.selectedTab : ""
}`}
onClick={() => setSelectedTab("achievements")}
>
Achievements ({achievements.length})
</div>
</div>
{selectedTab === "nfts" ? (
<div className={styles.gallery}>
{soloBuildings.map((building) => {
return (
<div
key={building.id}
className={styles.nftContainer}
>
<img
src={building.img_url}
className={styles.nftImage}
/>
<p className={styles.nftName}>{building.name}</p>
</div>
);
})}
</div>
</Tooltip>
{isOwner && isBraavosWallet ? (
<Tooltip title="Your Braavos Pro score" arrow>
<div className="flex flex-col gap-1">
<img
src="/braavos/braavosLogo.svg"
alt="braavos icon"
width={24}
/>
<span>{braavosScore}</span>
</div>
</Tooltip>
) : null}
</div>
{selectedTab === "achievements" ? (
<div className={styles.gallery}>
{achievements.map((achievement) => {
return (
<div
key={achievement.id}
className={styles.nftContainer}
>
<img
src={achievement.img_url}
className={styles.achievementImage}
/>
<p className={styles.achievementLvl}>
Level {achievement.level}
</p>
<p className={styles.achievementName}>
{achievement.name}
</p>
</div>
);
})}
</div>
) : null}
</>
}
/>
{hasVerifiedSocials(identity) ? (
<ProfileCard
title="Social network"
content={<SocialMediaActions identity={identity} />}
/>
) : null}
</div>
</>
) : (
Expand Down
Loading

1 comment on commit 74f4ce6

@vercel
Copy link

@vercel vercel bot commented on 74f4ce6 Oct 5, 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.