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
7 changes: 7 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2.1
orbs:
heroku: circleci/heroku@0.0.10
workflows:
heroku_deploy:
jobs:
- heroku/deploy-via-git
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"heroku-run-build-script": true,
"eslintConfig": {
"extends": "react-app"
},
Expand Down
189 changes: 99 additions & 90 deletions src/components/gallery.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,103 +8,112 @@ import Pagination from "./pagination"; // Importing simple pagination component
* Control entire gallery component
*/
class Gallery extends Component {
constructor(props) {
super(props);
this.state = { data: null, photo: null }; // initializing data and photo with null
}
constructor(props) {
super(props);
this.state = { data: null, photo: null }; // initializing data and photo with null
}

/**
* Getting images from API and setting state data
* @param {number} pageNumber
*/
getImages(pageNumber = 1) {
let search = window.location.search;
let params = new URLSearchParams(search);
let consumer_key = params.get("consumer_key");
console.log(consumer_key);
let apiUrl = `https://api.500px.com/v1/photos?feature=popular&image_size=20,2048&page=${pageNumber}&consumer_key=${consumer_key}`;
fetch(apiUrl)
.then(response => response.json())
.then(data => {
this.setState({ data: data });
})
.catch(err => console.error(this.props.url, err.toString()));
}
/**
* Getting images from API and setting state data
* @param {number} pageNumber
*/
getImages(pageNumber = 1) {
let search = window.location.search;
let params = new URLSearchParams(search);
let consumer_key = params.get("consumer_key");
console.log(consumer_key);
// let apiUrl = `https://api.500px.com/v1/photos?feature=upcoming&image_size[]=20&image_size[]=2048&page=${pageNumber}&consumer_key=${consumer_key}`;
let apiUrl = `https://api.500px.com/v1/photos?feature=popular&image_size[]=20&image_size[]=2048&page=${pageNumber}&consumer_key=${consumer_key}`;
fetch(apiUrl)
.then(response => response.json())
.then(data => {
this.setState({ data: data });
})
.catch(err => console.error(this.props.url, err.toString()));
}

componentDidMount() {
// Initialize data from API after the component mount
this.getImages();
}
componentDidMount() {
// Initialize data from API after the component mount
this.getImages();
}

/**
* Handle photo click and set photo state
* responsible to track photo click
*/
handlePhotoChange = photo => {
this.setState({ photo });
};
/**
* Handle photo click and set photo state
* responsible to track photo click
*/
handlePhotoChange = ( photo, event ) => {
if ( event && event.target && event.target.classList.contains( 'nsfw' ) ) {
event.target.classList.remove( 'nsfw' );
} else {
this.setState({ photo });
}
};

/**
* Handle page changes from pagination components and
* load the images from API according to the page numbers
*/
handlePageChange = (pageNumber, currentPage = null) => {
// Setting pageNumber for Next Button click
if (currentPage && pageNumber === "Next") {
pageNumber = currentPage + 1;
}
// Setting pageNumber for Previous Button click
if (currentPage && pageNumber === "Previous") {
pageNumber = currentPage - 1;
}
/**
* Handle page changes from pagination components and
* load the images from API according to the page numbers
*/
handlePageChange = (pageNumber, currentPage = null) => {
// Setting pageNumber for Next Button click
if (currentPage && pageNumber === "Next") {
pageNumber = currentPage + 1;
}
// Setting pageNumber for Previous Button click
if (currentPage && pageNumber === "Previous") {
pageNumber = currentPage - 1;
}

this.getImages(pageNumber);
};
this.getImages(pageNumber);
};

render() {
// object destructuring data
const { data } = this.state;
render() {
// object destructuring data
const { data } = this.state;

if (data && typeof data.error !== "undefined") {
return <p>{data.error}</p>;
}
return (
<div className="container">
<div className="row">
<h1>Gallery</h1>
</div>
<div className="row m1">
<div align="center">
{data && (
<Pagination
currentPage={data.current_page}
totalPages={data.total_pages}
totalItems={data.total_items}
onPageChange={this.handlePageChange}
/>
)}
</div>
</div>
<LightBox
onPhotoClick={this.handlePhotoChange}
photo={this.state.photo}
/>
<div className="row">
{data &&
data.photos.map((photo, index) => {
// loading images from data
return (
<ImageComponent
key={index}
photo={photo}
onPhotoClick={this.handlePhotoChange}
/>
);
})}
</div>
</div>
);
}
const pagination = <div className="row m1">
<div align="center">
{data && (
<Pagination
currentPage={data.current_page}
totalPages={data.total_pages}
totalItems={data.total_items}
onPageChange={this.handlePageChange}
/>
)}
</div>
</div>

if (data && typeof data.error !== "undefined") {
return <p>{data.error}</p>;
}
return (
<div className="container">
<div className="row">
<h1>Gallery</h1>
</div>
{ pagination }
<LightBox
onPhotoClick={this.handlePhotoChange}
photo={this.state.photo}
/>
<div className="image-container row">
{data &&
data.photos.map((photo, index) => {
// loading images from data
return (
<ImageComponent
key={index}
photo={photo}
onPhotoClick={this.handlePhotoChange}
/>
);
})}
</div>
{ pagination }

</div>
);
}
}

export default Gallery;
39 changes: 21 additions & 18 deletions src/components/imageComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import React, { Component } from "react";

class ImageComponet extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div
onClick={e => this.props.onPhotoClick(this.props.photo, e)}
className="image-item"
>
<img
src={this.props.photo.images[0].url}
className="img-responsive"
alt=""
/>
</div>
);
}
constructor(props) {
super(props);
this.state = {};
}
render() {
const nsfw = this.props.photo.nsfw;
const nsfwClass = nsfw ? 'nsfw' : '';
const orientation = this.props.photo.width > this.props.photo.height ? 'landscape' : 'portrait';
return (
<div
onClick={e => this.props.onPhotoClick(this.props.photo, e)}
className={`image-item ${nsfwClass} ${orientation}`}
>
<img
src={this.props.photo.images[0].url}
className="img-responsive"
alt=""
/>
</div>
);
}
}

export default ImageComponet;
84 changes: 45 additions & 39 deletions src/components/lightBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,52 @@ import React, { Component } from "react";
* Simple LightBox class for individual image display
*/
class LightBox extends Component {
constructor(props) {
super(props);
this.state = {};
}
constructor(props) {
super(props);
this.state = {};
}

render() {
const photo = this.props.photo;
if (this.props.photo) {
return (
<div
className="row lightbox"
// setting false as a param for onPhotoClick method to hide photo in light box
onClick={() => this.props.onPhotoClick(false)}
>
<div className="col-md-9 col-sm-12">
<img alt="" width="100%" src={this.props.photo.images[1].url} />
</div>
<div className="col-md-3 col-cm-12">
<div className="item">
<div className="title">Name:</div>
<div className="detail">{photo.name}</div>
</div>
<div className="item">
<div className="title">Author:</div>
<div className="detail">{photo.user.fullname}</div>
</div>
<div className="item">
<div className="title">Rating</div>
<div className="detail">{photo.rating}</div>
</div>
<div className="item">
<div className="title">Description:</div>
<div className="detail">{photo.description}</div>
</div>
</div>
</div>
);
}
return null;
}
componentDidMount() {

}

render() {
const photo = this.props.photo;
if (this.props.photo && photo.images.length > 0) {
console.log({photo});
let photoSrc = photo.images.length > 1 ? this.props.photo.images[1].url : this.props.photo.images[0].url;
return (
<div
className="row lightbox"
// setting false as a param for onPhotoClick method to hide photo in light box
onClick={() => this.props.onPhotoClick(false)}
>
<div className="col-md-9 col-sm-12">
<img alt="" style={{maxWidth: "100%"}} src={photoSrc} />
</div>
<div className="col-md-3 col-cm-12">
<div className="item">
<div className="title">Name:</div>
<div className="detail">{photo.name}</div>
</div>
<div className="item">
<div className="title">Author:</div>
<div className="detail">{photo.user.fullname}</div>
</div>
<div className="item">
<div className="title">Rating</div>
<div className="detail">{photo.rating}</div>
</div>
<div className="item">
<div className="title">Description:</div>
<div className="detail">{photo.description}</div>
</div>
</div>
</div>
);
}
return null;
}
}

export default LightBox;
Loading