Skip to content

Commit 5a28043

Browse files
committed
feat: search by hashtags
1 parent d0b7d50 commit 5a28043

File tree

11 files changed

+191
-260
lines changed

11 files changed

+191
-260
lines changed

client/src/api/posts.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ export const getPosts = async (cursor, limit) => {
99
}
1010
}
1111

12-
export const searchPosts = async (query) => {
12+
export const searchPosts = async (query, cursor, limit) => {
1313
try {
14-
const { data } = await api.get('/posts/search', { params: { query } })
14+
const { data } = await api.get('/posts/search', {
15+
params: { query, cursor, limit }
16+
})
1517
return data
1618
} catch (error) {
1719
throw handleApiError(error)

client/src/api/tags.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,14 @@ export const searchTags = async (q) => {
1717
throw handleApiError(error)
1818
}
1919
}
20+
21+
export const searchPostsByTags = async (tag, cursor, limit) => {
22+
try {
23+
const { data } = await api.get(`/tags/posts/${tag}`, {
24+
params: { cursor, limit }
25+
})
26+
return data
27+
} catch (error) {
28+
throw handleApiError(error)
29+
}
30+
}

client/src/components/AccountMenu.jsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,21 @@ import { Link } from 'react-router'
2020
import { useTheme } from '@/hooks'
2121
import { useState } from 'react'
2222
import { UserAvatar } from '.'
23+
import { useStore } from '@/store'
2324

2425
const AccountMenuItems = ({ handleClose, handleClick, open }) => {
25-
const { user } = useUser()
26+
const { user, sign } = useUser()
2627
const { signOut } = useAuth()
28+
const { openSnackbar } = useStore()
29+
30+
const logOut = () => {
31+
try {
32+
signOut()
33+
openSnackbar('Logged in successfully')
34+
} catch (error) {
35+
openSnackbar(error.message, 'error')
36+
}
37+
}
2738

2839
return (
2940
<>
@@ -52,7 +63,7 @@ const AccountMenuItems = ({ handleClose, handleClick, open }) => {
5263
<ChevronRight fontSize="small" />
5364
</ListItemIcon>
5465
</MenuItem>
55-
<MenuItem onClick={signOut}>
66+
<MenuItem onClick={logOut}>
5667
<ListItemIcon>
5768
<Logout fontSize="small" />
5869
</ListItemIcon>

client/src/components/PostCard.jsx

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,13 @@ const EditCard = ({ post, setEditing }) => {
177177
if (!validateInputs()) {
178178
return
179179
}
180-
try {
181-
updatePost({
182-
...editedPost,
183-
media: editedPost.media
184-
? await convertToBase64(editedPost.media)
185-
: editedPost.imageUrl
186-
})
187-
setEditing(false)
188-
} catch (error) {
189-
console.error(error)
190-
}
180+
updatePost({
181+
...editedPost,
182+
media: editedPost.media
183+
? await convertToBase64(editedPost.media)
184+
: editedPost.imageUrl
185+
})
186+
setEditing(false)
191187
}
192188

193189
return (
@@ -333,15 +329,9 @@ const EditCard = ({ post, setEditing }) => {
333329
const StaticCard = ({ post, setEditing }) => {
334330
const { user } = useUser()
335331
const navigate = useNavigate()
336-
console.log(post)
332+
337333
return (
338-
<Card
339-
sx={{
340-
position: 'relative',
341-
cursor: 'pointer',
342-
height: 1
343-
}}
344-
>
334+
<Card sx={{ position: 'relative', cursor: 'pointer', height: 1, maxHeight:400 }}>
345335
<CardHeader
346336
avatar={
347337
<UserAvatar
Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,65 @@
1+
import { useTrendingTags } from '@/hooks'
12
import {
23
List,
34
ListItem,
45
ListItemText,
56
Typography,
6-
Box,
7-
Paper
7+
Paper,
8+
CircularProgress
89
} from '@mui/material'
9-
import { Link, useNavigate } from 'react-router'
10+
import { Link } from 'react-router'
1011

11-
const TrendingTags = ({ tags }) => {
12-
const navigate = useNavigate()
12+
const TrendingTags = () => {
13+
const { data: tags, isLoading } = useTrendingTags()
1314
return (
1415
<Paper sx={{ p: 2 }} role="presentation" elevation={0}>
1516
<Typography variant="h6" gutterBottom>
1617
Trending Topics
1718
</Typography>
18-
<List sx={{ p: 0 }}>
19-
{tags.map((tag) => (
20-
<ListItem
21-
key={tag.hashtag}
22-
to={`/hashtag/${tag.hashtag}`}
23-
sx={{
24-
cursor: 'pointer',
25-
':hover': {
26-
bgcolor: 'primary.main',
27-
transition: 'background-color 0.2s'
28-
},
29-
p: 0.5,
30-
px: 1,
31-
textDecoration: 'none',
32-
color: 'inherit',
33-
borderRadius: 1
34-
}}
35-
component={Link}
36-
>
37-
<ListItemText
38-
primary={`#${tag.hashtag}`}
39-
secondary={`${tag.count} posts`}
40-
primaryTypographyProps={{
41-
fontWeight: 'medium'
42-
}}
43-
secondaryTypographyProps={{
44-
fontSize: '0.8rem',
45-
color: 'text.muted'
46-
}}
47-
/>
48-
</ListItem>
49-
))}
50-
</List>
19+
{isLoading ? (
20+
<CircularProgress size={20} />
21+
) : (
22+
<TagsList tags={tags} />
23+
)}
5124
</Paper>
5225
)
5326
}
5427

28+
const TagsList = ({ tags }) => {
29+
return (
30+
<List sx={{ p: 0 }}>
31+
{tags.map((tag) => (
32+
<ListItem
33+
key={tag.hashtag}
34+
to={`/hashtag/${tag.hashtag}`}
35+
sx={{
36+
cursor: 'pointer',
37+
':hover': {
38+
bgcolor: 'primary.main',
39+
transition: 'background-color 0.2s'
40+
},
41+
p: 0.5,
42+
px: 1,
43+
textDecoration: 'none',
44+
color: 'inherit',
45+
borderRadius: 1
46+
}}
47+
component={Link}
48+
>
49+
<ListItemText
50+
primary={`#${tag.hashtag}`}
51+
secondary={`${tag.count} posts`}
52+
primaryTypographyProps={{
53+
fontWeight: 'medium'
54+
}}
55+
secondaryTypographyProps={{
56+
fontSize: '0.8rem',
57+
color: 'text.muted'
58+
}}
59+
/>
60+
</ListItem>
61+
))}
62+
</List>
63+
)
64+
}
5565
export default TrendingTags

client/src/hooks/posts.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ export const useGetPosts = () =>
2323
getNextPageParam: (lastPage) => lastPage.nextCursor
2424
})
2525

26+
export const useSearchPosts = (query) =>
27+
useInfiniteQuery({
28+
queryKey: ['search-posts', query],
29+
queryFn: ({ pageParam }) => searchPosts(query, pageParam, 6),
30+
getNextPageParam: (lastPage) => lastPage.nextCursor
31+
})
32+
2633
export const useGetPost = (id) =>
2734
useQuery({
2835
queryKey: ['post', id],
@@ -163,13 +170,6 @@ export const useDeletePost = () => {
163170
})
164171
}
165172

166-
export const useSearchPosts = () => {
167-
return useQuery({
168-
queryKey: ['searchPosts'],
169-
queryFn: () => searchPosts
170-
})
171-
}
172-
173173
export const useRefresh = () => {
174174
const queryClient = useQueryClient()
175175
const [refreshing, setRefreshing] = useState(false)

client/src/hooks/tags.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useQuery } from '@tanstack/react-query'
2-
import { searchTags } from '@/api'
1+
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
2+
import { getTrendingTags, searchPostsByTags, searchTags } from '@/api'
33

44
export const useSearchTags = (input) =>
55
useQuery({
@@ -9,3 +9,17 @@ export const useSearchTags = (input) =>
99
staleTime: 1000 * 60 * 5,
1010
gcTime: 1000 * 60 * 30
1111
})
12+
13+
export const useTrendingTags = () =>
14+
useQuery({
15+
queryKey: ['tags'],
16+
queryFn: getTrendingTags,
17+
staleTime: Infinity
18+
})
19+
20+
export const useSearchPostsByTag = (tag) =>
21+
useInfiniteQuery({
22+
queryKey: ['search-tags', tag],
23+
queryFn: ({ pageParam }) => searchPostsByTags(tag, pageParam, 6),
24+
getNextPageParam: (lastPage) => lastPage.nextCursor
25+
})

client/src/pages/LogIn.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { LockOutlined } from '@mui/icons-material'
1515
import { useSignIn } from '@clerk/clerk-react'
1616
import { OAuthButtons } from '@/components'
1717
import { useState } from 'react'
18+
import { useStore } from '@/store'
1819

1920
const Form = () => {
2021
const initialState = { email: '', password: '' }
@@ -25,7 +26,7 @@ const Form = () => {
2526

2627
const handleChange = (e) =>
2728
setFormData({ ...formData, [e.target.name]: e.target.value })
28-
29+
const { openSnackbar } = useStore()
2930
const handleSubmit = async (event) => {
3031
event.preventDefault()
3132
setError('')
@@ -40,6 +41,7 @@ const Form = () => {
4041

4142
if (result.status === 'complete') {
4243
await setActive({ session: result.createdSessionId })
44+
openSnackbar('Logged in successfully')
4345
navigate('/')
4446
} else {
4547
console.error('Sign-in failed', result)

client/src/pages/Post.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const PostCard = ({ post, isLoading, error }) => {
6666
if (error?.message === 'API Error: Post not found') {
6767
navigate('/not-found')
6868
}
69+
document.title = `Memories | ${post.title}`
6970
return (
7071
<Card sx={{ width: 1 }}>
7172
<CardMedia component="img" image={post.imageUrl} alt="Post cover" />
@@ -149,6 +150,7 @@ const Top3Reactions = ({ post }) => {
149150
const Post = () => {
150151
const { id } = useParams()
151152
const { data: post, isLoading, error } = useGetPost(id)
153+
152154
return (
153155
<Container sx={{ py: { xs: 2, md: 4 }, mb: 10 }} maxWidth="xl">
154156
<Grid container spacing={3}>

client/src/pages/Posts.jsx

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,37 +60,15 @@ const PostGrid = () => {
6060
}
6161

6262
const Posts = () => {
63-
// const { data: tags } = useGetTrendingTags()
64-
const tags = [
65-
{
66-
hashtag: 'media',
67-
count: 5
68-
},
69-
{
70-
hashtag: 'post',
71-
count: 5
72-
},
73-
{
74-
hashtag: 'social',
75-
count: 5
76-
},
77-
{
78-
hashtag: 'love',
79-
count: 3
80-
},
81-
{
82-
hashtag: 'chocolates',
83-
count: 2
84-
}
85-
]
8663
return (
8764
<Container sx={{ py: { xs: 2, md: 4 }, height: '100vh' }} maxWidth="xl">
8865
<Grid container spacing={3}>
8966
<Grid
9067
container
9168
size={{ xs: 12, md: 8, xl: 9 }}
9269
overflow="auto"
93-
height={'calc(100vh - 100px)'}
70+
height={'calc(100vh - 170px)'}
71+
minHeight={400}
9472
sx={{
9573
'&::-webkit-scrollbar': { display: 'none' },
9674
scrollbarWidth: 'none',
@@ -112,8 +90,7 @@ const Posts = () => {
11290
</Paper>
11391
</Grid>
11492
<Grid size={{ xs: 12 }}>
115-
{/* <SearchForm /> */}
116-
<TrendingTags tags={tags} />
93+
<TrendingTags />
11794
</Grid>
11895
</Grid>
11996
</Grid>

0 commit comments

Comments
 (0)