Solution for a challenge from DevChallenges.io.
This application/site was created as a submission to a DevChallenges challenge. The challenge 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.
To clone and run this application, you'll need Git and Node.js (which comes with npm) installed on your computer. From your command line:
# Clone this repository & the companion backend repo
$ git clone https://github.com/jdegand/shoppingify-backend.git
$ git clone https://github.com/jdegand/shoppingify-frontend.git
# Install dependencies in both repos
$ npm install
# Add env variables && run both apps (match PORT number with BASE_URL in axios.js) (in browser - enable cookies)
$ npm start
- Added basic testing with Cypress
- Used a
cypress.env.json
forenv
variables in the Cypress tests. - Need to change username for register test each time - could possibly use nanoid for random value for name but can't reuse that user for login tests easily - have to look up in mongo atlas
- Can install eslint plugin to prevent errors in terminal when looking at the cypress e2e test files
- Home component holds state - pass as props to other components
- Project may have benefited from global state management but I do not think it is necessary
- No categories selection panel
- Build this desktop first - is design really mobile friendly? - mobile styling based on 375px width - did not look at all possible screen sizes - Tweaks are required for most sizes since I used grids with set pixel values vs percentages
- Overflow containers could be annoying on mobile
- Put the item panel after the other 2 sections - easiest mobile solution
- Mobile - ItemDetail comes after the cart - not great at all - scroll to its location?
- Added a scrolling hook but not perfect - doesn't reach top of screen or bottom of screen on first click - issue in hook?
- Problems when resizing as well
- The cart was not designed to be opened and closed and it may require a significant rework if you were to go that route
- I think that would help a lot for mobile - as you could replace the items section with itemDetail or itemPanel components
- Tons of data manipulation done versus more network requests - performance optimizations definitely possible here - useMemo etc
- Stats page - use all lists from all users or per user - I originally had it for all list items and switched to per-user
- Top Categories - categories in lists versus total categories used in all lists
- Top Items - overall percentage of items purchased across all lists (items / total items)
- Had to repeat overflow containers often.
- Had multiple 'missing key' warnings - should be mostly solved - I used nanoid - using map inside of another map, need to give keys to both wrapping divs?
- Could have put navbar and listpanel inside of layout component
- Change navbar tabs to nav-links and add styling for active link
- I went with tab system not tied to react router - using react router preferrable - better for bookmarking & accessbility
- Changing to nav-links requires changing the :/id api routes - using query params vs search params - need to duplicate backend route - one for each approach or could try to use ' req.params.id || req.query.id' logic in route
- The state of the list feature is half-baked - should list be available to update & where ? - in the shopping history detail view ?
- If all items are purchased (crossed-out), the list is complete - otherwise it is active. Saving a cancelled list makes no sense.
- Nor should saving a list require multiple prompts as design implies - creating friction in the process -> lose users who get tired of the process
- Add toggling of purchased items in the shopping history detail component - the purchased property is present and can be accessed inside of it - I cross out items on list that are purchased - send api request back to update the list and grab list id from url
- Didn't use gray for input labels - harder to see for no real benefit
- Various styling differences - disabled input border, bottle
- Tooltip reminded me -> if something needs to used multiple times -> make a component for it -> this can sometimes slip your mind and you find yourself using multiple state values and multiple handlers
- The ItemDetail Component had a lot of functionality that I kept removing as development progressed - its click handler had to be moved to the Link component otherwise keyboard functionality would have been broken
- Added keyboard functionality for the plus button and item panel - should be able to add items to list and save it all with keyboard - checkbox works with spacebar but not with enter key
- Handle case when no shopping history and no stats to display - right now shows empty chart on stats page
- problem with list names being unique - can't have different users have same list name ? Problem with having list being a separate model ?
- need to wrap nav in a header tag?
- Styling issues. "Completed" will overflow with present grid in the shopping list history component.
- Refactor some component logic.
- Folder structure improvements
- Look into Cypress test improvements.
- Migrate from Create React App or just update dependencies.
- Stack Overflow - testing useContext
- Code Sandbox - Vertical React Tabs
- Stack Overflow - div direct child of ul
- React Router Docs - nav link
- Medium - 100vh overflows
- React Docs - you might not need an effect
- Codepen - subtle box shadow
- Dev.to - nested ternary statements in react
- Codepen - react tabs
- React Docs - updating objects in state
- Stack Overflow - react router id & links
- React Router Docs - link
- Ultimate Courses - search params react router 6
- Mongoose Docs - mongoose defaults
- Stack Overflow - add an object with setState to array of objects
- Stack Overflow - prevent duplicate objects in state
- AppsLoveWorld - avoid pushing duplicate objects
- Stack Overflow - override overflow hidden
- Stack Overflow - make scrollbar always visible
- FreeCodeCamp - multiple checkboxes in react
- Stack Overflow - checkbox & react
- Pluralsight - handling multiple inputs with single onchange handler
- Stack Overflow - nested object arrays
- MDN Docs - array flat
- Stack Overflow - find in nested array
- YouTube - find unique objects in array
- Stack Overflow - update state in nested array
- LearnBestCoding - update nested state objects
- Stack Overflow - how can update state with index
- Stack Overflow - call multiple function onclick react
- Stack Overflow - react checkbox not updating
- Stack Overflow - multiple props in a single event handler
- Bobby Hadz - useNavigate
- Bobby Hadz - remove query params
- Stack Overflow - keyup enter key
- Stack Overflow - group the same category objects
- Stack Overflow - groupby on an array of objects
- Stack Overflow - setState callback with react hooks
- Stack Overflow - updated variable is not rendered
- Stack Overflow - display values from a map object in react
- ReactTraining - react state
- FreeCodeCamp - iterate nested object in react
- Stack Overflow - map object & react
- Stack Overflow - map through an object in react
- Bobby Hadz - react map nested array
- Stack Overflow - react setting state to an es6 map
- Bobby Hadz - sum values of object
- Stack Overflow - dynamic variable & react inline style
- Stack Overflow - width of a component based off a variable react
- Stack Overflow - render an object in react
- Bobby Hadz - count occurrences of each element in array
- Blog - recharts data charts
- Stack Overflow - merge object by id
- Stack Overflow - match objects with same key value pair
- Stack Overflow - matching elements within an array of objects
- YouTube - React Charts
- Stack Overflow - sort an array of objects by multiple fields
- Stack Overflow - change value of object in array on click event
- Stack Overflow - eslint integration with create react app
- Codepen - react tooltip (have to add react and reactDOM to see it working) - change end to ReactDOM.render
- Paladini Blog - reusable tooltip
- Codesandbox - extremely reusable tooltip component
- TestCafe - randomize e2e tests
- Reddit - wall of text
- Stack Abuse - scroll
- Stack Overflow - get viewport width and height
- Stack Overflow - submit form on enter key
- Stack Overflow - click a link with keyboard
- Github - react router onKeyPress
- Stack Overflow - merge objects
- Stack Overflow - reduce on array of objects
- YouTube - reduce on array of objects
- Medium - array reduce
- Stack Overflow - objects are not iterable
- Stack Overflow - merge objects
- TutorialsPoint - matching object values
- Stack Overflow - combine objects
- Stack Overflow - indexOf and filter
- TutorialsPoint - merge js objects
- Dev.to - merge multiple objects
- Stack Overflow - sum of same object name
- Stack Overflow - sum similar keys in an array of objects
- Vitor Paladini - reused his tooltip