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
- Technology Stack & Decisions
- Features
- State Architecture
- Development Environment Tools
- Types
- Configuration options and tools I didn't include because the project isn't large enough
- Clone repo
npm install
- Create
.env
and addVITE_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
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.
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
- Product Cards display original and discounted price
- Product cards indicate quantity of item in cart
- Product cards indicate high value (15%+) discounts
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.
- 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.
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.
- 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