import { Box, Button, ExternalLinkIcon, FormControl, FormHelperText, FormLabel, Heading, Image, InfoIcon, Input, Link, Spinner, Text, Tooltip, VStack, Wrap, WrapItem, } from '@metafam/ds'; import { generateUUID } from '@metafam/utils'; import React, { useCallback, useEffect, useMemo, useRef, useState, } from 'react'; import { MdRefresh } from 'react-icons/md'; import { DeworkData, getDeworkData, type Organisation, processDeworkData, } from 'utils/dework'; import DeworkLogo from '#assets/integrationLogos/deworkLogo.png'; import { MetaLink } from '#components/Link'; import { ProfileSection } from '#components/Section/ProfileSection'; import { Player, useUpsertDeworkProfileMutation } from '#graphql/autogen/hasura-sdk'; import { getPlayerDeworkUsername } from '#graphql/getDeworkUsername'; import { BoxTypes } from '#utils/boxTypes'; import { formatAddress } from '#utils/playerHelpers'; type Props = { player: Player; isOwnProfile?: boolean; editing?: boolean; }; type DeworkSectionWrapperProps = { children: React.ReactNode; }; type DeworkSectionHeadingProps = { text: string; }; export const DeworkSectionWrapper: React.FC = ({ children, }: { children: React.ReactNode; }) => ( {children} ); export const DeworkSectionHeading: React.FC = ({ text, }: { text: string; }) => ( {`${text}`} ); export const PlayerDework: React.FC = ({ player, isOwnProfile, editing, }) => { const [role, setRole] = useState('AddURL'); const [playerDeworkURL, setPlayerDeworkURL] = useState(''); const [addressMatch, setAddressMatch] = useState(false); const [deworkData, setDeworkData] = useState(); const connected = addressMatch && !playerDeworkURL; const [loading, setLoading] = useState(true); const noticeRef = useRef(null); useEffect(() => { const getDeworkUsername = async () => { getPlayerDeworkUsername(player.id).then( (res) => res && setPlayerDeworkURL(res as string), ); }; if (player?.id) { getDeworkUsername(); } }, [player?.id, player.accounts]); const getData = useCallback(async (address: string) => { setLoading(true); await getDeworkData(address).then((res: DeworkData) => { setDeworkData(res); const lowerCaseAddress = address.toLowerCase(); const lowerCaseResAddress = res?.address?.toLowerCase(); const hasTasks = res?.tasks?.length; // test if address matches dework data if (lowerCaseResAddress === lowerCaseAddress && hasTasks) { setAddressMatch(true); } else { setAddressMatch(false); } setLoading(false); }); }, []); useEffect(() => { getData(player?.ethereumAddress); // eslint-disable-next-line react-hooks/exhaustive-deps }, [player?.ethereumAddress]); const retryCall = async () => { await getData(player?.ethereumAddress); }; useEffect(() => { if (typeof window !== 'undefined') { // find the parent div of the noticeRef and position noticeRef at the top const parentDiv = noticeRef.current?.parentElement; if (parentDiv) { parentDiv.style.position = 'relative'; parentDiv.style.top = '0'; } } }, []); useMemo(() => { if (loading) { setRole('Loading'); } else if (playerDeworkURL) { setRole('DeworkProfile'); } else if (addressMatch && !playerDeworkURL) { setRole('AddURL'); } else { setRole('NoMatch'); } }, [loading, playerDeworkURL, addressMatch]); return ( retryCall()} /> {role !== 'NoMatch' && ( Dework logo )} ); }; const DeworkProfile: React.FC<{ data?: DeworkData; playerDeworkURL: string; }> = ({ data, playerDeworkURL }) => { const processedData = useMemo(() => data && processDeworkData(data), [data]); const deworkURL = `https://app.dework.xyz/${ playerDeworkURL ? `profile/${playerDeworkURL}` : '' }`; return ( {data && processedData && ( <> {data?.tasks?.length} {processedData.totalEarnedInUSDC.toFixed(2)} USD
{Number(processedData.totalSEEDsEarned) > 0 && ( <>{processedData.totalSEEDsEarned.toFixed(2)} SEED )}
{processedData?.tagGrouping.length > 0 ? ( processedData?.tagGrouping.map( (tag: { name: string; count: number }, i: number) => { const total: number = processedData?.tagGrouping.length; if (i < 3) { return ( {tag.name} {' '} ({tag.count}) {i === 2 && ( {`+${ total - 3 } other`} )} ); } return undefined; }, ) ) : ( No tasks )} {processedData?.uniqueOrganisations.length > 0 ? ( processedData?.uniqueOrganisations.map( (org: Organisation, i: number) => { const total: number = processedData?.uniqueOrganisations.length; if (i < 3) { return ( {org.name} {i === 2 && {`+${total - 3} other`}} ); } return undefined; }, ) ) : ( No organizations )} )} {data && ( See{' '}  complete  {' '} profile on Dework )}
); }; const PlayerDeworkView: React.FC<{ role: string; player: Player; playerDeworkURL: string; setPlayerDeworkURL: (url: string) => void; profileData?: DeworkData; retry: () => void; }> = ({ role, player, setPlayerDeworkURL, retry, profileData, playerDeworkURL, }) => { const currentView = { AddURL: ( ), Loading: , NoMatch: , DeworkProfile: ( ), }[role]; return <>{currentView}; }; const DeworkLink: React.FC<{ setPlayerDeworkURL: (url: string) => void; playerDeworkURL: string; player: Player; }> = ({ player, setPlayerDeworkURL, playerDeworkURL }) => { const [deworkURL, setDeworkURL] = useState(''); const [, upsertPlayerDework] = useUpsertDeworkProfileMutation(); const handleSetUserDeworkURL = async () => { try { const response = await upsertPlayerDework({ playerId: player?.id, identifier: deworkURL, }); // Handle the response if necessary. // For example, you might want to update the UI based on the mutation's result: if (response && response.data) { setPlayerDeworkURL(deworkURL); } } catch (error) { throw Error( `Error upserting the Dework profile: ${(error as Error).message}`, ); } }; return ( <> Input Dework Username setDeworkURL(value)} /> Enter exactly as written on Dework ); }; const NoMatch: React.FC<{ playerAddress: string; retry: () => void }> = ({ playerAddress, retry, }) => ( Wallets do not match{' '} We couldn’t find a Dework profile with the ETH address you used to connect with MetaGame. Go to your{' '} Dework {' '} profile and make sure you have connected with wallet{' '} {formatAddress(playerAddress)}. Connecting to a different wallet on Dework won’t result in any data loss or other issues. Go to Dework ); const Loading: React.FC = () => ( Looking for a Dework profile with the same ETH address );