Skip to content

Commit

Permalink
Merge pull request #525 from us3r-network/F-claimBoarding-ttang
Browse files Browse the repository at this point in the history
F claim boarding ttang
  • Loading branch information
Tonyce authored Feb 6, 2024
2 parents 656340f + 41652d9 commit 19234fb
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 23 deletions.
55 changes: 32 additions & 23 deletions apps/u3/src/components/layout/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import styled from 'styled-components';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css';
import { isMobile } from 'react-device-detect';
import { useLocation } from 'react-router-dom';
import { useLocation, useSearchParams } from 'react-router-dom';
import { useAuthentication } from '@us3r-network/auth-with-rainbowkit';
import { MEDIA_BREAK_POINTS } from '../../constants/index';
import Main from './Main';
Expand All @@ -20,37 +20,46 @@ import MobileHeader from './mobile/MobileHeader';
import MobileNav from './mobile/MobileNav';
import { MobileGuide } from './mobile/MobileGuide';
import AddPostMobile from '../social/AddPostMobile';
import ClaimOnboard from '../onboard/Claim';

function Layout() {
const { ready } = useAuthentication();
const location = useLocation();
const [searchParams, setSearchParams] = useSearchParams();
const claim = searchParams.get('claim');

useGAPageView();

return (
<LayoutWrapper id="layout-wrapper">
{ready ? isMobile ? <MobileHeader /> : <Menu /> : null}
{ready && isMobile ? <MobileNav /> : null}
{isMobile ? (
<MobileContentBox>
<Main />
<div className="fixed right-[20px] bottom-[80px]">
<AddPostMobile />
</div>
</MobileContentBox>
) : (
<RightBox>
<RightInner id="layout-main-wrapper">
{location.pathname.includes('social') ? (
{(claim === 'true' && <ClaimOnboard />) || (
<>
{ready ? isMobile ? <MobileHeader /> : <Menu /> : null}
{ready && isMobile ? <MobileNav /> : null}
{isMobile ? (
<MobileContentBox>
<Main />
) : (
<MainBox className="main-box">
<Main />
</MainBox>
)}
</RightInner>
<DappMenu />
</RightBox>
<div className="fixed right-[20px] bottom-[80px]">
<AddPostMobile />
</div>
</MobileContentBox>
) : (
<RightBox>
<RightInner id="layout-main-wrapper">
{location.pathname.includes('social') ? (
<Main />
) : (
<MainBox className="main-box">
<Main />
</MainBox>
)}
</RightInner>
<DappMenu />
</RightBox>
)}
<MobileGuide />
</>
)}
<MobileGuide />
<ToastContainer
position="top-right"
autoClose={3000}
Expand Down
160 changes: 160 additions & 0 deletions apps/u3/src/components/onboard/Claim.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useAccount } from 'wagmi';
import { useCallback } from 'react';
import { toast } from 'react-toastify';

import useLogin from '@/hooks/shared/useLogin';
import { cn } from '@/lib/utils';
import Checked from '../common/icons/checked';
import Unchecked from '../common/icons/unchecked';
import { useFarcasterCtx } from '@/contexts/social/FarcasterCtx';
import { claimRewardApi } from '@/services/social/api/farcaster';

export default function ClaimOnboard() {
const [searchParams, setSearchParams] = useSearchParams();
const { isLogin, login } = useLogin();
const navigate = useNavigate();
const {
isConnected,
currFid,
claimStatus,
setClaimStatus,
setSignerSelectModalOpen,
} = useFarcasterCtx();
const { address } = useAccount();

const claimAction = useCallback(async () => {
console.log('claimAction', claimStatus);
if (claimStatus.statusCode === 102) {
navigate('/');
return;
}
try {
const resp = await claimRewardApi();
const { data } = resp;
console.log('claimRewardApi', data);
if (data.code !== 0) {
toast.error(data.msg);
return;
}
setClaimStatus({ statusCode: 102, amount: 0 });
navigate('/');
} catch (e) {
console.error(e);
}
}, [currFid, claimStatus, navigate]);

return (
<div className="w-screen h-screen flex justify-center items-center">
<div className="w-full md:w-[840px] text-white">
<div className="flex items-center justify-center mb-7 md:mb-0">
<span className="hidden md:inline-block text-[80px]">🎉</span>
<div className="text-center mx-6 ">
<div className="text-[24px] md:text-[40px] italic flex items-center gap-2 justify-center mb-5 md:mb-0">
<span className="md:hidden">🎉</span>
Welcome to u3.xyz
<span className="md:hidden -rotate-90">🎉</span>
</div>
<p className="text-[#718096]">
Complete these simple steps to start playing in u3 and get
rewards!
</p>
</div>
<span className="hidden md:inline-block text-[80px] -rotate-90">
🎉
</span>
</div>
<div
className={cn(
' border rounded-2xl border-[#39424C]',
'p-5 flex flex-col gap-8 text-white',
'm-2 md:w-full'
)}
>
<div className="flex items-center justify-between pb-7 border-b border-[#39424C]">
<div className="text-[#718096]">Getting started</div>
<div>3 steps left</div>
</div>
<div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-5 italic text-xl">
{isLogin && address ? <Checked /> : <Unchecked />}
<span className="text-[#F41F4C] font-bold text-2xl md:text-3xl">
Step 1
</span>
<span className="hidden md:inline-block">Connect Wallet</span>
</div>
<button
type="button"
className="w-[120px] font-bold bg-white p-3 px-6 text-black rounded-xl"
onClick={() => {
if (!isLogin || !address) {
login();
}
}}
>
Connect
</button>
</div>
<span className="md:hidden font-bold text-base">
Connect Wallet
</span>
</div>
<div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-5 italic text-xl">
{isConnected && currFid ? <Checked /> : <Unchecked />}
<span className="text-[#F41F4C] font-bold text-2xl md:text-3xl">
Step 2
</span>
<span className="hidden md:inline-block">
Farcaster Handle Verify
</span>
</div>
<button
type="button"
className="w-[120px] font-bold bg-white p-3 px-6 text-black rounded-xl"
onClick={() => {
if (!currFid || !isConnected) setSignerSelectModalOpen(true);
}}
>
Verify
</button>
</div>
<span className="md:hidden font-bold text-base">
Farcaster Handle Verify
</span>
</div>
<div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-5 italic text-xl">
{(isLogin &&
currFid &&
isConnected &&
claimStatus.statusCode === 102 && <Checked />) || (
<Unchecked />
)}
<span className="text-[#F41F4C] font-bold text-2xl md:text-3xl">
Step 3
</span>
<span className="hidden md:inline-block">
Get 💰💰💰{claimStatus.amount} $DEGEN
</span>
</div>
<button
type="button"
className="w-[120px] font-bold bg-white p-3 px-6 text-black rounded-xl"
onClick={claimAction}
>
Claim
</button>
</div>
<span className="md:hidden font-bold text-base">
Get 💰💰💰100 $DEGEN
</span>
</div>
</div>
</div>
</div>
);
}
60 changes: 60 additions & 0 deletions apps/u3/src/components/social/farcaster/ClaimNotice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Cross2Icon } from '@radix-ui/react-icons';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';

import { cn } from '@/lib/utils';
import { useFarcasterCtx } from '@/contexts/social/FarcasterCtx';
import useLogin from '@/hooks/shared/useLogin';

export default function ClaimNotice() {
const { isLogin } = useLogin();
const { isConnected, currFid, claimStatus } = useFarcasterCtx();
const [show, setShow] = useState(true);

const [searchParams, setSearchParams] = useSearchParams();
const claim = searchParams.get('claim');

if (claim === 'true' || !isConnected || !currFid || !isLogin) {
return null;
}

if (!show) return null;

if (claimStatus.statusCode !== 101) return null;

return (
<div
className={cn(
'absolute z-50 m-auto left-0 right-0',
'md:right-14 md:left-auto bottom-8 bg-[#F41F4C] w-[320px] p-5 rounded-[20px] text-white',
'flex flex-col gap-5'
)}
>
<div className="flex items-center justify-between">
<div> ⚠️ Notice</div>
<button
type="button"
className="p-1"
onClick={() => {
setShow(false);
}}
>
<Cross2Icon className="w-5 h-5" />
</button>
</div>
<div>💰💰💰You have 100 $DEGEN unclaimed</div>
<div>Click the button below 👇👇👇</div>
<div>
<button
type="button"
className="w-full bg-white text-black text-base font-bold p-3 px-6 rounded-[10px]"
onClick={() => {
setSearchParams({ claim: 'true' });
}}
>
Claim
</button>
</div>
</div>
);
}
18 changes: 18 additions & 0 deletions apps/u3/src/contexts/social/FarcasterCtx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import AddPostModal from '@/components/social/AddPostModal';
import QuickSearchModal, {
QuickSearchModalName,
} from '@/components/social/QuickSearchModal';
import ClaimNotice from '@/components/social/farcaster/ClaimNotice';
import useFarcasterClaim from '@/hooks/social/farcaster/useFarcasterClaim';

export type Token = {
token: string;
Expand Down Expand Up @@ -109,6 +111,18 @@ export interface FarcasterContextData {
openPostModal: boolean;
setOpenPostModal: React.Dispatch<React.SetStateAction<boolean>>;
setOpenModalName: React.Dispatch<React.SetStateAction<string>>;
claimStatus: {
statusCode: number;
amount: number;
msg?: string;
};
setClaimStatus: React.Dispatch<
React.SetStateAction<{
statusCode: number;
amount: number;
msg?: string;
}>
>;
}

const FarcasterContext = createContext<FarcasterContextData | null>(null);
Expand Down Expand Up @@ -146,6 +160,7 @@ export default function FarcasterProvider({
const { farcasterFollowData } = useFarcasterFollowData({
fid: currFid,
});
const { claimStatus, setClaimStatus } = useFarcasterClaim({ currFid });
useEffect(() => {
setFollowing(farcasterFollowData?.followingData || []);
}, [farcasterFollowData]);
Expand Down Expand Up @@ -352,6 +367,8 @@ export default function FarcasterProvider({
openPostModal,
setOpenPostModal,
setOpenModalName,
claimStatus,
setClaimStatus,
}}
>
{children}
Expand Down Expand Up @@ -424,6 +441,7 @@ export default function FarcasterProvider({
}}
/>
)}
<ClaimNotice />
</FarcasterContext.Provider>
);
}
Expand Down
44 changes: 44 additions & 0 deletions apps/u3/src/hooks/social/farcaster/useFarcasterClaim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useCallback, useEffect, useState } from 'react';
import { getClaimStatusApi } from '@/services/social/api/farcaster';

export default function useFarcasterClaim({ currFid }: { currFid: number }) {
const [mounted, setMounted] = useState(false);
const [claimStatus, setClaimStatus] = useState({
statusCode: 100,
amount: 100,
msg: '',
});

const getClaimStatus = useCallback(async () => {
try {
const resp = await getClaimStatusApi();
const { data } = resp;
setClaimStatus({
statusCode: data.data.statusCode,
amount: data.data.amount || 100,
msg: data.msg,
});
console.log('getClaimStatus', data);
} catch (e) {
console.error('Error getting claim status', e);
}
}, []);

useEffect(() => {
if (!mounted) return;
if (!currFid) {
console.log('No FID', { currFid });
return;
}
getClaimStatus();
}, [getClaimStatus, mounted, currFid]);

useEffect(() => {
setMounted(true);
}, []);

return {
claimStatus,
setClaimStatus,
};
}
Loading

0 comments on commit 19234fb

Please sign in to comment.