Skip to content

Instantly share code, notes, and snippets.

@sayandedotcom
Last active December 19, 2024 18:11
Show Gist options
  • Save sayandedotcom/38555c3f9811bc61de5bf1409cbe7a66 to your computer and use it in GitHub Desktop.
Save sayandedotcom/38555c3f9811bc61de5bf1409cbe7a66 to your computer and use it in GitHub Desktop.
Twitter / X feed system with Next.js, Prisma, Tanstack Query !
File 1 :- home.tsx ======================================================================================
export default function Home() {
const { data: session } = useSession();
const router = useRouter();
const {
data,
isLoading: isInfiniteLoading,
fetchNextPage,
hasNextPage,
isFetched: isInfiniteFetched,
isFetchingPreviousPage,
} = useInfiniteQuery<TPosts>({
queryKey: ["timeline", "infinite"],
queryFn: ({ pageParam = 0 }) => {
return request.get("/timeline", {
params: {
skip: pageParam,
take: 10,
},
});
},
initialPageParam: 0,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
if (lastPage.data.data?.length < 10) {
return undefined;
}
return allPages?.length * 10;
},
});
const { ref, inView } = useInView({
/* Optional options */
// threshold: 0,
});
useEffect(() => {
if (inView && hasNextPage) {
fetchNextPage();
}
}, [fetchNextPage, inView, hasNextPage]);
if (isInfiniteLoading) {
return <Loading />;
}
return (
<>
<NewPosts pageParamsLength={data?.pageParams?.length} />
{data?.pages?.map((page) =>
page?.data?.data?.map((data) => (
<PostCard key={data.id}>
<PostCard.Image
src={data.user?.image ?? "/images/avatar/avatar.png"}
name={data.user?.name}
userName={data.user?.userName}
bio={data.user?.bio}
/>
<PostCard.Content>
<PostCard.Header
name={data.user?.name}
userName={data.user?.userName}
image={data.user?.image ?? "/images/avatar/avatar.png"}
bio={data.user?.bio}
time={fromNow(data.createdAt)}
timeLeft={data.expiresAt ? fromNow(data.expiresAt) : "No Expiry"}
postType={data.postType}
isAuthor={session?.user?.id === data.userId}
expired={expired(data.expiresAt)}
/>
<Navigate userName={data.user.userName} postId={data.id}>
<PostCard.Description showMore={true}>{data.description}</PostCard.Description>
</Navigate>
<PostCard.Tags
allTags={false}
companyName={data.companyName}
locationType={data.jobLocationType}
location={data.jobLocation}
experience={data.jobExperience}
jobType={data.jobType}
role={data.jobRole}
salary={data.jobCompensation}
postType={data.postType}
jobURL={data.jobURL}
jobCode={data.jobCode}
/>
<PostCard.Footer>
<MultipleButtons>
{/* <CommentButton /> */}
<ShareButton link={`${data.user.userName}/posts/${data.id}`} title={data.description} />
<BookmarkButton postId={data.id} />
<ApplyStatus totalApplied={data.totalApplied} acceptLimit={data.acceptLimit} />
{data.postType === "REFERRALPOST" && <StarButton star={data.stars} />}
</MultipleButtons>
{data.postType === "REFERRALPOST" && session?.user?.id === data.userId ? (
<div className="flex items-center gap-3">
<PauseButton postId={data.id} isPause={data.isPause} />
<Button
disabled={data.totalApplied === 0}
onClick={() => {
router.push(`/dashboard/requests?postId=${data.id}`);
}}
className="h-9 rounded-full text-sm md:w-36">
{data.totalApplied > 0 ? "Explore Requests" : "No Applies"}
</Button>
</div>
) : (
<ApplyDialog
postType={data.postType}
myObject={data.accept}
postId={data.id}
stars={data.stars}
totalApplied={data.totalApplied}
acceptLimit={data.acceptLimit}
authorId={data.userId}
expired={expired(data.expiresAt)}
isPaused={data.isPause}
/>
)}
</PostCard.Footer>
</PostCard.Content>
</PostCard>
))
)}
{!hasNextPage && (
<div className="flex flex-col items-center justify-center p-9">
<CheckCircle2 className="mb-3 h-10 w-10" />
<h6 className="font-heading">You&apos;re all caught up</h6>
<p className="text-sm">You&apos;ve seen all new posts !</p>
</div>
)}
{hasNextPage && (
<div ref={ref}>
<PostCardSkeleton />
</div>
)}
</>
);
}
File 2 :- new-posts.tsx ======================================================================================
export function NewPosts({ pageParamsLength }: { pageParamsLength?: number }) {
const { data: session } = useSession();
const router = useRouter();
const [refetchData, setRefetchData] = useState<TPosts>();
const { data, isRefetching } = useQuery<TPosts>({
queryKey: ["timeline", "morePosts", pageParamsLength],
queryFn: () => {
return request.get("/timeline", {
params: {
skip: pageParamsLength * 10,
take: 10,
},
});
},
refetchInterval(query) {
return pageParamsLength > 1 ? 5000 : undefined; // Only set interval if pageParams exist
},
refetchOnMount: false,
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
// 5000 300000
enabled: pageParamsLength > 1,
// select(data) {
// setRefetchData(data);
// return data;
// },
});
const [visible, setvisible] = useState(isRefetching && isRefetching);
useEffect(() => {
if (isRefetching === true) {
setvisible(isRefetching);
}
}, [isRefetching]);
return (
<>
{visible && (
<Badge
onClick={() => {
setvisible(!visible);
window.scrollTo({
top: 0,
left: 0,
behavior: "instant",
});
}}
className={cn("fixed left-2/4 top-4 -translate-x-1/2 transform cursor-pointer")}>
<ArrowUp />
<AvatarCircles numPeople={10} avatarUrls={avatars} />
</Badge>
)}
{refetchData?.data?.data?.map((data) => (
<PostCard key={data.id}>
<PostCard.Image
src={data.user?.image ?? "/images/avatar/avatar.png"}
name={data.user?.name}
userName={data.user?.userName}
bio={data.user?.bio}
/>
<PostCard.Content>
<PostCard.Header
name={data.user?.name}
userName={data.user?.userName}
image={data.user?.image ?? "/images/avatar/avatar.png"}
bio={data.user?.bio}
time={fromNow(data.createdAt)}
timeLeft={data.expiresAt ? fromNow(data.expiresAt) : "No Expiry"}
postType={data.postType}
isAuthor={session?.user?.id === data.userId}
expired={expired(data.expiresAt)}
/>
<Navigate userName={data.user.userName} postId={data.id}>
<PostCard.Description showMore={true}>{data.description}</PostCard.Description>
</Navigate>
<PostCard.Tags
allTags={false}
companyName={data.companyName}
locationType={data.jobLocationType}
location={data.jobLocation}
experience={data.jobExperience}
jobType={data.jobType}
role={data.jobRole}
salary={data.jobCompensation}
postType={data.postType}
jobURL={data.jobURL}
jobCode={data.jobCode}
/>
<PostCard.Footer>
<MultipleButtons>
{/* <CommentButton /> */}
<ShareButton link={`${data.user.userName}/posts/${data.id}`} title={data.description} />
<BookmarkButton postId={data.id} />
<ApplyStatus totalApplied={data.totalApplied} acceptLimit={data.acceptLimit} />
{data.postType === "REFERRALPOST" && <StarButton star={data.stars} />}
</MultipleButtons>
{data.postType === "REFERRALPOST" && session?.user?.id === data.userId ? (
<div className="flex items-center gap-3">
<PauseButton postId={data.id} isPause={data.isPause} />
<Button
disabled={data.totalApplied === 0}
onClick={() => {
router.push(`/dashboard/requests?postId=${data.id}`);
}}
className="h-9 rounded-full text-sm md:w-36">
{data.totalApplied > 0 ? "Explore Requests" : "No Applies"}
</Button>
</div>
) : (
<ApplyDialog
postType={data.postType}
myObject={data.accept}
postId={data.id}
stars={data.stars}
totalApplied={data.totalApplied}
acceptLimit={data.acceptLimit}
authorId={data.userId}
expired={expired(data.expiresAt)}
isPaused={data.isPause}
/>
)}
</PostCard.Footer>
</PostCard.Content>
</PostCard>
))}
</>
);
}
export function NewPosts({ pageParamsLength }: { pageParamsLength?: number }) {
const { data: session } = useSession();
const router = useRouter();
const [refetchData, setRefetchData] = useState<TPosts>();
const { data, isRefetching } = useQuery<TPosts>({
queryKey: ["timeline", "morePosts", pageParamsLength],
queryFn: () => {
return request.get("/timeline", {
params: {
skip: pageParamsLength * 10,
take: 10,
},
});
},
refetchInterval(query) {
return pageParamsLength > 1 ? 5000 : undefined; // Only set interval if pageParams exist
},
refetchOnMount: false,
refetchIntervalInBackground: false,
refetchOnWindowFocus: false,
// 5000 300000
enabled: pageParamsLength > 1,
// select(data) {
// setRefetchData(data);
// return data;
// },
});
const [visible, setvisible] = useState(isRefetching && isRefetching);
useEffect(() => {
if (isRefetching === true) {
setvisible(isRefetching);
}
}, [isRefetching]);
return (
<>
{visible && (
<Badge
onClick={() => {
setvisible(!visible);
window.scrollTo({
top: 0,
left: 0,
behavior: "instant",
});
}}
className={cn("fixed left-2/4 top-4 -translate-x-1/2 transform cursor-pointer")}>
<ArrowUp />
<AvatarCircles numPeople={10} avatarUrls={avatars} />
</Badge>
)}
{refetchData?.data?.data?.map((data) => (
<PostCard key={data.id}>
<PostCard.Image
src={data.user?.image ?? "/images/avatar/avatar.png"}
name={data.user?.name}
userName={data.user?.userName}
bio={data.user?.bio}
/>
<PostCard.Content>
<PostCard.Header
name={data.user?.name}
userName={data.user?.userName}
image={data.user?.image ?? "/images/avatar/avatar.png"}
bio={data.user?.bio}
time={fromNow(data.createdAt)}
timeLeft={data.expiresAt ? fromNow(data.expiresAt) : "No Expiry"}
postType={data.postType}
isAuthor={session?.user?.id === data.userId}
expired={expired(data.expiresAt)}
/>
<Navigate userName={data.user.userName} postId={data.id}>
<PostCard.Description showMore={true}>{data.description}</PostCard.Description>
</Navigate>
<PostCard.Tags
allTags={false}
companyName={data.companyName}
locationType={data.jobLocationType}
location={data.jobLocation}
experience={data.jobExperience}
jobType={data.jobType}
role={data.jobRole}
salary={data.jobCompensation}
postType={data.postType}
jobURL={data.jobURL}
jobCode={data.jobCode}
/>
<PostCard.Footer>
<MultipleButtons>
{/* <CommentButton /> */}
<ShareButton link={`${data.user.userName}/posts/${data.id}`} title={data.description} />
<BookmarkButton postId={data.id} />
<ApplyStatus totalApplied={data.totalApplied} acceptLimit={data.acceptLimit} />
{data.postType === "REFERRALPOST" && <StarButton star={data.stars} />}
</MultipleButtons>
{data.postType === "REFERRALPOST" && session?.user?.id === data.userId ? (
<div className="flex items-center gap-3">
<PauseButton postId={data.id} isPause={data.isPause} />
<Button
disabled={data.totalApplied === 0}
onClick={() => {
router.push(`/dashboard/requests?postId=${data.id}`);
}}
className="h-9 rounded-full text-sm md:w-36">
{data.totalApplied > 0 ? "Explore Requests" : "No Applies"}
</Button>
</div>
) : (
<ApplyDialog
postType={data.postType}
myObject={data.accept}
postId={data.id}
stars={data.stars}
totalApplied={data.totalApplied}
acceptLimit={data.acceptLimit}
authorId={data.userId}
expired={expired(data.expiresAt)}
isPaused={data.isPause}
/>
)}
</PostCard.Footer>
</PostCard.Content>
</PostCard>
))}
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment