import React from 'react'; import { useIntl, defMsg, Msg, IntlShape, IntlHelper } from '@tutorbook/intl'; import { Callback, Option, Timeslot, User, Query } from '@tutorbook/model'; import { v4 as uuid } from 'uuid'; import Carousel from '@tutorbook/carousel'; import RequestDialog from '@tutorbook/request-dialog'; import Utils from '@tutorbook/utils'; import Result from './result'; import Form from './form'; import styles from './search.module.scss'; interface SearchProps { readonly onChange: Callback; readonly results: ReadonlyArray; readonly searching: boolean; readonly query: Query; readonly user?: User; } const msgs: Record = defMsg({ noResultsTitle: { id: 'search.no-results.title', defaultMessage: 'No Results', }, noResultsBody: { id: 'search.no-results.body', defaultMessage: "We couldn't find anyone matching those filters. But here are some " + 'suggestions:', }, }); export default function Search({ user, query, results, searching, onChange, }: SearchProps): JSX.Element { const intl: IntlShape = useIntl(); const msg: IntlHelper = (message: Msg) => intl.formatMessage(message); const [viewing, setViewing] = React.useState(user); const [elevated, setElevated] = React.useState(false); const formRef: React.RefObject = React.createRef(); React.useEffect(() => { const listener = () => { if (!formRef.current) return; const viewportOffset = formRef.current.getBoundingClientRect(); const updated: boolean = viewportOffset.top <= 74; // We have to wait a tick before changing the class for the animation to // work. @see {@link https://stackoverflow.com/a/37643388/10023158} if (updated !== elevated) setTimeout(() => setElevated(updated), 100); }; window.addEventListener('scroll', listener); return () => window.removeEventListener('scroll', listener); }); return (
{viewing && ( setViewing(undefined)} subjects={Utils.intersection, string>( query.subjects, viewing[query.aspect].subjects, (a: Option, b: string) => a.value === b )} time={ Utils.intersection( query.availability, viewing.availability, (a: Timeslot, b: Timeslot) => a.equalTo(b) )[0] } /> )}
{searching && !results.length && (
    {Array(5) .fill(null) .map(() => ( ))}
)} {!!results.length && (
    {results.map((res: User) => ( setViewing(res)} /> ))}
)} {!searching && !results.length && (

{msg(msgs.noResultsTitle)}

{msg(msgs.noResultsBody)}

)}
); }