A full-stack e-commerce app for a coffee shop — browse the menu, order, pay and track orders.
React + TypeScript storefront · Express + MongoDB API · EJS admin panel
ColdBrew is an online store for a coffee shop. Customers browse the menu, add drinks and desserts to a basket, place orders, "pay" for them and follow each order from paused to finished. Every paid order earns the customer a loyalty point, and the most active customers are shown on the home page. The shop owner manages products, customers and help-page content in a separate server-rendered admin panel.
The project started from a course template and was then redesigned and extended: new coffee-themed UI and home page, admin-panel fixes (image uploads, search, profile pictures), security hardening and deployment to my own server.
This repository is the customer-facing frontend. The API and admin panel live in khodiboev/coldbrew.
| Menu with search, categories and sorting | Product detail |
|---|---|
![]() |
![]() |
| Orders: paused → process → finished | Profile settings |
|---|---|
![]() |
![]() |
Shopping
- Menu page with text search, category filter (coffee, drinks, desserts, bakery), sorting (newest, best seller, low or high price) and pagination (8 products per page)
- Product detail page with an image slider (Swiper) and view counter — each signed-in user is counted once per product
- Basket kept in
localStorage, so it survives page reloads; free delivery for orders of $100 or more, otherwise a $5 fee
Orders
- Three tabs that follow the order lifecycle: Paused (placed, not paid) → Process (paid) → Finished (received)
- Pay, cancel or confirm an order directly from its tab
- Each paid order adds 1 loyalty point to the customer
Account and content
- Sign up / log in in a modal dialog; authentication with a JWT stored in an
httpOnlycookie - Profile page: edit name, phone, address, description and avatar image
- Home page sections: statistics, popular products, menu categories, an advertisement video, top customers by points, events, "why us" and location
- Help page with Terms & Conditions and FAQ, loaded from the API and editable in the admin panel
flowchart LR
U[Customer<br/>browser] -->|React SPA| F[coldbrew-react<br/>this repo]
F -->|REST + cookies| B[Express API<br/>coldbrew]
A[Shop owner] -->|server-rendered EJS| B
B --> M[(MongoDB)]
B --> D[/uploads<br/>product and user images/]
- One backend, two clients: the React SPA talks to the REST API, while the admin panel is rendered on the server with EJS.
- Two kinds of authentication: customers use a JWT in an
httpOnlycookie; the shop owner uses a server-side session stored in MongoDB.
src/
├── app/
│ ├── App.tsx routes: /, /products, /orders, /member-page, /help
│ ├── screens/ one folder per page
│ │ ├── homePage/ sections + Redux slice & selectors
│ │ ├── productsPage/ menu, product detail + slice & selectors
│ │ ├── ordersPage/ paused / process / finished tabs
│ │ ├── userPage/ profile settings
│ │ └── helpPage/ terms & FAQ
│ ├── components/ navbar, basket, auth modal, footer
│ ├── services/ API calls (axios): Member, Product, Order, Content
│ ├── context/ global auth state (React Context)
│ ├── hooks/useBasket.ts basket logic backed by localStorage
│ └── store.ts Redux Toolkit store
└── lib/ types, enums, config, alerts
State management: page data (product lists, orders) lives in Redux Toolkit slices with memoized selectors; the signed-in user and a refresh trigger live in React Context, because they are needed everywhere but change rarely.
| Area | Technologies |
|---|---|
| UI | React 18, TypeScript, MUI (Material + Joy), styled-components, Swiper, SweetAlert2 |
| State | Redux Toolkit, React Context, custom hooks |
| Routing & data | React Router, axios |
| Backend (separate repo) | Node.js, Express, TypeScript, MongoDB / Mongoose, EJS |
| Deployment | Ubuntu VPS, PM2 |
Requirements: Node.js 18+ and the backend running on port 3003.
git clone https://github.com/khodiboev/coldbrew-react.git
cd coldbrew-react
npm install
echo "REACT_APP_API_URL=http://localhost:3003" > .env
npm start # http://localhost:3000Production build:
npm run build
npm run start:prod # serves the build folder on port 3000Jurabek (Juno) Khodiboev — full-stack developer in Seoul LinkedIn · GitHub · Ask my AI assistant




