feat: begin building out search results component
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { useRouter } from '@/hooks';
|
||||
import { SignedIn, SignedOut, useUser } from '@clerk/nextjs';
|
||||
import Link from 'next/link';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -16,8 +17,10 @@ import ThemeButton from './ThemeButton';
|
||||
import UserButton from './UserButton';
|
||||
|
||||
export default function Navbar() {
|
||||
const [term, setTerm] = useState('');
|
||||
const { user } = useUser();
|
||||
const [navOpen, setNavOpen] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
function handler() {
|
||||
@@ -57,13 +60,27 @@ export default function Navbar() {
|
||||
<ul className='flex flex-col w-full items-start gap-4 md:flex-row md:items-center md:max-w-min'>
|
||||
<SignedIn>
|
||||
<li className='flex w-full'>
|
||||
<div className='flex w-full'>
|
||||
<form
|
||||
onSubmit={e => {
|
||||
e.preventDefault();
|
||||
router.push(`/search/${term}`);
|
||||
}}
|
||||
className='flex w-full relative'
|
||||
>
|
||||
<input
|
||||
onChange={e => setTerm(e.target.value)}
|
||||
value={term}
|
||||
type='text'
|
||||
placeholder='Search'
|
||||
className='w-full md:w-[unset] py-1 px-2 rounded-md border border-gray-600 dark:bg-primary-gray dark:border-0'
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
disabled={!term || !term.trim()}
|
||||
type='submit'
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
<div className='flex items-center gap-2'>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
'use client';
|
||||
|
||||
import { UsePaginatedQueryReturnType, usePaginatedQuery } from 'convex/react';
|
||||
import { FunctionReference } from 'convex/server';
|
||||
import { useState } from 'react';
|
||||
import { api } from '../../convex/_generated/api';
|
||||
import { Id } from '../../convex/_generated/dataModel';
|
||||
import UserProfile from './UserProfile';
|
||||
|
||||
type UserSearchResultsPager = UsePaginatedQueryReturnType<
|
||||
FunctionReference<
|
||||
'query',
|
||||
'public',
|
||||
{
|
||||
term: string;
|
||||
paginationOpts: {
|
||||
id?: number | undefined;
|
||||
numItems: number;
|
||||
cursor: string | null;
|
||||
};
|
||||
},
|
||||
{
|
||||
page: {
|
||||
_id: Id<'users'>;
|
||||
_creationTime: number;
|
||||
clerkUsername: string | null;
|
||||
clerkImageUrl: string;
|
||||
clerkUserId: string;
|
||||
}[];
|
||||
isDone: boolean;
|
||||
continueCursor: string;
|
||||
}
|
||||
>
|
||||
>;
|
||||
|
||||
function UserSearchResults({ pager }: { pager: UserSearchResultsPager }) {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{pager.results.map(user => (
|
||||
<div key={user._id}>
|
||||
<UserProfile user={user} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function SearchResults({ term }: { term: string }) {
|
||||
const PAGE_SIZE = 10;
|
||||
const [current, setCurrent] = useState<'posts' | 'users'>('posts');
|
||||
|
||||
const postsPager = usePaginatedQuery(
|
||||
api.posts.getPostsBySearchTerm,
|
||||
{ term },
|
||||
{ initialNumItems: PAGE_SIZE }
|
||||
);
|
||||
const usersPager = usePaginatedQuery(
|
||||
api.users.getUsersBySearchTerm,
|
||||
{ term },
|
||||
{ initialNumItems: PAGE_SIZE }
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='flex gap-2 border-b border-gray-600'>
|
||||
<button
|
||||
onClick={() => setCurrent('posts')}
|
||||
disabled={current === 'posts'}
|
||||
type='button'
|
||||
className='py-1 px-2 border-b-4 border-transparent disabled:border-primary-accent'
|
||||
>
|
||||
Posts
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setCurrent('users')}
|
||||
disabled={current === 'users'}
|
||||
type='button'
|
||||
className='py-1 px-2 border-b-4 border-transparent disabled:border-primary-accent'
|
||||
>
|
||||
Users
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{current === 'posts' ? 'Posts' : <UserSearchResults pager={usersPager} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user