diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..9092b06 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,7 @@ +version: 2.1 +orbs: + heroku: circleci/heroku@0.0.10 +workflows: + heroku_deploy: + jobs: + - heroku/deploy-via-git \ No newline at end of file diff --git a/package.json b/package.json index 24e7e1d..ed08e4a 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "test": "react-scripts test", "eject": "react-scripts eject" }, + "heroku-run-build-script": true, "eslintConfig": { "extends": "react-app" }, diff --git a/src/components/gallery.jsx b/src/components/gallery.jsx index c385d96..4936325 100644 --- a/src/components/gallery.jsx +++ b/src/components/gallery.jsx @@ -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

{data.error}

; - } - return ( -
-
-

Gallery

-
-
-
- {data && ( - - )} -
-
- -
- {data && - data.photos.map((photo, index) => { - // loading images from data - return ( - - ); - })} -
-
- ); - } + const pagination =
+
+ {data && ( + + )} +
+
+ + if (data && typeof data.error !== "undefined") { + return

{data.error}

; + } + return ( +
+
+

Gallery

+
+ { pagination } + +
+ {data && + data.photos.map((photo, index) => { + // loading images from data + return ( + + ); + })} +
+ { pagination } + +
+ ); + } } export default Gallery; diff --git a/src/components/imageComponent.jsx b/src/components/imageComponent.jsx index b25cf00..0674401 100644 --- a/src/components/imageComponent.jsx +++ b/src/components/imageComponent.jsx @@ -1,24 +1,27 @@ import React, { Component } from "react"; class ImageComponet extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
this.props.onPhotoClick(this.props.photo, e)} - className="image-item" - > - -
- ); - } + 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 ( +
this.props.onPhotoClick(this.props.photo, e)} + className={`image-item ${nsfwClass} ${orientation}`} + > + +
+ ); + } } export default ImageComponet; diff --git a/src/components/lightBox.jsx b/src/components/lightBox.jsx index d9c6496..1dfa18b 100644 --- a/src/components/lightBox.jsx +++ b/src/components/lightBox.jsx @@ -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 ( -
this.props.onPhotoClick(false)} - > -
- -
-
-
-
Name:
-
{photo.name}
-
-
-
Author:
-
{photo.user.fullname}
-
-
-
Rating
-
{photo.rating}
-
-
-
Description:
-
{photo.description}
-
-
-
- ); - } - 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 ( +
this.props.onPhotoClick(false)} + > +
+ +
+
+
+
Name:
+
{photo.name}
+
+
+
Author:
+
{photo.user.fullname}
+
+
+
Rating
+
{photo.rating}
+
+
+
Description:
+
{photo.description}
+
+
+
+ ); + } + return null; + } } export default LightBox; diff --git a/src/components/pagination.jsx b/src/components/pagination.jsx index 7c248aa..26750e9 100644 --- a/src/components/pagination.jsx +++ b/src/components/pagination.jsx @@ -1,105 +1,103 @@ import React, { Component } from "react"; class Pagination extends Component { - constructor(props) { - super(props); - this.state = {}; - } + constructor(props) { + super(props); + this.state = {}; + } - /** - * create custom page range - * @param {Number} from - * @param {Number} to - * - * @returns {Array} rangeList - */ - pageRange(from, to) { - if (from <= 0) { - from = 1; - } - let rangeList = []; + /** + * create custom page range + * @param {Number} from + * @param {Number} to + * + * @returns {Array} rangeList + */ + pageRange(from, to) { + if (from <= 0) { + from = 1; + } + let rangeList = []; - while (from <= to) { - rangeList.push(from); - from++; - } + while (from <= to) { + rangeList.push(from); + from++; + } - return rangeList; - } + return rangeList; + } - /** - * Fetching page numbers to array and return - * @param {number} currentPage - * @param {number} totalItems - * @param {number} pageLimit - * - * @returns {Array} pages - */ - fetchPages(currentPage, totalItems, pageLimit = 20) { - let numOfPageItems = 10; - let pages = []; - let totalPages = Math.ceil(totalItems / pageLimit); + /** + * Fetching page numbers to array and return + * @param {number} currentPage + * @param {number} totalItems + * @param {number} pageLimit + * + * @returns {Array} pages + */ + fetchPages(currentPage, totalItems, pageLimit = 20) { + let numOfPageItems = 10; + let pages = []; + let totalPages = Math.ceil(totalItems / pageLimit); - // Set previous page when current page is not 1st page - if (currentPage > 1) { - pages = ["Previous"]; - } + // Set previous page when current page is not 1st page + if (currentPage > 1) { + pages = ["Previous"]; + } - // Print the page number for 1st 10 pages untill current page reaches in the middle - if (currentPage <= numOfPageItems - 4 && (numOfPageItems => totalPages)) { - let end = totalPages > numOfPageItems ? numOfPageItems : totalPages; - pages = [...pages, ...this.pageRange(1, end)]; - } + // Print the page number for 1st 10 pages untill current page reaches in the middle + if (currentPage <= numOfPageItems - 4 && (numOfPageItems => totalPages)) { + let end = totalPages > numOfPageItems ? numOfPageItems : totalPages; + pages = [...pages, ...this.pageRange(1, end)]; + } - // print the pages numbers and keep the active page in the middle - if (currentPage > numOfPageItems - 4) { - let start = currentPage - 4; - let end = currentPage + 5; - if (totalPages - numOfPageItems < currentPage) { - start = totalPages - numOfPageItems; - end = totalPages; - } + // print the pages numbers and keep the active page in the middle + if (currentPage > numOfPageItems - 4) { + let start = currentPage - 4; + let end = currentPage + 5; + if (totalPages - numOfPageItems < currentPage) { + start = totalPages - numOfPageItems; + end = totalPages; + } - pages = [...pages, ...this.pageRange(start, end)]; - } + pages = [...pages, ...this.pageRange(start, end)]; + } - // Print the next button for pages other than last active page - if (currentPage < totalPages) { - pages = [...pages, "Next"]; - } + // Print the next button for pages other than last active page + if (currentPage < totalPages) { + pages = [...pages, "Next"]; + } - return pages; - } + return pages; + } - render() { - // destructuring props - const { currentPage, totalItems } = this.props; - const pages = this.fetchPages(currentPage, totalItems); + render() { + // destructuring props + const { currentPage, totalItems } = this.props; + const pages = this.fetchPages(currentPage, totalItems); - return ( - - - - ); - } + return ( + + + + ); + } } export default Pagination; diff --git a/src/index.css b/src/index.css index 444faa3..20d5c38 100755 --- a/src/index.css +++ b/src/index.css @@ -1,47 +1,105 @@ body { - margin: 0; - padding: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; } .image-item { - margin: 1px; + margin: 1px; + position: relative; +} + +.image-item.nsfw::before { + content: ''; + position: absolute; + height: 100%; + width: 100%; + background-color: rgba(136, 136, 136, 0.918);; +} + +.image-item.nsfw::after { + content: 'Click Here to see'; + position: absolute; + height: 100%; + width: 100%; + color: black; + left: 0; + top: 0; + display: flex; + justify-content: center; + text-align: center; + align-items: center; + font-weight: bolder; + text-transform: uppercase; +} +/* +.image-container { + flex-flow: row; + align-items: flex-start; +} +.image-item { + max-height: 100px; +} +.image-item.portrait { + height: 200px; + width: 100px; +} +.image-item.landscape { + height: 100px; + width: 200px; +} */ + +section{ + display: flex; + flex-wrap: wrap; +} +.image-item{ + flex-grow: 1; + margin: 2px; + height: 200px; +} +.image-item img{ + height: 200px; + object-fit: cover; + max-width: 100%; + min-width: 100%; + vertical-align: bottom; } .lightbox { - background-color: white; - padding: 10px; - z-index: 9999; - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - overflow-y: auto; + background-color: white; + padding: 10px; + z-index: 9999; + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + overflow-y: auto; } .lightbox .item { - margin-bottom: 10px; + margin-bottom: 10px; } .item .title { - font-size: 17px; - font-weight: bold; + font-size: 17px; + font-weight: bold; } .page-item.active.disabled .page-link { - background-color: lightgray; + background-color: lightgray; } .page-item .page-link { - cursor: pointer; + cursor: pointer; }