Skip to content

Commit

Permalink
Merge pull request #516 from us3r-network/F-tipDetail-ttang
Browse files Browse the repository at this point in the history
feat: tip detail
  • Loading branch information
Tonyce authored Feb 2, 2024
2 parents 3563f84 + 0f276f7 commit 78df981
Show file tree
Hide file tree
Showing 8 changed files with 366 additions and 31 deletions.
12 changes: 6 additions & 6 deletions apps/u3/craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ module.exports = {

// Replace include option for babel loader with exclude
// so babel will handle workspace projects as well.
config.module.rules[1].oneOf.forEach((r) => {
if (r.loader && r.loader.indexOf('babel') !== -1) {
r.exclude = /node_modules/;
delete r.include;
}
});
// config.module.rules[1].oneOf.forEach((r) => {
// if (r.loader && r.loader.indexOf('babel') !== -1) {
// r.exclude = /node_modules/;
// delete r.include;
// }
// });
config.resolve.fallback = {
assert: require.resolve('assert'),
buffer: require.resolve('buffer'),
Expand Down
2 changes: 1 addition & 1 deletion apps/u3/src/components/social/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export function PostCardUserInfo({
}

const PostCardUserInfoWrapper = styled.div`
flex: 1;
/* flex: 1; */
display: flex;
align-items: flex-start;
gap: 10px;
Expand Down
37 changes: 13 additions & 24 deletions apps/u3/src/components/social/farcaster/FCast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
PostCardActionsWrapper,
PostCardContentWrapper,
PostCardFooterWrapper,
PostCardHeaderWrapper,
PostCardShowMoreWrapper,
PostCardUserInfo,
PostCardWrapper,
Expand All @@ -40,6 +39,7 @@ import { pinupCastApi } from '@/services/social/api/farcaster';
import useLogin from '@/hooks/shared/useLogin';
import { SaveButton } from '@/components/shared/button/SaveButton';
import FCastTips from './FCastTips';
import FCastTipDetail from './FCastTipDetail';

export default function FCast({
cast,
Expand Down Expand Up @@ -70,6 +70,7 @@ export default function FCast({
farcasterUserData,
farcasterUserDataObj,
});
const [count, setCount] = useState(0);
const [showMore, setShowMore] = useState(false);
const { following, pinupHashes, updatePinupHashes } = useFarcasterCtx();
const { followAction, unfollowAction, isPending, isFollowing } =
Expand Down Expand Up @@ -159,7 +160,7 @@ export default function FCast({
navigate(`/social/post-detail/fcast/${id}`);
}}
>
<PostCardHeaderWrapper>
<div className="flex items-center gap-5">
<PostCardUserInfo
data={{
platform: SocialPlatform.Farcaster,
Expand All @@ -169,13 +170,21 @@ export default function FCast({
createdAt: cast.created_at || cast.createdAt,
}}
/>
<FCastTipDetail cast={cast} />
<div className="flex-grow" />
<div
className="flex items-center gap-2"
onClick={(e) => {
e.stopPropagation();
}}
>
<FCastTips userData={userData} cast={cast} />
<FCastTips
userData={userData}
cast={cast}
updateCb={() => {
setCount(count + 1);
}}
/>
{isAdmin && (
<Button
className={cn(
Expand All @@ -192,28 +201,8 @@ export default function FCast({
<ArrowUpIcon />
</Button>
)}
{/* {showMenuBtn && (
<div>
<PostCardMenuBtn
data={{
name: userData.display,
handle: userData.userName,
}}
isFollowed={followed}
followPending={isPending}
unfollowPending={isPending}
followAction={() => {
if (followed) {
unfollowAction(userData.fid);
} else {
followAction(userData.fid);
}
}}
/>
</div>
)} */}
</div>
</PostCardHeaderWrapper>
</div>

<PostCardContentWrapper ref={viewRef} showMore={showMore}>
<FCastText cast={cast} farcasterUserDataObj={farcasterUserDataObj} />
Expand Down
190 changes: 190 additions & 0 deletions apps/u3/src/components/social/farcaster/FCastTipDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { useCallback, useState } from 'react';
import dayjs from 'dayjs';
import { toast } from 'react-toastify';
import { Cross2Icon } from '@radix-ui/react-icons';

import { FarCast } from '@/services/social/types';
import ModalContainer from '@/components/common/modal/ModalContainer';
import { cn } from '@/lib/utils';
import { getCastTipsDetail } from '@/services/social/api/farcaster';
import Loading from '@/components/common/loading/Loading';
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';

export default function FCastTipDetail({ cast }: { cast: FarCast }) {
const [openModal, setOpenModal] = useState(false);
const [loading, setLoading] = useState(false);
const [tipDetails, setTipDetails] = useState<
{
amount: number;
createdAt: number;
txHash: string;
type: string;
userDatas: { type: number; value: string }[];
}[]
>([]);

const loadTipsDetails = useCallback(async () => {
try {
setLoading(true);
const resp = await getCastTipsDetail(
Buffer.from(cast.hash.data).toString('hex')
);
if (resp.data.code !== 0) {
toast.error(resp.data.msg);
} else {
setTipDetails(resp.data.data);
}
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
}, [cast]);

if (!cast.tipsTotalAmount) {
return null;
}
return (
<>
<div
className="flex items-center cursor-pointer"
onClick={(e) => {
e.stopPropagation();
setOpenModal(true);
loadTipsDetails();
}}
>
{/* <span className="text-[#718096] text-sm"> received</span> */}
<span className="text-[#FFBB02]"> {cast.tipsTotalAmount} $DEGEN</span>
</div>
{openModal && (
<TipDetailsModal
open={openModal}
setOpen={setOpenModal}
loading={loading}
details={tipDetails}
tipsTotalAmount={tipDetails.reduce((acc, cur) => acc + cur.amount, 0)}
/>
)}
</>
);
}

function TipDetailsModal({
open,
setOpen,
details,
loading,
tipsTotalAmount,
}: {
open: boolean;
setOpen: (open: boolean) => void;
details: {
amount: number;
txHash: string;
createdAt: number;
type: string;
userDatas: { type: number; value: string }[];
}[];
loading: boolean;
tipsTotalAmount: number;
}) {
return (
<ModalContainer
open={open}
closeModal={() => {
setOpen(false);
}}
contentTop="40%"
className="w-full md:w-[600px]"
>
{(loading && (
<div className="flex justify-center items-center min-h-36">
<Loading />
</div>
)) || (
<div
className={cn(
'flex flex-col gap-5 p-5 bg-[#1B1E23] text-white border-[#39424C]',
'rounded-xl md:rounded-[20px] md:max-w-none md:w-[600px]'
)}
onClick={(e) => {
e.stopPropagation();
}}
>
<div className="flex flex-col gap-3 text-sm">
<div className="flex justify-between gap-2">
<div className="text-base">
<span className="text-[#718096]">Tips</span>
</div>
<div
className="hover:cursor-pointer"
onClick={() => {
setOpen(false);
}}
>
<Cross2Icon className="h-5 w-5 text-[#718096]" />
</div>
</div>
</div>
<Table>
<TableHeader className="border-none">
<TableRow className="hover:bg-none border-none">
<TableHead className="w-[300px]">From</TableHead>
<TableHead>Type</TableHead>
<TableHead>Price</TableHead>
<TableHead className="text-right">Date</TableHead>
</TableRow>
</TableHeader>
<TableBody className="border-none mb-5">
{details.map((detail, index) => {
const avatar = detail.userDatas.find((item) => item.type === 1);
const name = detail.userDatas.find((item) => item.type === 2);
const handle = detail.userDatas.find((item) => item.type === 6);
return (
<TableRow key={detail.createdAt} className="border-none">
<TableCell className="font-medium flex gap-3">
<img
src={avatar.value}
alt=""
className="w-12 h-12 object-cover rounded-full"
/>
<div>
<div className="text-lg">{name.value}</div>
<div className="text-sm text-[#718096]">
@{handle.value}
</div>
</div>
</TableCell>
<TableCell>{detail.type || 'Token'}</TableCell>
<TableCell>{detail.amount}</TableCell>
<TableCell className="text-right">
{dayjs(detail.createdAt).fromNow()}
</TableCell>
</TableRow>
);
})}
</TableBody>
<br />
<TableFooter className="bg-muted/0 border-[#718096]">
<TableRow className="">
<TableCell colSpan={2}>Tipped {details.length} times</TableCell>
<TableCell className="text-right" colSpan={2}>
Amount: {tipsTotalAmount} $DEGEN
</TableCell>
</TableRow>
</TableFooter>
</Table>
</div>
)}
</ModalContainer>
);
}
Loading

0 comments on commit 78df981

Please sign in to comment.