Skip to content

Commit

Permalink
Add Search component
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilleAngulo committed Jul 2, 2021
1 parent 62a57c5 commit afe636e
Show file tree
Hide file tree
Showing 31 changed files with 1,308 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ NEXTAUTH_URL=http://localhost:3000
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
NEXT_PUBLIC_IMAGE_HOST=http://localhost:1337
NEXT_PUBLIC_GA_TRACKING=

NEXT_PUBLIC_MEILISEARCH_SERVER=http://localhost:7700
NEXT_PUBLIC_MEILISEARCH_PUBLIC_KEY=
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
},
"dependencies": {
"@apollo/client": "^3.3.20",
"@meilisearch/instant-meilisearch": "^0.5.0",
"@stripe/react-stripe-js": "^1.4.1",
"@stripe/stripe-js": "^1.15.1",
"@styled-icons/boxicons-regular": "^10.34.0",
Expand All @@ -57,6 +58,7 @@
"polished": "^4.1.3",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-instantsearch-dom": "^6.11.2",
"react-slick": "^0.28.1",
"storybook-addon-next-router": "^2.0.4",
"styled-components": "5.3.0",
Expand All @@ -78,6 +80,7 @@
"@types/jest": "^26.0.23",
"@types/node": "^15.12.4",
"@types/react": "^17.0.11",
"@types/react-instantsearch-dom": "^6.10.1",
"@types/react-slick": "^0.23.4",
"@types/styled-components": "^5.1.10",
"@typescript-eslint/eslint-plugin": "^4.28.0",
Expand Down
6 changes: 5 additions & 1 deletion src/components/Banner/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ exports[`<Banner /> should render correctly 1`] = `
padding: 0.8rem 4.8rem;
}
.c5 > span {
white-space: nowrap;
}
.c5:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -156,4 +160,4 @@ exports[`<Banner /> should render correctly 1`] = `
</a>
</div>
</main>
`;
`
4 changes: 4 additions & 0 deletions src/components/Button/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ exports[`<Button /> should render the medium size by default 1`] = `
padding: 0.8rem 3.2rem;
}
.c0 > span {
white-space: nowrap;
}
.c0:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export const Wrapper = styled.button<WrapperProps>`
padding: ${theme.spacings.xxsmall};
text-decoration: none;
& > span {
white-space: nowrap;
}
&:focus {
box-shadow: 0 0 0 3px ${theme.colors.secondary};
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Empty/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ exports[`<Empty /> should render correctly 1`] = `
padding: 0.8rem 3.2rem;
}
.c3 > span {
white-space: nowrap;
}
.c3:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/FormSignIn/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ exports[`<FormSignIn /> should render the form 1`] = `
width: 100%;
}
.c8 > span {
white-space: nowrap;
}
.c8:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/FormSignUp/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ exports[`<FormSignUp /> should render the form 1`] = `
width: 100%;
}
.c7 > span {
white-space: nowrap;
}
.c7:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down
10 changes: 9 additions & 1 deletion src/components/GameCard/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ exports[`<GameCard /> should render correctly 1`] = `
color: #F231A5;
}
.c7 > span {
white-space: nowrap;
}
.c7:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -81,6 +85,10 @@ exports[`<GameCard /> should render correctly 1`] = `
font-size: 1.2rem;
}
.c11 > span {
white-space: nowrap;
}
.c11:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -294,4 +302,4 @@ exports[`<GameCard /> should render correctly 1`] = `
</div>
</div>
</article>
`;
`
10 changes: 9 additions & 1 deletion src/components/GameInfo/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ exports[`<GameInfo /> should render game informations 1`] = `
padding: 0.8rem 4.8rem;
}
.c6 > span {
white-space: nowrap;
}
.c6:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -79,6 +83,10 @@ exports[`<GameInfo /> should render game informations 1`] = `
color: #F231A5;
}
.c8 > span {
white-space: nowrap;
}
.c8:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -309,4 +317,4 @@ exports[`<GameInfo /> should render game informations 1`] = `
</button>
</div>
</div>
`;
`
6 changes: 5 additions & 1 deletion src/components/Highlight/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ exports[`<Highlight /> should render headings and button 1`] = `
padding: 0.8rem 3.2rem;
}
.c5 > span {
white-space: nowrap;
}
.c5:focus {
box-shadow: 0 0 0 3px #3CD3C1;
}
Expand Down Expand Up @@ -139,4 +143,4 @@ exports[`<Highlight /> should render headings and button 1`] = `
</a>
</div>
</section>
`;
`
6 changes: 2 additions & 4 deletions src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Link from 'next/link'

import { useState } from 'react'
import { Menu2 as MenuIcon } from '@styled-icons/remix-fill/Menu2'
import { Search as SearchIcon } from '@styled-icons/material-outlined/Search'
import { Close as CloseIcon } from '@styled-icons/material-outlined/Close'

import Button from 'components/Button'
Expand All @@ -12,6 +11,7 @@ import * as S from './styles'
import CartDropdown from 'components/CartDropdown'
import CartIcon from 'components/CartIcon'
import UserDropdown from 'components/UserDropdown'
import Search from 'components/Search'

export type MenuProps = {
username?: string | null
Expand Down Expand Up @@ -51,9 +51,7 @@ const Menu = ({ username, loading }: MenuProps) => {
{!loading && (
<>
<S.MenuGroup>
<S.IconWrapper>
<SearchIcon aria-label="Search" />
</S.IconWrapper>
<Search />
<S.IconWrapper>
<MediaMatch greaterThan="medium">
<CartDropdown />
Expand Down
9 changes: 8 additions & 1 deletion src/components/Menu/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ useRouter.mockImplementation(() => ({
query: {}
}))

jest.mock('components/Search', () => ({
__esModule: true,
default: function Mock() {
return <div data-testid="Mock Search" />
}
}))

describe('<Menu />', () => {
it('should render the menu', () => {
render(<Menu />)

expect(screen.getByLabelText(/open menu/i)).toBeInTheDocument()
expect(screen.getByRole('img', { name: /won games/i })).toBeInTheDocument()
expect(screen.getByLabelText(/search/i)).toBeInTheDocument()
expect(screen.getByTestId(/mock search/i)).toBeInTheDocument()
expect(screen.getAllByLabelText(/shopping cart/i)).toHaveLength(2)
})

Expand Down
68 changes: 68 additions & 0 deletions src/components/Search/Hits/Hit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Image from 'next/image'
import Link from 'next/link'

import { Highlight } from 'react-instantsearch-dom'
import { getImageUrl } from 'utils/getImageUrl'
import formatPrice from 'utils/format-price'

import { Apple, Windows, Linux } from '@styled-icons/fa-brands'
import * as S from './styles'

import { GameHitProps, Platform } from '.'

export type HitProps = {
hit: GameHitProps
}

const Hit = ({ hit }: HitProps) => {
const platformIcons = {
linux: <Linux title="Linux" />,
mac: <Apple title="Mac" />,
windows: <Windows title="Windows" />
}
const releaseYear =
hit.release_date && new Date(hit.release_date).getFullYear()

return (
<Link href={`game/${hit.slug}`} passHref>
<S.Result>
<S.ImageWrapper>
<Image
src={`${getImageUrl(hit.cover?.url)}`}
alt={hit.name}
layout="fill"
objectFit="cover"
/>
</S.ImageWrapper>
<S.Info>
<S.Title>
<Highlight attribute="name" hit={hit} />
{releaseYear && (
<S.ReleaseYear
itemProp="releaseYear"
dateTime={hit.release_date!}
>
{releaseYear}
</S.ReleaseYear>
)}
</S.Title>
<S.Details>
<S.Price>{formatPrice(hit.price)}</S.Price>
<S.Platform>
{hit.platforms.map((icon: Platform) => (
<S.PlatformIcon key={`${hit.id}${icon.name}`}>
{platformIcons[icon.name]}
</S.PlatformIcon>
))}
</S.Platform>
</S.Details>
<S.Description>
<Highlight attribute="short_description" hit={hit} />
</S.Description>
</S.Info>
</S.Result>
</Link>
)
}

export default Hit
47 changes: 47 additions & 0 deletions src/components/Search/Hits/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { connectHits, connectStateResults } from 'react-instantsearch-dom'

import NoResults from '../NoResults'
import Hit from './Hit'

import * as S from './styles'

export type Platform = {
name: 'windows' | 'linux' | 'mac'
}

export type Cover = {
url: string
}

export type GameHitProps = {
id: string
name: string
short_description: string
cover: Cover | null
slug: string
price: number
platforms: Platform[]
release_date: string | null
}

export type HitsProps = {
hits: GameHitProps[]
}

const Hits = connectHits(({ hits }: HitsProps) => (
<S.List>
{hits.length ? (
hits.map((hit) => (
<S.ListItem key={hit.id}>
<Hit hit={hit} />
</S.ListItem>
))
) : (
<NoResults />
)}
</S.List>
))

export default connectStateResults(({ searchState }) =>
searchState?.query ? <Hits /> : null
)
28 changes: 28 additions & 0 deletions src/components/Search/Hits/mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { GameHitProps } from '.'

export default [
{
id: '1',
name: 'Game 1',
short_description: 'Description',
cover: {
url: '/cover-1.jpg'
},
slug: 'game-1',
price: 25,
platforms: [{ name: 'windows' }],
release_date: '2015-12-05'
},
{
id: '2',
name: 'Game 2',
short_description: 'Description',
cover: {
url: '/cover-2.jpg'
},
slug: 'game-2',
price: 12,
platforms: [{ name: 'linux' }],
release_date: '2006-10-30'
}
] as GameHitProps[]
Loading

0 comments on commit afe636e

Please sign in to comment.