diff --git a/app/allocation/components/BudgetAllocation.tsx b/app/allocation/components/BudgetAllocation.tsx index 931174e..b5cb394 100644 --- a/app/allocation/components/BudgetAllocation.tsx +++ b/app/allocation/components/BudgetAllocation.tsx @@ -20,6 +20,9 @@ interface IBudgetAllocationProps extends BudgetCategory { delegations: number loading: boolean username?: string + isBadgeholder: boolean + bhCategory: string + categorySlug: string onDelegate: () => void onScore: () => void } @@ -33,6 +36,9 @@ const BudgetAllocation: React.FC = ({ loading, progress = CollectionProgressStatusEnum.Pending, username, + isBadgeholder, + bhCategory, + categorySlug, onScore, onDelegate, }) => { @@ -55,6 +61,9 @@ const BudgetAllocation: React.FC = ({ progress={progress} delegations={delegations} isAutoConnecting={isAutoConnecting} + isBadgeholder={isBadgeholder} + bhCategory={bhCategory} + categorySlug={categorySlug} /> ); } diff --git a/app/allocation/components/CategoryAllocation.tsx b/app/allocation/components/CategoryAllocation.tsx index 4b23e74..dc48803 100644 --- a/app/allocation/components/CategoryAllocation.tsx +++ b/app/allocation/components/CategoryAllocation.tsx @@ -34,6 +34,9 @@ interface CategoryAllocationProps extends TCategory { delegations: number loading: boolean username?: string + isBadgeholder: boolean + bhCategory: string + categorySlug: string onDelegate: () => void onScore: () => void onLockClick: () => void @@ -53,6 +56,9 @@ const CategoryAllocation: FC = ({ delegations, loading, username, + isBadgeholder, + bhCategory, + categorySlug, onDelegate, onScore, onLockClick, @@ -104,6 +110,9 @@ const CategoryAllocation: FC = ({ progress={progress} isAutoConnecting={isAutoConnecting} delegations={delegations} + isBadgeholder={isBadgeholder} + bhCategory={bhCategory} + categorySlug={categorySlug} /> ); } diff --git a/app/allocation/components/EOA/ConnectEOAModal.tsx b/app/allocation/components/EOA/ConnectEOAModal.tsx index 9ad0965..f9122a2 100644 --- a/app/allocation/components/EOA/ConnectEOAModal.tsx +++ b/app/allocation/components/EOA/ConnectEOAModal.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react'; +import { FC, useState } from 'react'; import Image from 'next/image'; import { useActiveWallet } from 'thirdweb/react'; import { Step } from './EmailLoginModal'; @@ -7,29 +7,47 @@ import { axiosInstance } from '@/app/utils/axiosInstance'; type TConnectEOAModalProps = { email: string setStep: (step: number) => void -} +}; -const ConnectEOAModal: FC = ({ - email, - setStep, -}) => { +const ConnectEOAModal: FC = ({ email, setStep }) => { const wallet = useActiveWallet(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); const connectEOA = async () => { - if (!wallet) return; - const msg = 'Sign in with Thirdweb wallet'; - const account = wallet?.getAccount(); + setLoading(true); + setError(null); + + if (!wallet) { + setError('Unable to connect to your wallet'); + setLoading(false); + return; + } + + try { + const msg = 'Sign in with Thirdweb wallet'; + const account = wallet?.getAccount(); - if (!account) return; + if (!account) { + setError('Unable to connect to your wallet'); + setLoading(false); + return; + } - const signature = await account.signMessage({ message: msg }); + const signature = await account.signMessage({ message: msg }); - await axiosInstance.post('auth/thirdweb/login', { - message: msg, - signature, - address: account.address, - }); - setStep(Step.SUCCESS); + await axiosInstance.post('auth/thirdweb/login', { + message: msg, + signature, + address: account.address, + }); + setLoading(false); + setStep(Step.SUCCESS); + } + catch (err) { + setError('An error occurred while connecting to your wallet'); + setLoading(false); + } }; return ( @@ -54,11 +72,21 @@ const ConnectEOAModal: FC = ({

Please link this with your connected ETH address to continue.

+ + {error && ( +
+

+ An error occurred! +

+

{error}

+
+ )} + diff --git a/app/allocation/components/EOA/EmailLoginModal.tsx b/app/allocation/components/EOA/EmailLoginModal.tsx index 9c26e03..66914f8 100644 --- a/app/allocation/components/EOA/EmailLoginModal.tsx +++ b/app/allocation/components/EOA/EmailLoginModal.tsx @@ -183,6 +183,7 @@ const EmailLoginModal = ({ closeModal, selectedCategoryId }: TEmailLoginModalPro handleGoBack={goBack} setStep={setStep} resendOTP={sendOTP} + closeModal={closeModal} /> )} diff --git a/app/allocation/components/EOA/MethodSelection.tsx b/app/allocation/components/EOA/MethodSelection.tsx index dca0977..f39c539 100644 --- a/app/allocation/components/EOA/MethodSelection.tsx +++ b/app/allocation/components/EOA/MethodSelection.tsx @@ -31,6 +31,7 @@ export const MethodSelection: FC = ({ setOtpData, sendOTP, setStep, + closeModal, }) => { const { connect } = useConnect(); @@ -50,21 +51,17 @@ export const MethodSelection: FC = ({ const smartWallet = await createSmartWalletFromEOA(account); setOAuthData({ ...oAuthData, loading: false }); + connect(smartWallet); + if (!personalWalletId) { - setOAuthData({ - ...oAuthData, - loading: true, - error: 'There was a problem connecting to your Google account', - }); + setStep(Step.CONNECT_EOA); + setPickedMethod(null); } else { - console.log('Connecting to smart wallet'); - connect(smartWallet); - setStep(Step.CONNECT_EOA); + closeModal(); } } catch (error: any) { - console.error(error); setOAuthData({ ...oAuthData, loading: true, diff --git a/app/allocation/components/EOA/OTPVerification.tsx b/app/allocation/components/EOA/OTPVerification.tsx index 454fe32..7d08802 100644 --- a/app/allocation/components/EOA/OTPVerification.tsx +++ b/app/allocation/components/EOA/OTPVerification.tsx @@ -21,6 +21,7 @@ interface IOTPVerificationProps { handleGoBack: () => void setStep: (step: number) => void resendOTP: () => void + closeModal: () => void } const FIVE_MINUTES = 1 * 60 * 1000; @@ -32,6 +33,7 @@ export const OTPVerification: FC = ({ handleGoBack, setStep, resendOTP, + closeModal, }) => { const { connect } = useConnect(); @@ -118,16 +120,19 @@ export const OTPVerification: FC = ({ const smartWallet = await createSmartWalletFromEOA(account); + setOtpData({ + ...otpData, + loading: false, + otpStatus: OtpStatus.VERIFIED, + }); + + connect(smartWallet); + if (!personalWalletId) { - setOtpData({ - ...otpData, - loading: false, - otpStatus: OtpStatus.INCORRECT, - }); + setStep(Step.CONNECT_EOA); } else { - connect(smartWallet); - setStep(Step.CONNECT_EOA); + closeModal(); } } catch { diff --git a/app/allocation/components/ProgressCards/PendingCategory.tsx b/app/allocation/components/ProgressCards/PendingCategory.tsx index f3150ff..516ee6b 100644 --- a/app/allocation/components/ProgressCards/PendingCategory.tsx +++ b/app/allocation/components/ProgressCards/PendingCategory.tsx @@ -6,6 +6,9 @@ type TPendingCategoryProps = { progress: string isAutoConnecting: boolean delegations?: number + isBadgeholder: boolean + bhCategory: string + categorySlug: string }; const PendingCategory = ({ @@ -14,18 +17,25 @@ const PendingCategory = ({ isAutoConnecting, delegations, progress, + isBadgeholder, + bhCategory, + categorySlug, }: TPendingCategoryProps) => { return (
@@ -33,7 +43,7 @@ const PendingCategory = ({ onClick={onDelegate} className={`w-[48%] rounded-md border py-3 text-sm font-medium ${ isAutoConnecting ? 'bg-gray-300 text-gray-600' : 'text-gray-700' - }`} + } ${isBadgeholder && bhCategory === categorySlug ? 'hidden' : ''}`} disabled={isAutoConnecting} > Delegate @@ -53,14 +63,12 @@ const PendingCategory = ({

)} - {progress === 'WIP' && ( + {progress === 'WIP' + && !(isBadgeholder && bhCategory !== categorySlug) && (

Voting

)} - {/*
-

Voting

-
*/}
); }; diff --git a/app/allocation/page.tsx b/app/allocation/page.tsx index 29f2891..7fd0d89 100644 --- a/app/allocation/page.tsx +++ b/app/allocation/page.tsx @@ -18,7 +18,12 @@ import { modifyPercentage, RankItem } from './utils'; import { ArrowRightIcon } from '@/public/assets/icon-components/ArrowRight'; import { ArrowLeft2Icon } from '@/public/assets/icon-components/ArrowLeft2'; import { CustomizedSlider } from './components/Slider'; -import { categoryIdSlugMap, categorySlugIdMap, convertCategoryToLabel, formatBudget } from '../comparison/utils/helpers'; +import { + categoryIdSlugMap, + categorySlugIdMap, + convertCategoryToLabel, + formatBudget, +} from '../comparison/utils/helpers'; import { useCategories } from '../comparison/utils/data-fetching/categories'; import WorldIdSignInSuccessModal from './components/WorldIdSignInSuccessModal'; import FarcasterModal from './components/FarcasterModal'; @@ -28,15 +33,21 @@ import FarcasterSuccess from '../delegation/farcaster/FarcasterSuccess'; import { axiosInstance } from '../utils/axiosInstance'; import { TargetDelegate } from '../delegation/farcaster/types'; import { useGetDelegationStatus } from '@/app/utils/getConnectionStatus'; -import { ICategory, CollectionProgressStatusEnum } from '../comparison/utils/types'; +import { + ICategory, + CollectionProgressStatusEnum, +} from '../comparison/utils/types'; import SmallSpinner from '../components/SmallSpinner'; import { useCategoryRankings, useUpdateCategoriesRanking, } from '@/app/comparison/utils/data-fetching/ranking'; -import { uploadBallot } from '../utils/wallet/agora-login'; +import { uploadBallot, getJWTData } from '../utils/wallet/agora-login'; import { useAuth } from '../utils/wallet/AuthProvider'; -import { ballotSuccessPost, getBallot } from '../comparison/ballot/useGetBallot'; +import { + ballotSuccessPost, + getBallot, +} from '../comparison/ballot/useGetBallot'; import BallotError from '../comparison/ballot/modals/BallotError'; import BallotLoading from '../comparison/ballot/modals/BallotLoading'; import BallotSuccessModal from '../comparison/ballot/modals/BallotSuccessModal'; @@ -70,6 +81,7 @@ const AllocationPage = () => { const router = useRouter(); const { address } = useAccount(); const { loggedToAgora } = useAuth(); + const { isBadgeholder, category } = getJWTData(); const { data: categories, isLoading: categoriesLoading } = useCategories(); const { data: delegations, isLoading: delegationsLoading } @@ -83,7 +95,9 @@ const AllocationPage = () => { const budgetDelegateToYou = delegations?.toYou?.budget; const budgetDelegateFromYou = delegations?.fromYou?.budget; - const [ballotState, setBallotState] = useState(BallotState.Initial); + const [ballotState, setBallotState] = useState( + BallotState.Initial + ); const [totalValue, setTotalValue] = useState(categoryRankings?.budget || 0); const [percentageError, setPercentageError] = useState(); const [isOpenFarcasterModal, setIsOpenFarcasterModal] = useState(false); @@ -110,7 +124,8 @@ const AllocationPage = () => { const { mutate: updateCategoriesRanking } = useUpdateCategoriesRanking({ budget: totalValue, - allocationPercentages: categoriesRanking?.map(el => el.percentage / 100) || [], + allocationPercentages: + categoriesRanking?.map(el => el.percentage / 100) || [], }); const handleDelegate = async (username: string, target: TargetDelegate) => { @@ -121,15 +136,15 @@ const AllocationPage = () => { targetUsername: username, }); - queryClient.refetchQueries(({ + queryClient.refetchQueries({ queryKey: ['fetch-delegates'], - })); - queryClient.refetchQueries(({ + }); + queryClient.refetchQueries({ queryKey: ['category-ranking'], - })); - queryClient.refetchQueries(({ + }); + queryClient.refetchQueries({ queryKey: ['categories'], - })); + }); setTargetDelegate(target); setDelegationState(DelegationState.Success); }; @@ -183,7 +198,8 @@ const AllocationPage = () => { }; const handleUploadBallot = async () => { - if (loggedToAgora === 'error' || loggedToAgora === 'initial' || !address) return; + if (loggedToAgora === 'error' || loggedToAgora === 'initial' || !address) + return; setBallotState(BallotState.Loading); // const agoraPayload = await isLoggedInToAgora(address); @@ -197,7 +213,8 @@ const AllocationPage = () => { setBallotState(BallotState.Success); } catch (e: any) { - if (e.response.data.pwCode === 'e-1005') setBallotState(BallotState.ErrorNotReady); + if (e.response.data.pwCode === 'e-1005') + setBallotState(BallotState.ErrorNotReady); else setBallotState(BallotState.Error); } }; @@ -247,9 +264,7 @@ const AllocationPage = () => { return (
{}} showCloseButton={false} > @@ -260,12 +275,16 @@ const AllocationPage = () => { /> )} {ballotState === BallotState.Loading && } - {ballotState === BallotState.Error && } - {ballotState === BallotState.ErrorNotReady && typeof loggedToAgora === 'object' - && ( + {ballotState === BallotState.Error && ( + + )} + {ballotState === BallotState.ErrorNotReady + && typeof loggedToAgora === 'object' && ( { setBallotState(BallotState.Initial); }} + onClick={() => { + setBallotState(BallotState.Initial); + }} /> )} @@ -420,6 +439,9 @@ const AllocationPage = () => { progress={dbudgetProgress} delegations={budgetDelegateToYou?.length || 0} loading={delegationsLoading} + isBadgeholder={isBadgeholder} + bhCategory={category} + categorySlug={category} onDelegate={() => { setCategoryToDelegate(budgetCategory); setDelegationState(DelegationState.DelegationMethod); @@ -427,9 +449,7 @@ const AllocationPage = () => { onScore={() => { setAllocatingBudget(true); }} - username={ - budgetDelegateFromYou?.metadata?.username - } + username={budgetDelegateFromYou?.metadata?.username} /> )} {categories.map((cat) => { @@ -446,6 +466,9 @@ const AllocationPage = () => { allocationPercentage={rank?.percentage || 0} allocationBudget={rank?.budget || 0} loading={delegationsLoading} + isBadgeholder={isBadgeholder} + bhCategory={category} + categorySlug={categoryIdSlugMap.get(cat.id)!} onDelegate={() => { setCategoryToDelegate(cat); setDelegationState(DelegationState.DelegationMethod); diff --git a/app/comparison/[category]/page.tsx b/app/comparison/[category]/page.tsx index 74dd709..3c83abf 100644 --- a/app/comparison/[category]/page.tsx +++ b/app/comparison/[category]/page.tsx @@ -38,6 +38,7 @@ import RevertLoadingModal from '../card/modals/RevertLoadingModal'; import StorageLabel from '@/app/lib/localStorage'; import { ProjectCardAI } from '../card/ProjectCardAI'; import EmailLoginModal from '@/app/allocation/components/EOA/EmailLoginModal'; +import PostVotingModal from '../ballot/modals/PostVotingModal'; export default function Home() { const { category } = useParams() ?? {}; @@ -62,7 +63,7 @@ export default function Home() { null ); const [showLoginModal, setShowLoginModal] = useState(false); - + const [showFinishModal, setShowFinishModal] = useState(false); const [sectionExpanded1, setSectionExpanded1] = useState({ repos: true, pricing: true, @@ -126,6 +127,8 @@ export default function Home() { useEffect(() => { if (!data || !address) return; if (data.pairs.length === 0) { + setShowFinishModal(true); + if (!project1 || !project2) { setProject1(mockProject1); setProject2(mockProject2); @@ -410,6 +413,7 @@ export default function Home() { || revertingBack || showPostRatingModal || showGoodRatingModal + || showFinishModal } onClose={() => {}} > @@ -439,6 +443,7 @@ export default function Home() { }} /> )} + {showFinishModal && } = ({ categorySlug, categoryLabel }) => { + return ( +
+ Celebration + +

+ Nice work! +

+ +

+ You’ve ranked all projects in the + {' '} + {categoryLabel} + {' '} + category. +

+ + + Show my results + +
+ ); +}; + +export default PostVoting; diff --git a/app/comparison/card/GrantBox.tsx b/app/comparison/card/GrantBox.tsx index 03b3021..7fb6b1c 100644 --- a/app/comparison/card/GrantBox.tsx +++ b/app/comparison/card/GrantBox.tsx @@ -9,7 +9,7 @@ import { USDIcon } from '@/public/assets/icon-components/Usd'; import { truncate } from '@/app/utils/methods'; interface Props { - type: 'grant' | 'investment' + type: 'grant' | 'investment' | 'retro_funding' title: string amount: string link: string | null @@ -56,15 +56,10 @@ const GrantBox: FC = ({ const { getCollapseProps, getToggleProps, isExpanded } = useCollapse(); const formatTitle = (title: string) => { - if (title === 'retroFunding') return 'Retro Funding'; - - const titleFormated = title.split('-').join(' '); if (type === 'grant') { - return 'Grant: ' + titleFormated; - } - else { - return titleFormated; + return 'Grant: ' + title.split('-').join(' '); } + else return title; }; return ( @@ -92,8 +87,6 @@ const GrantBox: FC = ({ {round && ( - Round - {' '} {round} )} diff --git a/app/comparison/card/Header-RF6.tsx b/app/comparison/card/Header-RF6.tsx index e88793f..89a23d5 100644 --- a/app/comparison/card/Header-RF6.tsx +++ b/app/comparison/card/Header-RF6.tsx @@ -73,8 +73,10 @@ const HeaderRF6: FC = ({ }, [badges]); useEffect(() => { + const HEADER_HEIGHT = 80; + const handleScroll = () => { - if (window.scrollY > 100) { + if (window.scrollY > HEADER_HEIGHT) { setIsBarFixed(true); } else { @@ -151,9 +153,7 @@ const HeaderRF6: FC = ({ {category} )} -
+
{activeBadges.length > 0 && (