Rough order — your teacher might want screenshots of each step.
Make folders: mkdir backend and mkdir frontend
React app: cd frontend then npx create-react-app . (or copy a package.json and run npm install)
Backend deps: cd backend then npm install
Inside backend: mkdir routes
Copy the files from below into the right places
Reset empty DB: cd backend then node seed.js (wipes tables — no starter products)
API: node server.js on port 5000
React: cd frontend then npm start on port 3000
First time: register on Login, then add stock in Admin. Shop stays empty until you do. No card / payment step — not needed for the brief.
Vagrant setup
Tested with Vagrant 2.4.9. Guest VM should use Node 22.22.2 and npm 10.9.7 (or close — run node -v / npm -v inside the VM).
Put Vagrantfile and provision-vm.sh in the same folder as backend/ and frontend/ (repo root).
vagrant up — first boot installs Node via the provision script.
vagrant ssh then cd /vagrant (project is mounted there).
Ports 5000 and 3000 are forwarded to your Windows machine — open http://localhost:3000 in Edge/Chrome on the host.
Inside the VM: cd backend && npm install && node seed.js && node server.js in one terminal, and cd frontend && npm install && npm start in another (or use screen/tmux).
If the React dev server binds only to localhost inside the VM, that still works with Vagrant port forwarding.
If VirtualBox complains about VT-x, turn on virtualisation in BIOS or use WSL2 instead of Vagrant — same Node commands apply.
Backend: package.json
Express + sql.js only. Skipping cors so the file stays small (same machine = fine for marking).
backend/package.json
Backend: database.js
sql.js so you don't fight Visual Studio build tools. The Statement class is just so routes can keep using .prepare().all() like the tutorials online.
backend/database.js
Backend: server.js
Makes an uploads folder, serves files at /uploads/... so product photos work. Still no cors.
backend/server.js
Backend: seed.js
Only clears tables — no fake stock. You add real rows through Admin so the marker can see you doing CRUD. Run again if you want a clean slate (wipes users too).
backend/seed.js
Backend: routes/products.js
REST API routes for products. Supports filtering by category, searching by name, fetching categories, getting active deals (with a JOIN to the products table), and fetching a single product by ID.
backend/routes/products.js
Backend: routes/orders.js
Handles fetching a user's order history (with a JOIN to get item details) and creating new orders. When an order is placed, it calculates the total, inserts order items, and awards loyalty reward points (1 point per pound spent).
backend/routes/orders.js
Backend: routes/users.js
Sign up / log in. Passwords kept as plain text so the file stays short. Redeem is fixed at 100 points = £10 off.
backend/routes/users.js
Backend: routes/admin.js
POST /api/admin/upload with form field image saves a file and returns { url: "/uploads/p-....jpg" }. Put that string in image_url. Stock is just a number column — set it when adding/editing.
backend/routes/admin.js
Frontend: package.json
React app dependencies. Uses react-router-dom for page navigation and react-scripts for the dev server and build tooling.
frontend/package.json
Frontend: public/index.html
The HTML shell. React mounts into the div with id "root".
frontend/public/index.html
Frontend: src/index.js
Entry point. Wraps the App in BrowserRouter (for routing), UserProvider and CartProvider (for global state).
frontend/src/index.js
Frontend: src/index.css
Global CSS reset. Removes default margins, sets the base font, and resets link/button/input styles.
frontend/src/index.css
Frontend: src/App.js
Navbar, routes, footer. Admin route is just another path.
frontend/src/App.js
Frontend: src/App.css
All the styles for the entire application — navbar, slide-out basket, footer, hero, product grid, cards, forms, checkout layout, auth pages, and responsive breakpoints. This is the longest file.
frontend/src/App.css
State Management: CartContext.js
React Context for the checkout basket. Provides addToCart, removeFromCart, updateQuantity, clearCart, plus computed cartTotal and cartCount values to all components.
frontend/src/context/CartContext.js
State Management: UserContext.js
React Context for the logged-in user. Persists user data to localStorage so the session survives page refreshes.
frontend/src/context/UserContext.js
Component: Navbar.js
Navigation bar with logo, page links (including Admin link), basket button with item count badge, and login/logout. Includes a slide-out panel with quantity controls and checkout links for delivery or collection.
frontend/src/components/Navbar.js
Component: ProductCard.js
Reusable product card used on the Home, Products, and Deals pages. Shows the image (emoji), name, description, price (with deal price if applicable), and an add button with a brief confirmation state.
frontend/src/components/ProductCard.js
Page: Home.js
Landing page with a hero banner, category grid linking to filtered listings, a preview of current promotions, and featured items from the first category (Electronics).
frontend/src/pages/Home.js
Page: Products.js
Browse all products with a sidebar category filter and search bar. Uses useSearchParams to read/write the category from the URL query string. Fetches deals to show discount badges on matching products.
frontend/src/pages/Products.js
Page: Deals.js
Shows all active deals with a red banner and product cards displaying discount percentages and original/deal prices.
frontend/src/pages/Deals.js
Page: OrderHistory.js
Displays the logged-in user's past orders. Each order card shows the order number, date, status badge, item list, delivery/collection info, and total. Requires authentication.
frontend/src/pages/OrderHistory.js
Page: Rewards.js
£1 spent = 1 point. 100 points = £10 off (button posts { points: 100 } to the API).
frontend/src/pages/Rewards.js
Page: Collection.js
Pickup checkout page. Uses a single branch (no dropdown — just one store). User picks a date and time slot, reviews the order summary, and submits. Success screen shows confirmation and loyalty points.
frontend/src/pages/Collection.js
Page: Delivery.js
Home delivery checkout page. User enters their address, postcode, selects a date and time slot. Includes a delivery fee (£3.99, free over £40). Order summary with running total. Success screen on completion.
frontend/src/pages/Delivery.js
Page: Login.js
Combined login and registration page. Toggles between login and register forms. Sends credentials to the backend API and stores the returned user data in UserContext on success.
frontend/src/pages/Login.js
Page: Admin.js + image helpers
Admin: file input → FormData + fetch('/api/admin/upload') → paste returned url into image_url. Or type an emoji. Stock: number input + show in the table. Shop:ProductThumb.js + productImage.js turn /uploads/... into <img src="http://localhost:5000/uploads/..."> (React runs on 3000, images on 5000).