-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(search): add basic search functionality
this commit adds basic search feature. fix: https://codeberg.org/zyachel/libremdb/issues/9, #10
- Loading branch information
Showing
25 changed files
with
1,191 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Companies } from '../../interfaces/shared/search'; | ||
import Link from 'next/link'; | ||
|
||
import styles from '../../styles/modules/components/find/company.module.scss'; | ||
|
||
type Props = { | ||
company: Companies[0]; | ||
}; | ||
|
||
const Company = ({ company }: Props) => { | ||
return ( | ||
<li className={styles.company}> | ||
<Link href={`name/${company.id}`}> | ||
<a className={`heading ${styles.heading}`}>{company.name}</a> | ||
</Link> | ||
{company.country && <p>{company.country}</p>} | ||
{!!company.type && <p>{company.type}</p>} | ||
</li> | ||
); | ||
}; | ||
|
||
export default Company; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Keywords } from '../../interfaces/shared/search'; | ||
import Link from 'next/link'; | ||
|
||
import styles from '../../styles/modules/components/find/keyword.module.scss'; | ||
|
||
type Props = { | ||
keyword: Keywords[0]; | ||
}; | ||
|
||
const Keyword = ({ keyword }: Props) => { | ||
return ( | ||
<li className={styles.keyword}> | ||
<Link href={`name/${keyword.id}`}> | ||
<a className={`heading ${styles.heading}`}>{keyword.text}</a> | ||
</Link> | ||
{keyword.numTitles && <p>{keyword.numTitles} titles</p>} | ||
</li> | ||
); | ||
}; | ||
|
||
export default Keyword; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { People } from '../../interfaces/shared/search'; | ||
import Image from 'next/future/image'; | ||
import Link from 'next/link'; | ||
import { modifyIMDbImg } from '../../utils/helpers'; | ||
import styles from '../../styles/modules/components/find/person.module.scss'; | ||
|
||
type Props = { | ||
person: People[0]; | ||
}; | ||
|
||
const Person = ({ person }: Props) => { | ||
return ( | ||
<li className={styles.person}> | ||
<div className={styles.imgContainer} style={{ position: 'relative' }}> | ||
{person.image ? ( | ||
<Image | ||
src={modifyIMDbImg(person.image.url, 400)} | ||
alt={person.image.caption} | ||
fill | ||
className={styles.img} | ||
/> | ||
) : ( | ||
<svg className={styles.imgNA}> | ||
<use href="/svg/sprite.svg#icon-image-slash" /> | ||
</svg> | ||
)} | ||
</div> | ||
<div className={styles.info}> | ||
<Link href={`name/${person.id}`}> | ||
<a className={`heading ${styles.heading}`}>{person.name}</a> | ||
</Link> | ||
{person.aka && <p>{person.aka}</p>} | ||
{person.jobCateogry && <p>{person.jobCateogry}</p>} | ||
{(person.knownForTitle || person.knownInYear) && ( | ||
<ul className={styles.basicInfo} aria-label="quick facts"> | ||
{person.knownForTitle && <li>{person.knownForTitle}</li>} | ||
{person.knownInYear && <li>{person.knownInYear}</li>} | ||
</ul> | ||
)} | ||
</div> | ||
</li> | ||
); | ||
}; | ||
|
||
export default Person; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Titles } from '../../interfaces/shared/search'; | ||
import Image from 'next/future/image'; | ||
import Link from 'next/link'; | ||
import { modifyIMDbImg } from '../../utils/helpers'; | ||
|
||
import styles from '../../styles/modules/components/find/title.module.scss'; | ||
|
||
type Props = { | ||
title: Titles[0]; | ||
}; | ||
|
||
const Title = ({ title }: Props) => { | ||
return ( | ||
<li className={styles.title}> | ||
<div className={styles.imgContainer}> | ||
{title.image ? ( | ||
<Image | ||
src={modifyIMDbImg(title.image.url, 400)} | ||
alt={title.image.caption} | ||
fill | ||
className={styles.img} | ||
/> | ||
) : ( | ||
<svg className={styles.imgNA}> | ||
<use href="/svg/sprite.svg#icon-image-slash" /> | ||
</svg> | ||
)} | ||
</div> | ||
<div className={styles.info}> | ||
<Link href={`/title/${title.id}`}> | ||
<a className={`heading ${styles.heading}`}>{title.name}</a> | ||
</Link> | ||
<ul aria-label="quick facts" className={styles.basicInfo}> | ||
{title.type && <li>{title.type}</li>} | ||
{title.sAndE && <li>{title.sAndE}</li>} | ||
{title.releaseYear && <li>{title.releaseYear}</li>} | ||
</ul> | ||
{!!title.credits.length && ( | ||
<p className={styles.stars}> | ||
<span>Stars: </span> | ||
{title.credits.join(', ')} | ||
</p> | ||
)} | ||
{title.seriesId && ( | ||
<ul aria-label="quick series facts" className={styles.seriesInfo}> | ||
{title.seriesType && <li>{title.seriesType}</li>} | ||
<li> | ||
<Link href={`/title/${title.seriesId}`}> | ||
<a className="link">{title.seriesName}</a> | ||
</Link> | ||
</li> | ||
{title.seriesReleaseYear && <li>{title.seriesReleaseYear}</li>} | ||
</ul> | ||
)} | ||
</div> | ||
</li> | ||
); | ||
}; | ||
|
||
export default Title; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import Find from '../../interfaces/shared/search'; | ||
import Company from './Company'; | ||
import Person from './Person'; | ||
import Title from './Title'; | ||
|
||
import styles from '../../styles/modules/components/find/results.module.scss'; | ||
import Keyword from './Keyword'; | ||
import { getResTitleTypeHeading } from '../../utils/helpers'; | ||
|
||
type Props = { | ||
results: Find | null; | ||
className?: string; | ||
title: string; | ||
}; | ||
|
||
const resultsExist = (results: Props['results']) => { | ||
if ( | ||
!results || | ||
(!results.people.length && | ||
!results.keywords.length && | ||
!results.companies.length && | ||
!results.titles.length) | ||
) | ||
return false; | ||
|
||
return true; | ||
}; | ||
|
||
// MAIN COMPONENT | ||
const Results = ({ results, className, title }: Props) => { | ||
if (!resultsExist(results)) | ||
return ( | ||
<h1 className={`heading heading__primary ${className}`}> | ||
No results found | ||
</h1> | ||
); | ||
|
||
const { titles, people, keywords, companies, meta } = results!; | ||
const titlesSectionHeading = getResTitleTypeHeading( | ||
meta.type, | ||
meta.titleType | ||
); | ||
|
||
return ( | ||
<article className={`${className} ${styles.results}`}> | ||
<h1 className="heading heading__primary">Results for '{title}'</h1> | ||
<div className={styles.results__list}> | ||
{!!titles.length && ( | ||
<section className={styles.titles}> | ||
<h2 className="heading heading__secondary"> | ||
{titlesSectionHeading} | ||
</h2> | ||
<ul className={styles.titles__list}> | ||
{titles.map(title => ( | ||
<Title title={title} key={title.id} /> | ||
))} | ||
</ul> | ||
</section> | ||
)} | ||
{!!people.length && ( | ||
<section className={styles.people}> | ||
<h2 className="heading heading__secondary">People</h2> | ||
<ul className={styles.people__list}> | ||
{people.map(person => ( | ||
<Person person={person} key={person.id} /> | ||
))} | ||
</ul> | ||
</section> | ||
)} | ||
{!!companies.length && ( | ||
<section className={styles.people}> | ||
<h2 className="heading heading__secondary">Companies</h2> | ||
<ul className={styles.people__list}> | ||
{companies.map(company => ( | ||
<Company company={company} key={company.id} /> | ||
))} | ||
</ul> | ||
</section> | ||
)} | ||
{!!keywords.length && ( | ||
<section className={styles.people}> | ||
<h2 className="heading heading__secondary">Keywords</h2> | ||
<ul className={styles.people__list}> | ||
{keywords.map(keyword => ( | ||
<Keyword keyword={keyword} key={keyword.id} /> | ||
))} | ||
</ul> | ||
</section> | ||
)} | ||
</div> | ||
</article> | ||
); | ||
}; | ||
|
||
export default Results; |
Oops, something went wrong.