Skip to content

Commit

Permalink
Merge pull request #241 from UTDNebula/search-bar-submit
Browse files Browse the repository at this point in the history
Search bar Submit functionality.
  • Loading branch information
nl32 authored Oct 3, 2024
2 parents eae9bf3 + 906cc94 commit eca5322
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 41 deletions.
6 changes: 6 additions & 0 deletions src/components/searchBar/ClubSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export const ClubSearchBar = () => {
setSearch={setSearch}
searchResults={data || []}
onClick={onClickSearchResult}
submitButton
submitLogic={() => {
if (data && data[0]) {
onClickSearchResult(data[0]);
}
}}
/>
);
};
6 changes: 6 additions & 0 deletions src/components/searchBar/DebouncedSearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ export type DebouncedSearchBarProps<T extends SearchElement> = {
setSearch: Dispatch<SetStateAction<string>>;
searchResults?: Array<T>;
onClick?: (input: T) => void;
submitButton?: boolean;
submitLogic?: () => void;
};
export const DebouncedSearchBar = <T extends SearchElement>({
placeholder,
value,
setSearch,
searchResults,
onClick,
submitButton,
submitLogic,
}: DebouncedSearchBarProps<T>) => {
const [input, setInput] = useState<string>(value ?? '');
const [focused, setFocused] = useState(false);
Expand All @@ -48,6 +52,8 @@ export const DebouncedSearchBar = <T extends SearchElement>({
onChange={handleSearch}
onFocus={() => setFocused(true)}
onBlur={() => setTimeout(() => setFocused(false), 300)}
submitButton={submitButton}
submitLogic={submitLogic}
/>
{input && focused && searchResults && searchResults.length > 0 && (
<div className="absolute left-0 right-0 top-full z-50 mt-1 rounded-sm shadow-lg">
Expand Down
27 changes: 14 additions & 13 deletions src/components/searchBar/EventClubSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import { useState, useEffect } from 'react';
import { useState } from 'react';
import type { SelectClub as Club } from '@src/server/db/models';
import { api } from '@src/trpc/react';
import { DebouncedSearchBar } from './DebouncedSearchBar';
Expand All @@ -9,29 +9,30 @@ type EventClubSearchBarProps = {
};
export const EventClubSearchBar = ({ addClub }: EventClubSearchBarProps) => {
const [search, setSearch] = useState('');
const [res, setRes] = useState<Club[]>([]);
const utils = api.useUtils();
const clubQuery = api.club.byName.useQuery(
const { data } = api.club.byName.useQuery(
{ name: search },
{
enabled: !!search,
},
);
useEffect(() => {
if (clubQuery.data) {
setRes(clubQuery.data);
}
}, [clubQuery.data]);
const submit = (club: Club) => {
void utils.club.byId.prefetch({ id: club.id });
addClub(club.id);
setSearch('');
};
return (
<DebouncedSearchBar
placeholder="Select a club"
setSearch={setSearch}
value={search}
searchResults={res}
onClick={(club) => {
void utils.club.byId.prefetch({ id: club.id });
addClub(club.id);
setSearch('');
searchResults={data || []}
onClick={submit}
submitButton
submitLogic={() => {
if (data && data[0]) {
submit(data[0]);
}
}}
/>
);
Expand Down
22 changes: 12 additions & 10 deletions src/components/searchBar/EventSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import { useState, useEffect } from 'react';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { api } from '@src/trpc/react';
import type { SelectEvent as Event } from '@src/server/db/models';
Expand All @@ -8,26 +8,28 @@ import { DebouncedSearchBar } from './DebouncedSearchBar';
export const EventSearchBar = () => {
const router = useRouter();
const [search, setSearch] = useState<string>('');
const [res, setRes] = useState<Event[]>([]);

const eventQuery = api.event.byName.useQuery(
const { data } = api.event.byName.useQuery(
{
name: search,
sortByDate: true,
},
{ enabled: !!search },
);
useEffect(() => {
if (eventQuery.data) setRes(eventQuery.data);
}, [eventQuery.data]);

const onClickSearchResult = (event: Event) => {
router.push(`/event/${event.id}`);
};
return (
<DebouncedSearchBar
placeholder="Search for Events"
setSearch={setSearch}
searchResults={res}
onClick={(event) => {
router.push(`/event/${event.id}`);
searchResults={data || []}
onClick={onClickSearchResult}
submitButton
submitLogic={() => {
if (data && data[0]) {
onClickSearchResult(data[0]);
}
}}
/>
);
Expand Down
27 changes: 13 additions & 14 deletions src/components/searchBar/UserSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
'use client';
import { type SelectUserMetadata } from '@src/server/db/models';
import { api } from '@src/trpc/react';
import { useState, useEffect } from 'react';
import { useState } from 'react';
import { DebouncedSearchBar } from './DebouncedSearchBar';

type UserSearchBarProps = {
passUser: (user: { id: string; name: string }) => void;
};
type User = {
name: string;
} & SelectUserMetadata;
export const UserSearchBar = ({ passUser }: UserSearchBarProps) => {
const [search, setSearch] = useState('');
const [res, setRes] = useState<User[]>([]);
const userQuery = api.userMetadata.searchByName.useQuery(
{ name: search },
{
enabled: !!search,
},
);
useEffect(() => {
if (userQuery.data) {
const newData = userQuery.data.map((val) => {
const formattedData = userQuery.isSuccess
? userQuery.data.map((val) => {
return { name: val.firstName + ' ' + val.lastName, ...val };
});
setRes(newData);
}
}, [userQuery.data]);
})
: [];
return (
<DebouncedSearchBar
placeholder="Search for Someone"
setSearch={setSearch}
value={search}
searchResults={res}
searchResults={formattedData}
onClick={(user) => {
passUser({ id: user.id, name: user.name });
setSearch('');
}}
submitLogic={() => {
if (formattedData && formattedData[0]) {
const user = formattedData[0];
passUser({ id: user.id, name: user.name });
setSearch('');
}
}}
/>
);
};
34 changes: 30 additions & 4 deletions src/components/searchBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { SearchIcon } from '@src/icons/Icons';
import { ComponentProps } from 'react';
import { RightArrowIcon, SearchIcon } from '@src/icons/Icons';
import { type ComponentProps } from 'react';

type SearchBarProps = Omit<ComponentProps<'input'>, 'type'>;
type SearchBarProps = Omit<ComponentProps<'input'>, 'type'> & {
submitButton?: boolean;
submitLogic?: () => void;
};

export const SearchBar = (props: SearchBarProps) => {
const submitButton = props.submitButton;
const submitLogic = props.submitLogic;
return (
<div className="relative">
<span className="absolute inset-y-0 flex items-center pl-3">
Expand All @@ -12,8 +17,29 @@ export const SearchBar = (props: SearchBarProps) => {
<input
{...props}
type="text"
className={`h-10 w-full rounded-full border pl-10 pr-3 focus:outline-none ${props.className}`}
className={`h-10 w-full rounded-full border pl-10 ${submitButton ? 'pr-[38px]' : 'pr-3'} focus:outline-none ${props.className}`}
onKeyDown={(e) => {
if (e.key === 'Enter' && typeof submitLogic !== 'undefined') {
submitLogic();
}
}}
/>
{submitButton && (
<button
type={typeof submitLogic !== 'undefined' ? 'button' : 'submit'}
onClick={
typeof submitLogic !== 'undefined'
? (e) => {
e.preventDefault();
submitLogic();
}
: undefined
}
className="absolute inset-y-0 right-2 flex items-center"
>
<RightArrowIcon fill="fill-[#C3CAD9]" />
</button>
)}
</div>
);
};
Expand Down

0 comments on commit eca5322

Please sign in to comment.