Built Twitter Like App - 22

Add PostFeed

  1. Add component PostFeed
  2. Add component PostItem
  3. Add PostFeed to Home Page

Add Component PostFeed

Add file components/PostFeed.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import usePosts from "@/hooks/usePosts";
import PostItem from "./PostItem";

interface PostFeedProps {
userId: string;
}

const PostFeed: React.FC<PostFeedProps> = ({ userId }) =>{
const { data: posts = []} = usePosts( userId ) ;

return (
<>
{posts.map((post: Record<string, any >) => (
<PostItem
userId = { userId }
key = {post.id}
data = {post}
/>
))}
</>
);
}
export default PostFeed;

Add Component PostItem

Add file components/PostItem.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import useCurrentUser from "@/hooks/useCurrentUser";
import useLoginModal from "@/hooks/useLoginModal";
import { formatDistanceToNow } from "date-fns";
import { useRouter } from "next/router";
import { useCallback, useMemo } from "react";
import Avatar from "../Avatar";
import { AiOutlineHeart, AiOutlineMessage } from "react-icons/ai";

interface PostFeedProps{
data: Record<string, any>
userId?: string;
}

const PostItem: React.FC<PostFeedProps> =({ data, userId }) =>{
const router = useRouter();
const loginModel = useLoginModal();

const { data: currentUser } = useCurrentUser();

const gotoUser = useCallback((event:any) => {
event.stopPropagation();

router.push(`/users/${data.user.id}`);

},[ router, data.user.id])

const gotoPost = useCallback(() => {
router.push(`/posts/${data.id}`);
},[ router, data.id ])

const onLike = useCallback((event: any) => {
event.stopPropagation();
loginModel.onOpen();
},[loginModel])

const createdAt = useMemo(() => {
if (!data?.createdAt){
return null;
}

return formatDistanceToNow(new Date(data.createdAt))
},[data.createdAt])

return (
<div
onClick={gotoPost}
className="
border-b-[1px]
border-neutral-800
p-5
cursor-pointer
hover:bg-neutral-900
transition
"
>
<div className="flex flex-row items-start gap-3">
<Avatar userId={data.user.id} />
<div>
<div className="flex flex-row items-center gap-2">
<p onClick={gotoUser} className=
"text-white fond-semibold cursor-pointer hover:underline">
{data.user.name}
</p>
<span onClick={gotoUser} className=
"text-neutral-500 cousor-pointer hover:underline hidden md:block">
@{data.user.username}
</span>
<span className="text-neutral-500 text-sm">
{createdAt}
</span>
</div>
<div className="text-white mt-1">
{data.body}
</div>
<div className="flex flex-row items-center mt-3 gap-10">
<div
className="
flex
flex-row
item-center
text-neutral-500
gap-2
cursor-pointer
transition
hover:text-sky-500
"
>
<AiOutlineMessage size={20} />
<p>
{data.comments?.length || 0}
</p>
</div>
<div
onClick={onLike}
className="
flex
flex-row
item-center
text-neutral-500
gap-2
cursor-pointer
transition
hover:text-red-500
"
>
<AiOutlineHeart size={20} />
<p>
{data.comments?.length || 0}
</p>
</div>
</div>
</div>
</div>
</div>
);
}

export default PostItem;

Add PostFeed to Home Page

modify pages/index.tsx:

1
2
3
4
5
6
7
8
9
10
11
12
13
import Form from "@/components/Form";
import Header from "../components/Header";
import PostFeed from "@/components/posts/PostFeed";

export default function Home() {
return (
<>
<Header label="Home"/>
<Form placeholder="What's happening?"/>
<PostFeed userId=""/>
</>
)
}

Add PostFeed to User Page

modify pages/users/[userId].tsx:

1
2
3
4
5
6
7
8
9
10
11
12
...
return (
<>
<Header showBackArrow label={fetechedUser?.name} />
<UserHero userId={ userId as string } />
<UserBio userId={ userId as string } />
<PostFeed userId={ userId as string } />
</>
);
}

export default UserView;

Demo

Home Page:

User Page:

请我喝杯咖啡吧~

支付宝
微信