/cart-app

Primary LanguageTypeScript

Cart App

This app is built with React, TypeScript, Sass, CSSModules, Vite, Vitest, and Zustand for state management.

This project is hosted at https://kl13nt.github.io/cart-app/ for convenience.

Getting Started

  1. Clone repo
  2. npm install
  3. Create .env and add VITE_API_URL=https://dummyjson.com/products

Then run the following commands as needed:

# development, building, and testing
npm run dev # dev server
npm run test # run tests
npm run build # build for production
npm run test:watch # run tests in watch mode with a browser UI

# linting, style checking, and type checking
npm run lint
npm run stylelint
npm run check
npm run tsc

Technology Stack & Decisions

I used numerous tools to ensure that the code is clean, performant, and tested. The requirements were simple enough that I didn't need to complicate the codebase too much, while allowing me to express my experience and knowledge. Technical decisions in the real world would depend on requirements and the available time-frame.

  • React: Required, but I'm also familiar with SolidJS, Vue, Next, and Qwik.
  • TypeScript: Bonus, but is my default choice nonetheless.
  • Sass: Personal preference and requirements don't force me to go for more sophisticated options.
  • CSSModules: I prefer CSSModules over BEM or alternatives because it allows for styles to be scoped to a component without having to maintain a specific naming tree.
  • Vite: CRA is deprecated, Parcel doesn't provide as many options, and Webpack is too heavy for this project. Vite is the perfect middle ground.
  • Vitest: Great alternative to Jest with a much faster test runner and direct integration with Vite and the whole development environment. I implemented Snapshot Testing, Component UI Testing, and Unit Testing.
  • Zustand: An extremely light-weight state management library with performance in mind. Removes the hassle of optimizing React Context, and has a much smaller development overhead than Redux and other alternatives. Also has native support for Redux DevTools, persistence, and other integrations.

Features

Required:

  • Fetch products from API
  • List products as cards {price in GBP, title, thumbnail}
  • Add products to cart button on cards
  • List products in cart {thumbnail, quantity, title}
  • Increase or decrease quantity of products in cart
  • Remove products from cart when quantity reaches 0
  • Display total price of cart in GBP with discounts applied

Stretch Goals Achieved:

  • Use TypeScript
  • Unit Testing
  • Design and functionality enhancements
    • Toggle-able cart drawer
    • Persistent cart state across sessions
    • Truly responsive (Scales for all sizes until 320px wide)
    • Cart drawer sticky on desktop to feel more integrated in the listing
    • Cart displays number of items in cart in header Cart Quantity
    • Product Cards display original and discounted price Discounted Price
    • Product cards indicate quantity of item in cart Quantity in Cart
    • Product cards indicate high value (15%+) discounts High Value Discount

Extras:

  • Import path aliases
  • Autogenerated TypeScript API types
  • Documented environment variables in vite-env.d.ts
  • Snapshot Testing
  • Component UI Testing
  • React, Zustand, and my own code in separate chunks
  • Deployed using GitHub Actions to GitHub Pages
  • Coverage Reporting
  • Design tokens in one place
  • Sass breakpoints to avoid repeating media queries numbers manually
  • Automatically generated type-scale that respects user preferences (using UTOPIA)

I thought about adding transitions for the cart toggling and cart icon in navbar but I didn't wish to add too many extras.

State Architecture

Architecture

Development Environment Tools

  • ESLint
  • Prettier
  • Stylelint

On larger projects I would add Husky and Lint Staged (based on team approval) to the mix to ensure that all code is linted, formatted, and tested before being committed. I would also add a CI pipeline to ensure that all code is linted and formatted before being merged into the main branch.

Types

I used Quicktype to generate the types from the JSON response since I don't have the ability to automatically generate them. In a larger, more formulated project I would be able to use OpenAPI specs, graphql schemas, or other means of API type documentation to generate these types.

Configuration options and tools I didn't include because the project isn't large enough

  • SVGR to optimize SVGs
  • Integration testing
  • Axe-core for automated pipeline accessibility testing
  • E2E automated testing
  • Storybook for component development and documentation
  • React Router for routing
  • React Query or alternatives for data fetching