Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16,822 changes: 16,822 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

90 changes: 86 additions & 4 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,89 @@
import logo from './logo.svg';
import React, { useEffect, useState } from 'react'
import logo from '../images/logo.svg';
import Card from './card'
import Model from './detailModel'
import { getData, searchData } from '../fetchSrevices'

const App = () => (
<img src={logo} alt="Timescale" />
)
function App() {
const [page, setPage] = useState(1)
const [data, setData] = useState([])
const [model, setModel] = useState(false)
const [detail, setDetail] = useState({})

const handleModel = (item) => {
setDetail(item)
openOrClose()
}
const openOrClose = () => {
setModel(!model)
}
const onSearch = async (e) => {
let name = e.target.value
if (name) {
const data = await searchData(name)
setData(data)
}
else api()
}

const api = async (pageNo) => {
const data = await getData(pageNo)
setData(data)
}
const handleOnClick = (value) => {
let pageNo = page
if (value === 'next') {
setPage(pageNo + 1)
pageNo = pageNo + 1
}
else if (value === 'pre') {
if (pageNo > 1) {
setPage(pageNo - 1)
pageNo = pageNo - 1
}
}
else {
pageNo = page
}
api(pageNo)
}

useEffect(() => {
api()
}, [])
return (
<>
<div className={`${model ? "blur" : ""}`}>
<div className="header">
<div className="container header-inner">
<img src={logo} alt="Timescale" />
<div style={{ display: 'flex', alignItems: 'center' }}><input className="input" type="text" name="search" placeholder="Search.." onChange={(e) => onSearch(e)} /></div>
</div>
</div>
{data.length > 0 ? (
<div className="center">
<div className="container">
<div className="gridlayout">
{data.map((item, index) => {
return (
<Card key={index} data={item} onClick={() => handleModel(item)} />
)
})}
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', paddingLeft: '50px', paddingRight: '50px', paddingBottom: '25px' }}>
<div><button className="button" onClick={() => handleOnClick('pre')}>Pre.</button></div>
<div><button className="button" onClick={() => handleOnClick('next')}>Next</button></div>
</div>
</div>
</div>
) :
(<div className="noData"><p>No Record Found</p></div>)
}
</div>
{model && <div className="alignModel"><Model data={detail} onClick={() => openOrClose()} /></div>}

</>

)
}
export default App;
16 changes: 16 additions & 0 deletions src/components/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'

function Card(props) {
const imageBaseUrl = `https://image.tmdb.org/t/p/original/${props.data.poster_path}`
return (
<div className="card" onClick={() => props.onClick()}>
<div className="position"><p className="radius">{props.data.vote_average}</p></div>
<img className="img" src={imageBaseUrl} alt="poster" />
<div style={{textAlign: 'center'}}>
<p>{props.data.title}</p>
</div>
</div>
)

}
export default Card
22 changes: 22 additions & 0 deletions src/components/detailModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

function Model (props) {
const imageBaseUrl = `https://image.tmdb.org/t/p/original/${props.data.poster_path}`
return(
<div className="model">
<div style={{display:'flex', justifyContent:'space-between'}}>
<div style={{marginLeft:'20px'}}><p style={{fontWeight:'bold'}}>{props.data.title}</p></div>
<div><button onClick={()=> props.onClick()}>x</button></div>
</div>
<div className="flex">
<div className="w"><img className='img' src={imageBaseUrl} /></div>
<div className="w">
<p className="p"><span style={{fontWeight:'bold',paddingRight:'10px'}}>Release date:</span>{props.data.release_date}</p>
<p className="">{props.data.overview}</p>
<p className=""><span style={{fontWeight:'bold'}}>{props.data.vote_average}</span>/10 ( {props.data.vote_count} total votes)</p>
</div>
</div>
</div>
)
}
export default Model
27 changes: 27 additions & 0 deletions src/fetchSrevices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Axios from 'axios'
const BaseUrl = process.env.REACT_APP_MOVIE_BASE_URL
const SearchUrl = process.env.REACT_APP_MOVIE_SEARCH_URL
const ApiKey = process.env.REACT_APP_MOVIE_DB_API_KEY;

const getData = async (pageNo) => {
try {
const response = await Axios.get(`${BaseUrl}?api_key=${ApiKey}&page=${pageNo}`);
var result = response.data.results;
return result;
} catch (e) {
return false;
}
};

const searchData = async (name) => {
try {
const response = await Axios.get(`${SearchUrl}?api_key=${ApiKey}&query=${name}`);
var result = response.data.results;
return result;
} catch (e) {
return false;
}
};


export {getData,searchData}
Binary file added src/images/searchicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import './scss/application.scss'

ReactDOM.render(
<React.StrictMode>
Expand Down
148 changes: 148 additions & 0 deletions src/scss/application.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
@import url("https://pro.fontawesome.com/releases/v5.10.0/css/all.css");

body {
margin: 0;

}
.header {
padding: 10px 15px;
box-shadow: 0px 0px 5px #d4d4d4;
display: flex;
justify-content: space-between;
position: fixed;
width: 100%;
z-index: 9;
background: #fff;
}
.card {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
border-radius: 5px;
margin-bottom: 20px;
max-width: 260px;
margin: 20px auto;
}

.card:hover {
box-shadow: 0 25px 40px 0 rgba(0,0,0,0.2);
}

.img {
width: 100%;
max-height: 250px;

}

.container {
max-width: 80%;
margin: 0 auto;
width: 100%;
}
.header-inner {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
margin: 0 auto;
padding: 15px;
}
.gridlayout {
display: grid;
grid-template-columns: repeat(4, 1fr);
margin-top: 30px;
grid-column-gap: 25px;

@media(max-width:990px) {
grid-template-columns: repeat(2, 1fr);
}
@media(max-width:480px) {
grid-template-columns: repeat(2, 1fr);
}
}

.button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}

.input {
width: 130px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
font-size: 16px;
background-color: white;
background-image: url('../images/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
padding: 12px 20px 12px 40px;
-webkit-transition: width 0.4s ease-in-out;
transition: width 0.4s ease-in-out;
}

.model {
width: 50%;
margin: 20px;
border: 1px gray solid;
background-color: white;
padding:10px
}
.p {
padding: 0;
margin: 0;
}
.blur {
filter: blur(4px);
}
.alignModel {
position: fixed;
width: 100%;
height: 50%;
left: 325px;
top: 250px;
@media (max-width:480px) {
left: 65px;
top: 50px;
}
}
.center {
padding-top: 70px;
}
.w {
width: 45%;
@media(max-width:480px) {
width: 100%;
}
}
.flex {
display: flex;
justify-content: space-between;
@media(max-width:480px) {
display: block;
justify-content: center;
}
}
.radius {
border-radius: 72px;
background-color: white;
border: 1px solid;
padding: 2px;
}
.position {
position: absolute;
padding-left: 10px;
}
.noData {
display: flex;
justify-content: center;
padding-top: 150px;
font-weight: bold;
font-size: x-large;
color: red;
}