Skip to content

Commit decb61d

Browse files
committed
fix loading, revalidation, comment count
1 parent 52fe0d0 commit decb61d

10 files changed

Lines changed: 124 additions & 117 deletions

File tree

‎apps/codebility/app/home/feeds/IMPROVEMENTS.md‎

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ This document outlines potential improvements for the feeds feature based on cod
44

55
## Performance & Optimization
66

7-
1. **Implement infinite scroll** instead of traditional pagination
7+
<!-- 1. **Implement infinite scroll** instead of traditional pagination
88
- Better UX for feed browsing
99
- Reduces cognitive load on users
10-
- More engaging scrolling experience
10+
- More engaging scrolling experience -->
1111

1212
2. **Add optimistic updates** for upvotes/comments
1313
- Instant UI feedback before server response
@@ -19,17 +19,12 @@ This document outlines potential improvements for the feeds feature based on cod
1919
- Automatic background refetching
2020
- Built-in stale-while-revalidate pattern
2121

22-
4. **Add real-time updates** using Supabase subscriptions
23-
- New posts appear automatically without manual refresh
24-
- Live upvote/comment count updates
25-
- Better collaboration experience
26-
27-
5. **Optimize image loading**
22+
4. **Optimize image loading**
2823
- Add blur placeholders (Next.js Image component supports this)
2924
- Lazy loading for images below the fold
3025
- Progressive image loading
3126

32-
6. **Memoize filtered posts computation**
27+
5. **Memoize filtered posts computation**
3328
- Already using `useMemo` in Feed.tsx:25-41
3429
- Could optimize further with better dependency keys
3530
- Consider moving heavy filtering to server-side
@@ -41,11 +36,11 @@ This document outlines potential improvements for the feeds feature based on cod
4136
- Multiple categories per post
4237
- Visual category badges
4338

44-
8. **Sort options**
39+
<!-- 8. **Sort options**
4540
- Newest first (current default)
4641
- Most upvoted
4742
- Trending (combination of recent + upvotes)
48-
- Most commented
43+
- Most commented -->
4944

5045
9. **Bookmark/save posts**
5146
- Let users save posts for later reading
@@ -57,10 +52,10 @@ This document outlines potential improvements for the feeds feature based on cod
5752
- Show content excerpt with "Read more..."
5853
- Better preview of post content
5954

60-
11. **Comment count display** on PostCard
55+
<!-- 11. **Comment count display** on PostCard
6156
- Show engagement metrics at a glance
6257
- Currently only shows upvote count
63-
- Display next to upvote button
58+
- Display next to upvote button -->
6459

6560
12. **Share functionality**
6661
- Copy link to clipboard
@@ -72,22 +67,17 @@ This document outlines potential improvements for the feeds feature based on cod
7267
- Notify mentioned users
7368
- Highlight mentions in text
7469

75-
14. **Image gallery view** for posts with multiple images
76-
- Currently supports single thumbnail
77-
- Carousel/gallery for multiple images
78-
- Lightbox for full-size viewing
79-
80-
15. **Draft posts**
70+
14. **Draft posts**
8171
- Save work in progress before publishing
8272
- Auto-save functionality
8373
- Resume editing later
8474

8575
## Code Quality & Architecture
8676

87-
16. **Fix hardcoded admin check** (page.tsx:13)
77+
<!-- 16. **Fix hardcoded admin check** (page.tsx:13)
8878
- Currently: `const [isAdmin, setIsAdmin] = useState(true);`
8979
- Should initialize as `false`
90-
- Security risk if not properly validated
80+
- Security risk if not properly validated -->
9181

9282
17. **Consolidate duplicate user role fetching**
9383
- Used in page.tsx:20-27 and PostView.tsx:48-52
@@ -110,15 +100,15 @@ This document outlines potential improvements for the feeds feature based on cod
110100
- Graceful degradation
111101
- User-friendly error messages
112102

113-
21. **Loading skeletons** for individual post cards
103+
<!-- 21. **Loading skeletons** for individual post cards
114104
- Currently only in PostView.tsx:110-115
115105
- Add to Feed.tsx while posts are loading
116-
- Better loading states
106+
- Better loading states -->
117107

118-
22. **Extract magic numbers** to constants
108+
<!-- 22. **Extract magic numbers** to constants
119109
- `postsPerPage: 6` (Feed.tsx:43)
120110
- Debounce delay `500ms` (page.tsx:32)
121-
- Create `constants.ts` file
111+
- Create `constants.ts` file -->
122112

123113
23. **Consistent async/await error handling**
124114
- Some functions use try/catch, others don't
@@ -234,29 +224,29 @@ This document outlines potential improvements for the feeds feature based on cod
234224

235225
These improvements can be implemented quickly and provide immediate value:
236226

237-
- ✅ **Fix the `isAdmin` initialization bug** (page.tsx:13)
227+
<!-- - ✅ **Fix the `isAdmin` initialization bug** (page.tsx:13)
238228
- Change `useState(true)` to `useState(false)`
239229
- 1-line fix, important security improvement
240230
241231
- ✅ **Add comment count to PostCard component**
242232
- Query comment count in getPosts
243233
- Display next to upvote count
244-
- ~20 lines of code
234+
- ~20 lines of code -->
245235

246-
- ✅ **Extract constants**
236+
<!-- - ✅ **Extract constants**
247237
- Create `_constants/index.ts`
248238
- Move magic numbers: `POSTS_PER_PAGE = 6`, `SEARCH_DEBOUNCE_MS = 500`
249-
- Better maintainability
239+
- Better maintainability -->
250240

251-
- ✅ **Add loading skeleton for post cards**
241+
<!-- - ✅ **Add loading skeleton for post cards**
252242
- Reuse existing Skeleton component
253243
- Show while `fetchPosts()` is loading
254-
- ~15 lines of code
244+
- ~15 lines of code -->
255245

256-
- ✅ **Add empty state when no posts match search**
246+
<!-- - ✅ **Add empty state when no posts match search**
257247
- Simple conditional in Feed.tsx
258248
- Better UX than empty grid
259-
- ~10 lines of code
249+
- ~10 lines of code -->
260250

261251
## File References
262252

‎apps/codebility/app/home/feeds/_components/Feed.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ export default function Feed({
2222
}: FeedProp) {
2323
const posts = useFeedsStore((state) => state.posts);
2424
const fetchPosts = useFeedsStore((state) => state.fetchPosts);
25-
const isLoading = useFeedsStore((state) => state.isLoading);
25+
const isFetchingPosts = useFeedsStore((state) => state.isFetchingPosts);
2626

2727
const [visibleCount, setVisibleCount] = useState(POSTS_PER_PAGE);
2828
const loaderRef = useRef<HTMLDivElement | null>(null);
2929

3030
useEffect(() => {
3131
fetchPosts();
32-
}, [fetchPosts]);
32+
}, []);
3333

3434
// Filter posts
3535
const filteredPosts = useMemo(() => {
@@ -116,7 +116,7 @@ export default function Feed({
116116
<>
117117
{/* Posts grid */}
118118
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
119-
{isLoading
119+
{isFetchingPosts
120120
? Array.from({ length: 6 }).map((_, i) => (
121121
<PostCardSkeleton key={i} />
122122
))
@@ -131,7 +131,7 @@ export default function Feed({
131131
</div>
132132

133133
{/* Loader */}
134-
{!isLoading && visibleCount < sortedPosts.length && (
134+
{!isFetchingPosts && visibleCount < sortedPosts.length && (
135135
<div
136136
ref={loaderRef}
137137
className="mt-6 flex justify-center text-sm text-gray-500"
@@ -144,7 +144,7 @@ export default function Feed({
144144
)}
145145

146146
{/* Empty state */}
147-
{!isLoading && sortedPosts.length === 0 && (
147+
{!isFetchingPosts && sortedPosts.length === 0 && (
148148
<div className="mt-8 text-center text-gray-500">No posts found.</div>
149149
)}
150150
</>

‎apps/codebility/app/home/feeds/_components/PostCard.tsx‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import toast from "react-hot-toast";
1212
import { deletePost } from "../_services/action";
1313
import { PostType } from "../_services/query";
1414
import { DeleteDialog } from "./DeleteDialog";
15+
import PostCommentCount from "./PostCommentCount";
1516
import PostUpvote from "./PostUpvote";
1617

1718
interface PostProps {
@@ -125,14 +126,7 @@ export default function Post({ post, isAdmin, onDelete }: PostProps) {
125126
<div className="mx-4 mt-4 flex items-center space-x-4 text-gray-600 dark:text-gray-400">
126127
<PostUpvote post={post} />
127128

128-
{/* Comment Count */}
129-
<div className="flex items-center space-x-1">
130-
<MessageSquare
131-
size={20}
132-
className="text-gray-600 dark:text-gray-400"
133-
/>
134-
<span>{post.comment_count ?? 0}</span>
135-
</div>
129+
<PostCommentCount post={post} />
136130
</div>
137131
</Box>
138132
<FeedPostModal
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useEffect, useState } from "react";
2+
import { useFeedsStore } from "@/store/feeds-store";
3+
import { MessageSquare } from "lucide-react";
4+
5+
import { PostType } from "../_services/query";
6+
7+
interface PostCommentCountProps {
8+
post: PostType;
9+
}
10+
11+
export default function PostCommentCount({ post }: PostCommentCountProps) {
12+
const [count, setCount] = useState(post.comment_count ?? 0);
13+
14+
// Update local state whenever the post prop changes
15+
useEffect(() => {
16+
setCount(post.comment_count ?? 0);
17+
}, [post]);
18+
19+
return (
20+
<div className="flex items-center space-x-1">
21+
<MessageSquare size={20} className="text-gray-600 dark:text-gray-400" />
22+
<span>{count}</span>
23+
</div>
24+
);
25+
}

‎apps/codebility/app/home/feeds/_components/PostUpvote.tsx‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,17 @@ export default function PostUpvote({ post }: PostUpvoteProps) {
6363

6464
if (!isUpvoted) {
6565
const postUpvote = await AddPostUpvote(post.id, user.id);
66+
67+
useFeedsStore.getState().updatePost(post.id, {
68+
upvote_count: post.comment_count! + 1,
69+
});
6670
} else {
6771
await removePostUpvote(post.id, user.id);
68-
}
6972

70-
await fetchPosts();
73+
useFeedsStore.getState().updatePost(post.id, {
74+
upvote_count: post.comment_count! - 1,
75+
});
76+
}
7177
}
7278
};
7379

0 commit comments

Comments
 (0)