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.photos.map((photo, index) => {
- // loading images from data
- return (
-
- );
- })}
-
-
- );
- }
+ const pagination =
+
+ 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)}
- >
-
-

-
-
-
-
-
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)}
+ >
+
+

+
+
+
+
+
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;
}