Skip to content

Commit

Permalink
Updated components structure
Browse files Browse the repository at this point in the history
  • Loading branch information
juliolmuller committed May 7, 2021
1 parent 05f558d commit 7b2a19a
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 81 deletions.
15 changes: 7 additions & 8 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { FC, useState } from 'react'
import { useState } from 'react'
import Header from './Header'
import SearchBox from './SearchBox'
import CharactersList from './CharactersList'
import marvel from '../services/marvelApi'
import loadingSpinner from '../assets/images/loading.gif'

const App: FC = () => {
function App() {
const [metadata, setMetadata] = useState({})
const [characters, setCharacters] = useState([])
const [loading, setLoading] = useState(false)
Expand All @@ -23,7 +23,7 @@ const App: FC = () => {
setMetadata(responseMetadata)
setCharacters(results)
} catch (ex) {
console.error(ex)
console.error(ex) // eslint-disable-line no-console
} finally {
setLoading(false)
}
Expand All @@ -38,20 +38,19 @@ const App: FC = () => {

<div className={(loading || characters.length) ? 'd-block' : 'd-none'}>
<hr />
<If condition={loading}>

{loading ? (
<div className="text-center py-5">
<img src={loadingSpinner} alt="Loading animation" />
</div>
</If>

<If condition={!loading}>
) : (
<CharactersList
metadata={metadata}
characters={characters}
currentPage={currentPage}
goToPage={(page: number) => submitSearch(lastSearch, page)}
/>
</If>
)}
</div>
</div>
</div>
Expand Down
51 changes: 26 additions & 25 deletions src/components/CharacterCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
import { FC } from 'react'
import './styles.scss'

interface CharacterCardProps {
showDetails: (CharacterCard?: any) => any
showDetails: (record?: any) => any
character: any
}

const CharacterCard: FC<CharacterCardProps> = ({ character, showDetails }) => (
<div className="col-12 col-md-6">
<div className="card mb-3 border-marvel character-card">
<div className="card-body">
<img
src={`${character.thumbnail.path}.${character.thumbnail.extension}`}
className="figure-fluid float-left"
alt="Character thumbnail"
/>
function CharacterCard({ character, showDetails }: CharacterCardProps) {
return (
<div className="col-12 col-md-6">
<div className="card mb-3 border-marvel character-card">
<div className="card-body">
<img
src={`${character.thumbnail.path}.${character.thumbnail.extension}`}
className="figure-fluid float-left"
alt="Character thumbnail"
/>

<div className="character-card-details">
<h3 className="card-title text-truncate h5" title={character.name}>
{character.name}
</h3>
<div className="card-text text-center">
<button
type="button"
className="btn btn-sm btn-marvel w-50 rounded-0"
onClick={showDetails.bind(null, character)}
>
More Details...
</button>
<div className="character-card-details">
<h3 className="card-title text-truncate h5" title={character.name}>
{character.name}
</h3>
<div className="card-text text-center">
<button
type="button"
className="btn btn-sm btn-marvel w-50 rounded-0"
onClick={showDetails.bind(null, character)}
>
More Details...
</button>
</div>
</div>
</div>
</div>
</div>
</div>
)
)
}

export default CharacterCard
11 changes: 8 additions & 3 deletions src/components/CharacterModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useEffect } from 'react'
import { useEffect } from 'react'
import $ from 'jquery'
import './styles.scss'

Expand All @@ -7,7 +7,7 @@ interface CharacterModalProps {
character: any
}

const CharacterModal: FC<CharacterModalProps> = ({ character, hideDetails }) => {
function CharacterModal({ character, hideDetails }: CharacterModalProps) {
useEffect(() => {
$('#character-details').modal('show')
$(document.body).css({
Expand All @@ -23,7 +23,12 @@ const CharacterModal: FC<CharacterModalProps> = ({ character, hideDetails }) =>
}, [hideDetails])

return (
<div id="character-details" className="modal fade" tabIndex={1} role="dialog">
<div
id="character-details"
className="modal fade"
role="dialog"
tabIndex={1}
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header d-flex flex-column align-items-center">
Expand Down
26 changes: 16 additions & 10 deletions src/components/CharactersList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useState } from 'react'
import { useState } from 'react'
import CharacterCard from '../CharacterCard'
import CharacterModal from '../CharacterModal'
import Pagination from '../Pagination'
Expand All @@ -14,21 +14,27 @@ interface CharactersListProps {
}
}

const CharactersList: FC<CharactersListProps> = ({
goToPage, currentPage, characters, metadata: { total = 1, limit = 1 },
}) => {
function CharactersList({
goToPage,
characters,
currentPage,
metadata: {
total = 1,
limit = 1,
},
}: CharactersListProps) {
const [displayDetails, setDisplayDetails] = useState(null)

return (
<div className="pb-4">
<If condition={total > limit}>
{total > limit && (
<Pagination
goToPage={goToPage}
current={currentPage}
total={total}
limit={limit}
/>
</If>
)}

<div className="row">
{characters.map((character: any) => (
Expand All @@ -40,22 +46,22 @@ const CharactersList: FC<CharactersListProps> = ({
))}
</div>

<If condition={total > limit}>
{total > limit && (
<Pagination
goToPage={goToPage}
current={currentPage}
total={total}
limit={limit}
displayCounter
/>
</If>
)}

<If condition={!!displayDetails}>
{!displayDetails || (
<CharacterModal
character={displayDetails}
hideDetails={setDisplayDetails}
/>
</If>
)}
</div>
)
}
Expand Down
31 changes: 16 additions & 15 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { FC } from 'react'
import logo from '../../assets/images/logo-marvel.png'
import './styles.scss'

const Header: FC = () => (
<div className="container-fluid py-4 bg-marvel">
<div className="mx-auto w-25">
<figure className="figure w-100">
<img className="figure-img img-fluid" src={ logo } alt="Marvel Comics logo" />
</figure>
function Header() {
return (
<div className="container-fluid py-4 bg-marvel">
<div className="mx-auto w-25">
<figure className="figure w-100">
<img className="figure-img img-fluid" src={logo} alt="Marvel Comics logo" />
</figure>

<div className="h6 text-white px-1 d-flex justify-content-between" aria-hidden="true" style={{ zIndex: 1, marginTop: '-24px' }}>
{'CHARACTERS'.split('').map((letter, index) => <div key={index}>{letter}</div>)}
</div>
<div className="h6 text-white px-1 d-flex justify-content-between" aria-hidden="true" style={{ zIndex: 1, marginTop: '-24px' }}>
{'CHARACTERS'.split('').map((letter, index) => <div key={index}>{letter}</div>)}
</div>

<h1 className="sr-only">
Characters of the Marvel Comics Universe
</h1>
<h1 className="sr-only">
Characters of the Marvel Comics Universe
</h1>
</div>
</div>
</div>
)
)
}

export default Header
26 changes: 13 additions & 13 deletions src/components/Pagination/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useReducer } from 'react'
import { useReducer } from 'react'
import './styles.scss'

interface PaginationProps {
Expand All @@ -9,18 +9,18 @@ interface PaginationProps {
limit: number
}

const Pagination: FC<PaginationProps> = (props) => {
const last = Math.ceil(props.total / props.limit)

function Pagination({ goToPage, displayCounter, current, total, limit }: PaginationProps) {
const [, forceUpdate] = useReducer((x: number) => x + 1, 0)

const goToPrevious = () => {
props.goToPage(props.current - 1)
const last = Math.ceil(total / limit)

function goToPrevious() {
goToPage(current - 1)
forceUpdate()
}

const goToNext = () => {
props.goToPage(props.current + 1)
function goToNext() {
goToPage(current + 1)
forceUpdate()
}

Expand All @@ -30,18 +30,18 @@ const Pagination: FC<PaginationProps> = (props) => {
type="button"
className="btn btn-outline-marvel page-nav-btn"
onClick={goToPrevious}
style={{ visibility: (props.current === 1) ? 'hidden' : 'visible' }}
style={{ visibility: (current === 1) ? 'hidden' : 'visible' }}
>Previous</button>

<If condition={!!props.displayCounter}>
<span>Page {props.current} of {last}</span>
</If>
{!displayCounter || (
<span>Page {current} of {last}</span>
)}

<button
type="button"
className="btn btn-outline-marvel page-nav-btn"
onClick={goToNext}
style={{ visibility: (props.current === last) ? 'hidden' : 'visible' }}
style={{ visibility: (current === last) ? 'hidden' : 'visible' }}
>Next</button>
</div>
)
Expand Down
8 changes: 4 additions & 4 deletions src/components/SearchBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { FC, FormEvent, useState } from 'react'
import { FormEvent, useState } from 'react'
import './styles.scss'

interface SearchBoxProps {
submitSearch: (search: string) => any
}

const SearchBox: FC<SearchBoxProps> = (props) => {
function SearchBox({ submitSearch }: SearchBoxProps) {
const [search, setSearch] = useState('')

const handleSubmit = (ev: FormEvent) => {
function handleSubmit(ev: FormEvent) {
ev.preventDefault()
props.submitSearch(search)
submitSearch(search)
}

return (
Expand Down
6 changes: 3 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react'
import { StrictMode } from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
import 'jquery'
import 'bootstrap'
import './assets/styles/global.scss'

ReactDOM.render(
<React.StrictMode>
<StrictMode>
<App />
</React.StrictMode>,
</StrictMode>,
document.getElementById('root'),
)

1 comment on commit 7b2a19a

@vercel
Copy link

@vercel vercel bot commented on 7b2a19a May 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.