{"id":21307268,"url":"https://github.com/jdegand/my-unsplash-frontend","last_synced_at":"2026-05-20T15:13:25.498Z","repository":{"id":110668719,"uuid":"520588787","full_name":"jdegand/my-unsplash-frontend","owner":"jdegand","description":"Devchallenges - Legacy - Full-Stack Developer - My Unsplash","archived":false,"fork":false,"pushed_at":"2024-10-06T03:31:15.000Z","size":2216,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T09:12:25.454Z","etag":null,"topics":["axios","devchallenges","devchallenges-legacy","react"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jdegand.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-02T17:24:19.000Z","updated_at":"2024-10-06T03:31:18.000Z","dependencies_parsed_at":"2024-09-08T04:20:24.362Z","dependency_job_id":"65001530-9911-4764-8cf9-67a24b465792","html_url":"https://github.com/jdegand/my-unsplash-frontend","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdegand%2Fmy-unsplash-frontend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdegand%2Fmy-unsplash-frontend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdegand%2Fmy-unsplash-frontend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdegand%2Fmy-unsplash-frontend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jdegand","download_url":"https://codeload.github.com/jdegand/my-unsplash-frontend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243784103,"owners_count":20347409,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axios","devchallenges","devchallenges-legacy","react"],"created_at":"2024-11-21T16:30:54.920Z","updated_at":"2026-05-20T15:13:25.440Z","avatar_url":"https://github.com/jdegand.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eMy Unsplash Frontend\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n   Solution for a challenge from  \u003ca href=\"https://web.archive.org/web/20231130035602/https://legacy.devchallenges.io/challenges/rYyhwJAxMfES5jNQ9YsP\" target=\"_blank\"\u003eDevchallenges.io\u003c/a\u003e.\n\u003c/div\u003e\n\n## Table of Contents\n\n- [Overview](#overview)\n  - [Built With](#built-with)\n- [Features](#features)\n- [How to use](#how-to-use)\n- [Thoughts](#thoughts)\n- [Useful Resources](#useful-resources)\n\n## Overview\n\n![](my-unsplash-register.png)\n\n![](my-unsplash-login.png)\n\n![](my-unsplash-mobile-1.png \"mobile\")\n\n![](my-unsplash-mobile-2.png)\n\n![](my-unsplash-tablet.png \"tablet\")\n\n![](my-unsplash-tablet-2.png)\n\n![](my-unsplash-1024px.png \"very large tablet\")\n\n![](my-unsplash-desktop.png \"desktop\")\n\n![](my-unsplash-add-picture-modal.png)\n\n![](my-unsplash-picture-modal-values-added.png)\n\n![](my-unsplash-desktop-pictures-added.png)\n\n![](my-unsplash-desktop-hover.png)\n\n![](my-unsplash-image-filter.png \"filtered images\")\n\n![](my-unsplash-desktop-different-layout.png)\n\n![](my-unsplash-4k.png \"very large desktop\")\n\n### Built With\n\n- [React](https://reactjs.org)\n- [Axios](https://axios-http.com)\n\n## Features\n\nThis application/site was created as a submission to a [DevChallenges](https://devchallenges.io/challenges) challenge. The [challenge](https://web.archive.org/web/20231130035602/https://legacy.devchallenges.io/challenges/rYyhwJAxMfES5jNQ9YsP) was to build an application to complete the given user stories. **Note**: The previous design document may be incomplete, as you need to find an archived version of the challenge as all `legacy` challenges have had their documentation removed from DevChallenges.\n\n## How To Use\n\nTo clone and run this application, you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:\n\n```bash\n# Clone this repository \u0026 the backend repo (need to add env variables to backend)\n$ git clone https://github.com/jdegand/my-unsplash-backend.git\n$ git clone https://github.com/jdegand/my-unsplash-frontend.git\n\n# Install dependencies in both repos\n$ npm install\n\n# Run the both apps (in frontend - enable cookies)\n$ npm start\n```\n\n## Thoughts\n\n- JWT Cookie needs to use 'secure:true' or chrome will block the cookie.\n- Windbnb, Cat Wiki, Mongo Async Crud, React Register Tut used to create this.  \n- Images are not capped by height.  So they can be larger and smaller.  Used columns to approximate the masonry look.  \n- Using grid - grid-auto-flow: dense - really doesn't help create a masonry like look.  Experimental 'masonry auto flow' has no support and may not be adopted at all.  \n- Using columns seems to be a good way of achieving a similar look without using external libraries.  \n- Testing is difficult using random images because they will change after a few minutes of time.  I could use cloudinary and add different sized pictures and then have a url to get the images.  \n- On hover, the delete button is positioned right 10% so if picture is not wide enough the button may not overlap the image.      \n- Used a url regex to valid the input - this could probably be improved or looked into more.  \n- The search filter has an useless submit function - I could remove the button and just add the magnify svg as a background image.  \n- I prefer the search filter to automatically filter results versus waiting to the submit button to be clicked.\n- Could have added the authentication header to axiosPrivate instance\n- Used a chained ternary in the Images component render \n- Could have used a state object for the username and password and one onChange handler vs separate state and onChange handlers\n- Added all styles to index.css versus multiple style sheets for various components.\n- Add a package to disable react dev tools - to prevent accessToken tampering.\n- Used `response.data['accessToken']` - response.data.accessToken didn't work  \n- Used state to prevent a ton of requests to the backend - adding images to the first useEffect in Images - caused a ton of requests to the backend - probably could refactor that useEffect and maybe not even need my workaround. \n- Need to look more into Axios. Axios has advanced features that I have not used frequently.  \n- Removed JWT-decode - not really necessary \n- All pictures are linked to a user \n- Could create a page where all user pictures are displayed and you can only delete when logged in etc\n- Adding authentication made sense over using a password delete system - which I have done similarly in [odin-project-members-only](https://github.com/jdegand/odin-project-members-only)\n- Lazy loading - problem might be not knowing the dimensions of random image\n\n## Useful Resources\n\n- [Medium](https://levelup.gitconnected.com/react-template-for-jwt-authentication-with-private-routes-and-redirects-f77c488bfb85) - jwt authentication and private routes / redirects\n- [Awik](https://awik.io/generate-random-images-unsplash-without-using-api/) - generate random images from unsplash without api key\n- [Stack Overflow](https://stackoverflow.com/questions/10123953/how-to-sort-an-object-array-by-date-property) - sort an object array by date\n- [Stack Overflow](https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url) - regex to match a url\n- [Medium](https://javascript.plainenglish.io/build-a-pinterest-layout-in-reactjs-458b815126d8) - pinterest layout in react\n- [Blog](https://tutorial101.blogspot.com/2021/10/reactjs-image-gallery-react-masonry.html) - react image gallery react masonry\n- [Medium](https://medium.com/suyeonme/react-how-to-prevent-unnecessary-api-calls-649b6a6ab84d) - prevent unnecessary api calls\n- [Stack Overflow](https://stackoverflow.com/questions/55439651/react-hooks-props-in-useeffect) - props \u0026 useEffect\n- [Stack Overflow](https://stackoverflow.com/questions/52184975/how-to-prevent-cascading-filters-or-undo-cascaded-filter) - prevent filter cascade\n- [Mastering JS](https://masteringjs.io/tutorials/axios/delete) - axios delete\n- [Stack Overflow](https://stackoverflow.com/questions/51069552/axios-delete-request-with-body-and-headers) - axios delete request \n- [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/masonry-auto-flow#browser_compatibility) - masonry auto flow\n- [FreeCodeCamp](https://www.freecodecamp.org/news/build-an-image-gallery-with-nextjs/#how-to-fetch-data-from-the-pexels-api) - image gallery with pexels api\n- [YouTube](https://www.youtube.com/watch?v=-isQPqqnIBo) - CSS Masonry Layout with columns\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdegand%2Fmy-unsplash-frontend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjdegand%2Fmy-unsplash-frontend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdegand%2Fmy-unsplash-frontend/lists"}