Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MEP 16/10/24 #884

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/UI/profileCard/profileCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ const ProfileCard: FunctionComponent<ProfileCard> = ({
)}
</div>

<div className="flex flex-col h-full justify-between">
<div className="flex flex-col h-full justify-center">
<Typography type={TEXT_TYPE.BODY_SMALL} color="secondary" className={styles.accountCreationDate}>
{sinceDate ? `${sinceDate}` : ""}
</Typography>
<Typography type={TEXT_TYPE.H2} className={styles.profile_name}>{identity.domain.domain}</Typography>
<Typography type={TEXT_TYPE.H2} className={`${styles.profile_name} mt-2`}>{identity.domain.domain}</Typography>
<div className={styles.address_div}>
<CopyAddress
address={identity?.owner ?? ""}
Expand Down
194 changes: 91 additions & 103 deletions components/discover/claimModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,145 +10,114 @@ import AppIcon from "./appIcon";
import TokenIcon from "./tokenIcon";
import { useNotification } from "@context/NotificationProvider";
import Loading from "@app/loading";
import { useAccount, useContractWrite } from "@starknet-react/core";
import { RewardsPerProtocol } from "../../types/backTypes";
import { getRewards } from "@services/apiService";
import { gweiToEth } from "@utils/feltService";

type RewardItem = {
appName: string,
currencies: { currencyName: string, value: number }[]
}
appName: string;
currencies: { currencyName: string; value: number }[];
};

type CurrencyRowProps = {
currencyName: string;
currencyValue: number;
}
};

type ClaimModalProps = {
closeModal: () => void;
showSuccess: () => void;
open: boolean;
};

const RewardComponent: FunctionComponent<RewardItem> = ({ appName, currencies }) => (
<div className="flex w-full justify-between items-center bg-background px-2 py-3 my-1 rounded-lg">
const RewardComponent: FunctionComponent<RewardItem> = ({
appName,
currencies,
}) => (
<div className="flex w-full justify-between items-center bg-background px-4 py-3 my-1 rounded-lg">
<div className="flex flex-row gap-4">
<AppIcon app={appName} />
<AppIcon
app={appName}
imageDimensions={{
width: 25,
height: 25,
}}
customStyle={{
border: ".5px solid #fff",
}}
/>
<Typography type={TEXT_TYPE.BODY_MIDDLE}>
{appName}
<span className="capitalize">{appName}</span>
</Typography>
</div>
<div className="flex w-fit flex-col items-end">
{currencies.map((currency, idx) => (
<CurrencyRow key={idx} currencyName={currency.currencyName} currencyValue={currency.value} />
<CurrencyRow
key={idx}
currencyName={currency.currencyName}
currencyValue={currency.value}
/>
))}
</div>
</div>
);

const CurrencyRow: FunctionComponent<CurrencyRowProps> = ({ currencyName, currencyValue }) => (
const CurrencyRow: FunctionComponent<CurrencyRowProps> = ({
currencyName,
currencyValue,
}) => (
<div className="flex flex-row items-center gap-4">
<Typography type={TEXT_TYPE.BODY_SMALL}>
{currencyValue < 1000 ? currencyValue : `${currencyValue / 1000}K`}
</Typography>
<Typography type={TEXT_TYPE.BODY_SMALL}>
{currencyName}
</Typography>
<Typography type={TEXT_TYPE.BODY_SMALL}>{currencyName}</Typography>
<TokenIcon token={currencyName} />
</div>
);

const ClaimModal: FunctionComponent<ClaimModalProps> = ({
closeModal,
showSuccess,
open
open,
}) => {
const [claimRewards, setClaimRewards] = useState<RewardItem[]>();
const [loading, setLoading] = useState<boolean>(true);
const { showNotification } = useNotification();
const { address } = useAccount();
const [rewards, setRewards] = useState<RewardsPerProtocol | null>(null);
const [calls, setCalls] = useState<Call[]>([]);
const { writeAsync: execute } = useContractWrite({
calls: calls,
});

const getClaimRewards = useCallback(async () => {
// TODO: Implement fetch from backend. Returning mock values.
try {
setLoading(true);
const rewards = [
{
appName: "EKUBO",
currencies: [
{ currencyName: "STRK", value: 11570 }
],
},
{
appName: "NOSTRA",
currencies: [
{ currencyName: "STRK", value: 12.124 },
{ currencyName: "ETH", value: 1.1245 }
],
},
{
appName: "zkLend",
currencies: [
{ currencyName: "USDT", value: 124.12 }
],
},
{
appName: "VESU",
currencies: [
{ currencyName: "STRK", value: 36 }
],
},
{
appName: "Nimbora",
currencies: [
{ currencyName: "STRK", value: 70.145 }
],
},
{
appName: "zkLend",
currencies: [
{ currencyName: "USDT", value: 124.12 }
],
},
{
appName: "VESU",
currencies: [
{ currencyName: "STRK", value: 36 }
],
},
{
appName: "Nimbora",
currencies: [
{ currencyName: "STRK", value: 70.145 }
],
},
];
const res = await new Promise<RewardItem[]>(resolve => setTimeout(() => resolve(rewards), 2000));
setClaimRewards(res);
setLoading(false);
} catch (error) {
setLoading(false);
showNotification("Error while fetching rewards", "error");
console.log("Error while fetching rewards", error);
}
}, []);
useEffect(() => {
if (!address) return;
getRewards(address)
.then((res) => {
setRewards(res?.rewards);
setCalls(res?.calls);
setLoading(false);
})
.catch((error) => {
showNotification("Error while fetching rewards", "error");
console.log("Error while fetching rewards", error);
});
}, [address]);

const doClaimRewards = useCallback(async () => {
// TODO: Implement logic to claim rewards
try {
setLoading(true);
await new Promise(resolve => setTimeout(resolve, 2000));
await execute();
setLoading(false);
closeModal();
showSuccess();
} catch (error) {
setLoading(false);
showNotification("Error while claiming rewards", "error");
console.log("Error while claiming rewards", error);
console.log("Error while claiming rewards", error, calls);
}
}, []);

useEffect(() => {
if (open) {
getClaimRewards();
}
}, [open, getClaimRewards]);
}, [calls]);

return (
<Modal
Expand All @@ -157,14 +126,19 @@ const ClaimModal: FunctionComponent<ClaimModalProps> = ({
aria-label="Reward claim success modal"
open={open}
>
<div className={`${styles.popup} !overflow-y-hidden !rounded-2xl !mt-0 !px-1 !py-1 md:!px-0 md:!py-0`}>
<div
className={`${styles.popup} !overflow-y-hidden !rounded-2xl !mt-0 !px-1 !py-1 md:!px-0 md:!py-0`}
>
<Loading isLoading={loading} loadingType="spinner">
<div className={`${styles.popupContent} !px-0 !pt-6 !pb-0 md:!px-12 md:!pt-14`}>
<div
className={`${styles.popupContent} !px-0 !pt-6 !pb-0 md:!px-12 md:!pt-14`}
>
<div className="flex w-full flex-col self-start">
<div className="flex w-full lg:flex-row flex-col-reverse lg:items-start items-center justify-between gap-4 md:pb-2">
<div className="flex flex-col gap-4 lg:text-left text-center">
<Typography type={TEXT_TYPE.BODY_MIDDLE}>
Collect your rewards from all supported protocols on Starknet
Collect your rewards from all supported protocols on
Starknet
</Typography>
<Typography type={TEXT_TYPE.H4}>
Claim Your Rewards
Expand All @@ -178,25 +152,39 @@ const ClaimModal: FunctionComponent<ClaimModalProps> = ({
style={{ transform: "rotateY(190deg)" }}
/>
</div>
<div className="flex w-full flex-col mt-4 max-h-80 overflow-auto">
{!claimRewards ?
<Typography type={TEXT_TYPE.BODY_DEFAULT}>No rewards available</Typography>
:
claimRewards.map((item, index) => (
<RewardComponent key={index} appName={item.appName} currencies={item.currencies} />
))}
<div className="flex w-full flex-col py-4 max-h-80 overflow-auto">
{rewards && calls.length > 0 ? (
Object.entries(rewards)
.filter(([key, rewardList]) => key && rewardList.length > 0)
.map(([key, rewardList]) => (
<RewardComponent
key={key}
appName={key}
currencies={rewardList.map((reward) => ({
currencyName: reward.token_symbol,
value:
Math.round(
parseFloat(gweiToEth(reward.amount)) * 100
) / 100,
}))}
/>
))
) : (
<Typography type={TEXT_TYPE.BODY_DEFAULT}>
No rewards available
</Typography>
)}
</div>
</div>
</div>
<div className={`${styles.bottomContent} !gap-6 !py-6 !px-5`}>
<div className="flex w-full justify-between items-center">
<button onClick={closeModal} aria-label="Cancel claiming rewards">
<Typography type={TEXT_TYPE.BODY_MIDDLE}>
Cancel
</Typography>
<Typography type={TEXT_TYPE.BODY_MIDDLE}>Cancel</Typography>
</button>
<div className="w-fit">
<Button disabled={claimRewards ? false : true}
<Button
disabled={!calls || calls.length === 0 || loading}
onClick={doClaimRewards}
>
Claim all
Expand All @@ -210,4 +198,4 @@ const ClaimModal: FunctionComponent<ClaimModalProps> = ({
);
};

export default ClaimModal;
export default ClaimModal;
Loading