Skip to content

Latest commit

 

History

124 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

SetupLab

React Vite Node.js Express MongoDB

A full-stack e-commerce web application for computer hardware and setup products. Users can browse products, filter by category, save favorites, manage a shopping cart, and place orders. The application includes user authentication with login and registration functionality.


Table of Contents


Getting Started — Frontend

The frontend is built with React 19 and Vite.

Requirements: Node.js installed on your machine.

# 1. Navigate to the frontend folder
cd setuplab-frontend

# 2. Install dependencies
npm install

# 3. Start the development server
npm run dev

The application will be available at http://localhost:5173

The backend must also be running for the application to work correctly.


Getting Started — Backend

The backend is built with Node.js, Express, and MongoDB.

Requirements: Node.js and a MongoDB database (local or MongoDB Atlas).

1. Navigate to the backend folder

cd setuplab-backend

2. Create a .env file

Create a file named .env in the setuplab-backend/ folder with the following content:

PORT=3000
CONNECTION_STRING=your_mongodb_connection_string_here
ACCESS_TOKEN_SECRET=your_secret_key_here
Variable Description
PORT The port the server runs on (default: 3000)
CONNECTION_STRING MongoDB connection URI (local or Atlas)
ACCESS_TOKEN_SECRET Secret key used to sign and verify JWT tokens

3. Install dependencies

npm install

4. Seed the database with products (first time only)

npm run seed

5. Start the development server

npm run dev

The backend API will be available at http://localhost:3000

A default test user is created automatically when the server starts (see below).


Test Account

A default user is created automatically on server startup if it does not already exist.

Field Value
Username user
Password password

API Endpoints

Method Endpoint Auth required Description
GET /api/products No Returns all products
GET /api/products/:id No Returns a single product by ID
POST /api/users/register No Creates a new user account
POST /api/users/login No Logs in and returns a JWT token
GET /api/users/current Yes (Bearer) Returns the currently logged-in user
POST /api/orders No Creates a new order

Protected endpoints require an Authorization: Bearer <token> header.


Project Structure

Frontend — setuplab-frontend/

setuplab-frontend/
├── index.html              # HTML entry point
├── vite.config.js          # Vite configuration
├── public/
│   └── images/             # Static images
└── src/
    ├── App.jsx             # Root component — renders Navbar, Footer, and routes
    ├── main.jsx            # Application entry point — mounts App with all Providers
    ├── api/
    │   └── apiClient.js    # Shared fetch wrapper for all HTTP requests to the backend
    ├── services/
    │   ├── authService.js  # Login, register, token and user storage functions
    │   ├── productService.js # Fetch all products or a single product
    │   └── orderService.js # Create a new order
    ├── context/
    │   ├── AuthContext.jsx      # Global auth state — user, token, login/logout/register
    │   ├── CartContext.jsx      # Global cart state — items persisted in localStorage
    │   └── FavoritesContext.jsx # Global favorites state — persisted in localStorage
    ├── components/
    │   ├── Navbar/         # Top navigation bar with links and cart icon
    │   ├── Footer/         # Site footer
    │   ├── Hero/           # Hero banner shown on the home page
    │   ├── ProductCard/    # Card component for displaying a single product
    │   ├── ProductList/    # Renders a grid of ProductCards
    │   ├── CategoryFilter/ # Filter buttons for filtering products by category
    │   ├── CartItem/       # Single item row in the shopping cart
    │   ├── CheckoutForm/   # Form for entering customer and payment details
    │   ├── PageHeader/     # Reusable page title/header component
    │   └── ScrollToTop/    # Scrolls to top on route change
    ├── pages/
    │   ├── HomePage/            # Landing page with hero and featured products
    │   ├── ProductsPage/        # All products with category filter
    │   ├── ProductDetailsPage/  # Single product with full details
    │   ├── FavoritesPage/       # List of favorited products
    │   ├── CartPage/            # Shopping cart with quantity controls
    │   ├── CheckoutPage/        # Checkout form — requires items in cart
    │   ├── ConfirmationPage/    # Order confirmation after successful checkout
    │   └── LoginRegisterPage/   # Login and registration on the same page
    ├── routes/
    │   └── AppRoutes.jsx   # Defines all client-side routes using React Router
    ├── helpers/
    │   └── formatPrice.js  # Utility for formatting prices
    └── styles/
        └── global.css      # Global CSS variables and base styles

Backend — setuplab-backend/

setuplab-backend/
├── server.js               # Entry point — sets up Express, middleware, routes, and starts the server
├── package.json
├── config/
│   └── dbConnection.js     # Connects to MongoDB using Mongoose
├── routes/
│   ├── productRoutes.js    # GET /api/products, GET /api/products/:id
│   ├── orderRoutes.js      # POST /api/orders
│   └── userRoutes.js       # POST /api/users/register, POST /api/users/login, GET /api/users/current
├── controllers/
│   ├── productController.js # Handles product logic — fetch all or one product
│   ├── orderController.js   # Handles order creation and saves to database
│   └── userController.js    # Handles registration, login, and current user
├── models/
│   ├── productModel.js      # Mongoose schema for products
│   ├── orderModel.js        # Mongoose schema for orders
│   └── userModel.js         # Mongoose schema for users
├── middleware/
│   ├── validateTokenHandler.js # Verifies JWT token — protects private routes
│   └── errorHandler.js         # Global error handler — formats error responses
└── seed/
    ├── seedProducts.js      # Seeds the database with initial product data
    └── seedDefaultUser.js   # Creates a default test user on server startup

Data Flow

Below is a description of how data flows through the application from the user's perspective.

Fetching and displaying products

User visits /products
  → ProductsPage calls productService.getProducts()
    → productService calls apiClient.request("/products")
      → GET http://localhost:3000/api/products
        → Express routes to productController.getProducts()
          → productController queries MongoDB via productModel
            → MongoDB returns product documents
          ← productController formats and returns JSON
        ← Express sends response
      ← apiClient returns parsed JSON
    ← productService returns array of products
  ← ProductsPage stores products in local state
← Products are rendered via ProductList → ProductCard

Adding to cart

User clicks "Add to cart" on a ProductCard
  → CartContext.addToCart(product) is called
    → Cart state is updated in memory
    → Updated cart is saved to localStorage
  ← All components using CartContext re-render with updated cart

Placing an order

User fills in CheckoutForm and submits
  → CheckoutPage calls orderService.createOrder(orderData)
    → orderService calls apiClient.request("/orders", { method: "POST", body: ... })
      → POST http://localhost:3000/api/orders
        → Express routes to orderController.createOrder()
          → Request body is validated (customer, paymentMethod, items)
          → Order is saved to MongoDB via orderModel
          ← orderController returns the saved order
        ← Express sends response
      ← apiClient returns order data
    ← orderService returns order
  ← User is redirected to /confirmation
  ← Cart is cleared

Login

User submits login form
  → LoginRegisterPage calls AuthContext.login(username, password)
    → AuthContext calls authService.loginUser()
      → POST http://localhost:3000/api/users/login
        → Express routes to userController.loginUser()
          → Username is looked up in MongoDB
          → Password is verified with bcrypt
          → JWT access token is generated and returned
        ← Express sends token + user data
      ← authService receives token
    ← AuthContext saves token to localStorage and updates auth state
  ← isLoggedIn becomes true — UI updates accordingly

Responsibilities by Layer

Frontend

Layer Responsibility
pages/ Full-page views. Fetch data, manage local state, compose components.
components/ Reusable UI pieces. Receive props and render markup. No direct API calls.
context/ Global state shared across the entire app (auth, cart, favorites).
services/ All communication with the backend API. One service per resource.
api/ Low-level HTTP logic. Shared request() function used by all services.
routes/ Defines URL paths and which page component is rendered for each path.
helpers/ Small utility functions (e.g. formatting prices).
styles/ Global CSS variables and base styles applied across the entire application.

Backend

Layer Responsibility
server.js Bootstraps the application — registers middleware, routes, and starts server.
routes/ Maps HTTP method + URL to the correct controller function.
controllers/ Business logic — validates input, queries the database, sends responses.
models/ Mongoose schemas that define the shape of data stored in MongoDB.
middleware/ Reusable request processing — JWT validation and global error handling.
config/ Database connection setup.
seed/ Scripts for populating the database with initial or default data.




SetupLab — Svenska

En fullstack e-handelssajt för datorkomponenter och setup-produkter. Användare kan bläddra bland produkter, filtrera på kategori, spara favoriter, hantera en varukorg och lägga beställningar. Applikationen har inbyggd användarautentisering med inloggning och registrering.


Innehåll


Kom igång — Frontend

Frontenden är byggd med React 19 och Vite.

Krav: Node.js måste vara installerat på din dator.

# 1. Navigera till frontend-mappen
cd setuplab-frontend

# 2. Installera beroenden
npm install

# 3. Starta utvecklingsservern
npm run dev

Applikationen är tillgänglig på http://localhost:5173

Backendet måste också vara igång för att applikationen ska fungera korrekt.


Kom igång — Backend

Backendet är byggt med Node.js, Express och MongoDB.

Krav: Node.js och en MongoDB-databas (lokal eller MongoDB Atlas).

1. Navigera till backend-mappen

cd setuplab-backend

2. Skapa en .env-fil

Skapa en fil med namnet .env i mappen setuplab-backend/ med följande innehåll:

PORT=3000
CONNECTION_STRING=din_mongodb_connection_string_här
ACCESS_TOKEN_SECRET=din_hemliga_nyckel_här
Variabel Beskrivning
PORT Porten som servern körs på (standard: 3000)
CONNECTION_STRING MongoDB-anslutnings-URI (lokal eller Atlas)
ACCESS_TOKEN_SECRET Hemlig nyckel som används för att signera och verifiera JWT-tokens

3. Installera beroenden

npm install

4. Lägg in produkter i databasen (endast första gången)

npm run seed

5. Starta utvecklingsservern

npm run dev

Backend-API:et är tillgängligt på http://localhost:3000

En standardanvändare skapas automatiskt när servern startar (se nedan).


Testkonto

En standardanvändare skapas automatiskt när servern startar, om den inte redan finns.

Fält Värde
Användarnamn user
Lösenord password

API-endpoints

Metod Endpoint Kräver auth Beskrivning
GET /api/products Nej Returnerar alla produkter
GET /api/products/:id Nej Returnerar en specifik produkt baserat på ID
POST /api/users/register Nej Skapar ett nytt användarkonto
POST /api/users/login Nej Loggar in och returnerar en JWT-token
GET /api/users/current Ja (Bearer) Returnerar den inloggade användaren
POST /api/orders Nej Skapar en ny order

Skyddade endpoints kräver headern Authorization: Bearer <token>.


Projektstruktur

Frontend — setuplab-frontend/

setuplab-frontend/
├── index.html              # HTML-startpunkt
├── vite.config.js          # Konfiguration för Vite
├── public/
│   └── images/             # Statiska bilder
└── src/
    ├── App.jsx             # Rotkomponent — renderar Navbar, Footer och routes
    ├── main.jsx            # Applikationens startpunkt — monterar App med alla Providers
    ├── api/
    │   └── apiClient.js    # Gemensam fetch-funktion för alla HTTP-anrop till backend
    ├── services/
    │   ├── authService.js  # Inloggning, registrering, token- och användarlagring
    │   ├── productService.js # Hämtar alla produkter eller en specifik produkt
    │   └── orderService.js # Skapar en ny order
    ├── context/
    │   ├── AuthContext.jsx      # Global autentiseringsstate — användare, token, login/logout
    │   ├── CartContext.jsx      # Global varukorgsstate — sparas i localStorage
    │   └── FavoritesContext.jsx # Global favoritstate — sparas i localStorage
    ├── components/
    │   ├── Navbar/         # Navigeringsfält högst upp med länkar och kundkorgsikon
    │   ├── Footer/         # Sidfot
    │   ├── Hero/           # Hero-banner som visas på startsidan
    │   ├── ProductCard/    # Kortkomponent för att visa en enskild produkt
    │   ├── ProductList/    # Renderar ett rutnät av ProductCards
    │   ├── CategoryFilter/ # Filterknappar för att filtrera produkter efter kategori
    │   ├── CartItem/       # En rad i varukorgen för en enskild produkt
    │   ├── CheckoutForm/   # Formulär för att fylla i kunduppgifter och betalning
    │   ├── PageHeader/     # Återanvändbar sidtitel/rubrikkomponent
    │   └── ScrollToTop/    # Scrollar till toppen vid sidnavigering
    ├── pages/
    │   ├── HomePage/            # Startsida med hero och populära produkter
    │   ├── ProductsPage/        # Alla produkter med kategorifilter
    │   ├── ProductDetailsPage/  # Enskild produkt med fullständig information
    │   ├── FavoritesPage/       # Lista med favoritmarkerade produkter
    │   ├── CartPage/            # Varukorg med möjlighet att ändra antal
    │   ├── CheckoutPage/        # Kassasida — kräver produkter i varukorgen
    │   ├── ConfirmationPage/    # Orderbekräftelse efter genomförd beställning
    │   └── LoginRegisterPage/   # Inloggning och registrering på samma sida
    ├── routes/
    │   └── AppRoutes.jsx   # Definierar alla klientsidans routes med React Router
    ├── helpers/
    │   └── formatPrice.js  # Hjälpfunktion för att formatera priser
    └── styles/
        └── global.css      # Globala CSS-variabler och grundstilar

Backend — setuplab-backend/

setuplab-backend/
├── server.js               # Startpunkt — sätter upp Express, middleware, routes och startar servern
├── package.json
├── config/
│   └── dbConnection.js     # Kopplar upp mot MongoDB med Mongoose
├── routes/
│   ├── productRoutes.js    # GET /api/products, GET /api/products/:id
│   ├── orderRoutes.js      # POST /api/orders
│   └── userRoutes.js       # POST /api/users/register, POST /api/users/login, GET /api/users/current
├── controllers/
│   ├── productController.js # Produktlogik — hämtar alla eller en specifik produkt
│   ├── orderController.js   # Orderlogik — skapar och sparar order i databasen
│   └── userController.js    # Användarlogik — registrering, inloggning och hämtning av inloggad användare
├── models/
│   ├── productModel.js      # Mongoose-schema för produkter
│   ├── orderModel.js        # Mongoose-schema för ordrar
│   └── userModel.js         # Mongoose-schema för användare
├── middleware/
│   ├── validateTokenHandler.js # Verifierar JWT-token — skyddar privata endpoints
│   └── errorHandler.js         # Global felhanterare — formaterar felmeddelanden
└── seed/
    ├── seedProducts.js      # Fyller databasen med startprodukter
    └── seedDefaultUser.js   # Skapar en standardanvändare när servern startar

Dataflöde

Nedan beskrivs hur data flödar genom applikationen ur användarens perspektiv.

Hämta och visa produkter

Användaren besöker /products
  → ProductsPage anropar productService.getProducts()
    → productService anropar apiClient.request("/products")
      → GET http://localhost:3000/api/products
        → Express skickar vidare till productController.getProducts()
          → productController hämtar data från MongoDB via productModel
            → MongoDB returnerar produktdokument
          ← productController formaterar och returnerar JSON
        ← Express skickar svar
      ← apiClient returnerar tolkad JSON
    ← productService returnerar array med produkter
  ← ProductsPage sparar produkterna i lokalt state
← Produkterna renderas via ProductList → ProductCard

Lägga till i varukorgen

Användaren klickar "Lägg i varukorg" på en ProductCard
  → CartContext.addToCart(product) anropas
    → Varukorgens state uppdateras i minnet
    → Uppdaterad varukorg sparas i localStorage
  ← Alla komponenter som använder CartContext renderas om med uppdaterad data

Lägga en beställning

Användaren fyller i CheckoutForm och skickar
  → CheckoutPage anropar orderService.createOrder(orderData)
    → orderService anropar apiClient.request("/orders", { method: "POST", body: ... })
      → POST http://localhost:3000/api/orders
        → Express skickar vidare till orderController.createOrder()
          → Request body valideras (kunduppgifter, betalningsmetod, produkter)
          → Ordern sparas i MongoDB via orderModel
          ← orderController returnerar den sparade ordern
        ← Express skickar svar
      ← apiClient returnerar orderdata
    ← orderService returnerar ordern
  ← Användaren omdirigeras till /confirmation
  ← Varukorgen töms

Logga in

Användaren skickar inloggningsformuläret
  → LoginRegisterPage anropar AuthContext.login(username, password)
    → AuthContext anropar authService.loginUser()
      → POST http://localhost:3000/api/users/login
        → Express skickar vidare till userController.loginUser()
          → Användarnamnet slås upp i MongoDB
          → Lösenordet verifieras med bcrypt
          → En JWT-token genereras och returneras
        ← Express skickar token och användardata
      ← authService tar emot token
    ← AuthContext sparar token i localStorage och uppdaterar auth-state
  ← isLoggedIn blir true — gränssnittet uppdateras

Vad varje del ansvarar för

Frontend

Lager Ansvar
pages/ Helsidiga vyer. Hämtar data, hanterar lokalt state och sätter ihop komponenter.
components/ Återanvändbara UI-delar. Tar emot props och renderar markup. Gör inga direkta API-anrop.
context/ Globalt state som delas i hela applikationen (auth, varukorg, favoriter).
services/ All kommunikation med backend-API:et. En service-fil per resurs.
api/ Lågnivå HTTP-logik. Gemensam request()-funktion som används av alla services.
routes/ Definierar URL-sökvägar och vilken sidkomponent som renderas för varje path.
helpers/ Små hjälpfunktioner (t.ex. formatering av priser).
styles/ Globala CSS-variabler och grundstilar som gäller i hela applikationen.

Backend

Lager Ansvar
server.js Startar applikationen — registrerar middleware, routes och startar servern.
routes/ Mappar HTTP-metod + URL till rätt controller-funktion.
controllers/ Affärslogik — validerar indata, frågar databasen och skickar svar.
models/ Mongoose-scheman som definierar hur data ser ut i MongoDB.
middleware/ Återanvändbar request-hantering — JWT-validering och global felhantering.
config/ Databaskopplingskonfiguration.
seed/ Skript för att fylla databasen med startdata eller standardanvändare.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages