Skip to content

ValentinZoia/e-commerce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

495 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

VZ-COMMERCE

Transform Shopping Into Seamless, Limitless Experiences

React TypeScript Vite Tailwind CSS ShadcnUI React Hook Form Zod Redux React Table React Query

Nodejs Express Prisma MongoDB OpenAI Whatsapp-web-js Jest

An e-commerce platform built with React, TypeScript, and Vite, leveraging modern web development practices and a component-driven architecture.

Table of Contents


What & Why

What is VZ-Commerce?

VzCommerce is a lightweight, sales-focused ecommerce platform designed for small businesses that close deals through WhatsApp.

Instead of forcing the entire checkout process inside the website, VzCommerce acts as a seamless bridge: customers browse a full product catalog, view price, stock and promotions, and once they decide to buy, the platform automatically routes the order to WhatsApp so the seller and customer can finalize payment, shipping, and details privately.

On the admin side, sellers get a complete dashboard with real-time analytics powered by Chart.js, dynamic tables with pagination for managing products, and a dedicated orders panel. It also includes an integrated AI assistant specialized in digital business and sales to provide guidance, insights, and optimization tips.

Why I Built This

I noticed that many small sellers prefer finalizing their sales through WhatsApp, where they can negotiate, build trust, and adapt pricing or delivery on the fly. However, keeping a catalog updated manually, sending photos, prices, descriptions one by one is tedious and unscalable.

VzCommerce was built to solve that gap: give customers a comfortable, organized place to explore the entire catalog, while preserving the seller's preferred workflow of closing the sale in private through WhatsApp. It blends the convenience of a modern storefront with the flexibility of conversational selling.

The Challenge

The main challenge was to create an ecommerce platform that feels complete and professional, apply Clean Architecture with design patterns, and implement a robust testing strategy with +500 tests. At the same time, building a robust admin panel with real-time analytics, dynamic data tables, and an AI assistant required careful architecture, and clean, maintainable code.


Highlights

  • Product Listings: Display of products with details such as name, description, price, and images.
  • Category Management: Categorizing products for easy navigation.
  • Shopping Cart: Add, remove, and manage products in a shopping cart.
  • Admin Authentication: Secure admin login.
  • Admin Panel: Administrative interface for managing products, categories, and orders with Data-Tables (tanstack/react-table).
  • Checkout Process: Streamlined checkout process with token-based validation.
  • AI Assistant: Private admin AI to help manage the store.
  • WhatsApp Automated Message: WhatsApp notifications for order confirmations.
  • Image Handling: Image transformation, WebP conversion, and cloudinary uploads, and lazy loading for optimized performance.
  • Real-time Analytics: Track statistics of the store with Chartjs.
  • Modular Components: Reusable UI elements and organized architecture for maintainability.
  • Optimized Build Process: Streamlined workflows with Vite, TailwindCSS, and TypeScript configurations.
  • Secure API & Authentication: Robust route protection, session management, and user authentication.
  • State & Data Management: Centralized store with Redux Toolkit, React Query, and data validation schemas.
  • Flexible Routing & Admin Tools: Organized navigation, admin dashboards, and private pages.

Pages Preview

Public Pages

'/'

'/products'

'/promotion'

'/featured'

'/new'

'/categories/zapatillas'

'/search'

'/products/:id'

Shopping Cart

'/checkout/:token'

'/order/:id'

'/login'

Private Pages

'/private/admin'

'/private/admin/analytics'

'/private/admin/products'

'/private/admin/categories'

'/private/admin/order'

'/private/admin/ai'

'/private/admin/settings'


System Architecture

The application follows a Clean Architecture with layers like Domain, Application, Infrastructure and Presentation.

If you are interested in what is a clean architecture and how you can use it, please check my free book, in Spanish.

Arquitecturas y Patrones - Valentin Zoia


Technology Stack

Layer Technology Key Packages
Frontend React 19, TypeScript, Vite react, react-router-dom, @reduxjs/toolkit, @tanstack/react-query
UI Framework Tailwind CSS 4, Radix UI, Shadcn tailwindcss, @radix-ui/react-*, lucide-react,
Data Table Tanstack React Table and Shadcn @tanstack/react-table,
Form React Hook Form and Zod for Validations react-hook-form, zod,
State Management Redux Toolkit, React Query @reduxjs/toolkit, react-redux, @tanstack/react-query
Backend Node.js, Express 5, TypeScript express, typescript, tsx
Database MongoDB with Prisma ORM @prisma/client, prisma
Authentication JWT, Bcrypt jsonwebtoken, bcryptjs
External APIs WhatsApp Web.js, OpenAI whatsapp-web.js, openai
Testing Jest, Supertest jest, supertest
Development Vite, ESLint vite, eslint

Technical Deep Dive

State Management

This project implements a hybrid state management strategy that separates server state from client state:

State Type Technology Use Case
Server State TanStack Query (React Query) Products, Categories, Orders, Auth data
Client State Redux Toolkit Shopping cart (needs persistence)
Form State React Hook Form All forms with Zod validation
UI State React useState Local component state

Why React Query + Redux?

The decision to use both technologies was intentional:

  • React Query: Handles server state with automatic caching, background refetching, optimistic updates, and cache invalidation. Perfect for data that comes from the API.
  • Redux Toolkit: Used exclusively for the shopping cart because it needs to persist across sessions (localStorage) and has complex synchronous logic with reducers.
// React Query - Server State
const { data, isLoading } = useProducts({ 
  page: 1, 
  limit: 10,
  category: 'shoes',
  priceMin: 50,
  priceMax: 200,
  sortBy: 'price',
  sortDir: 'asc'
});

// Redux Toolkit - Client State (Cart)
const { items, addItem, removeItem, clearCart } = useCartActions();

Clean Architecture (Backend)

The backend follows Clean Architecture with 4 clearly defined layers:

src/
β”œβ”€β”€ Domain/           # Entities, Interfaces, DTOs (innermost layer)
β”œβ”€β”€ Application/     # Use cases, Business logic services
β”œβ”€β”€ Infrastructure/  # External implementations (Prisma, APIs, Adapters)
└── Presentation/    # Routes, Controllers, Middlewares

Principles applied:

  • πŸ”„ Dependency Inversion: External layers depend on internal ones
  • πŸ§ͺ Testability: Each layer can be tested in isolation
  • πŸ“¦ Separation of Concerns: Responsibilities clearly defined

Design Patterns

Pattern Implementation Location
Repository Data access abstraction infrastructure/repositories/*
Builder Complex object creation ProductBuilder, OrderBuilder, OrderItemBuilder
Adapter Interface conversion OrderSendMessageToCustomer.impl.ts
Factory Test data generation Test helpers
Middleware Cross-cutting concerns AuthMiddleware, ValidationMiddleware
Dependency Injection Loose coupling Constructor injection in services

Performance Optimizations

Optimization Implementation
Lazy Loading React.lazy() + <Suspense> for routes and heavy components
Image Lazy Loading Custom <Lazy> component with IntersectionObserver
Debounced Search useDebounce hook (300ms delay) to avoid excessive API calls
Skeleton Loaders Visual placeholders during data fetch
React Query Caching staleTime: 5min, gcTime: 10min
Optimistic Updates Immediate UI updates with automatic rollback on error
Image Optimization WebP conversion, Cloudinary CDN
Component Memoization React.memo where needed

Security

Feature Implementation
JWT in Cookies httpOnly, secure, sameSite cookies
Helmet.js HTTP security headers
CORS Configurable allowed origins
Rate Limiting express-rate-limit (100 requests/15min)
bcryptjs Password hashing
Zod Validation Input validation on both client and server
Auth Middleware Token verification on protected routes

Testing Strategy

The backend has 59 test files with over 11,000 lines of test code:

Test Type Coverage
Unit Tests Services, DTOs, Entities
Integration Tests Repositories, Controllers
E2E Tests Full flows (auth β†’ create β†’ update β†’ delete)
Black Box Tests Testing without internal code access

Test Coverage by Module:

Module Unit Integration E2E
Auth βœ… βœ… βœ…
Products βœ… βœ… βœ…
Categories βœ… βœ… βœ…
Orders βœ… βœ… βœ…
Middlewares βœ… ❌ ❌

API & Data Fetching

Query Parameters

All GET endpoints support pagination and filtering:

{
  page: number;           // Current page
  limit: number;          // Items per page (take)
  search?: string;        // Text search
  category?: string;      // Filter by category
  priceMin?: number;      // Minimum price
  priceMax?: number;      // Maximum price
  inStock?: boolean;     // Only in-stock products
  freeShipping?: boolean;
  featured?: boolean;
  promotion?: boolean;
  new?: boolean;
  size?: string;
  sortBy?: 'price' | 'createdAt' | 'discountPercentage';
  sortDir?: 'asc' | 'desc';
}

Custom Hooks (25+)

The project includes many custom hooks for code reuse:

Hook Purpose
useProducts() Fetch products with filters
useProductsFilters() Filter state management
useProductById() Single product fetch
useProductMutations() CRUD operations
useCategories() Categories fetch
useCategoryMutations() Categories CRUD
useOrders(), useOrderById() Orders fetch
useOrderMutations() Orders CRUD
useStoreCustomer() Store data
useAuthMutations() Login/Logout
useSession() Session verification
useCartActions() Cart management
useCheckout() Checkout process
useAIMutations() AI chat
useDebounce() Avoid excessive requests
useImageCropper() Image cropping
useMobile() Responsive detection
useCheckoutForm() Checkout form
useProductForm() Product form
useOrderForm() Order form
useInstallments() Installment calculation
useImageUpload() Cloudinary upload

Key Features

WhatsApp Integration

  • WhatsApp Web.js for session management
  • QR authentication for linking
  • Message states: PENDING β†’ SENT β†’ RESPONDED β†’ COMPLETED
  • Automatic order confirmation messages
  • Real-time connection events

AI Integration (OpenAI)

  • OpenAI SDK integration with GPT-4.1
  • AI Chat Interface in admin panel
  • AI Insights Cards for business analysis
  • Custom endpoint support (compatible routers)

Image Management

  • Cloudinary direct upload with presets
  • Automatic WebP conversion
  • react-cropper for image resizing
  • Browser-side compression before upload
  • Multiple images per product (gallery)

Admin Dashboard

  • Real-time analytics with Recharts:
    • Line Chart: Sales trends
    • Bar Chart: Top products
    • Pie Chart: Category distribution
    • Area Chart: Monthly performance
  • Dynamic tables with TanStack Table
  • Sorting, filtering, pagination
  • Order management
  • Store configuration

Project Structure

The project is structured as a monorepo, with separate directories for the client and server.

β”œβ”€β”€ client/                  # Frontend application
β”‚   β”œβ”€β”€ src/               # Source code
β”‚   β”‚   β”œβ”€β”€ components/    # React components
β”‚   β”‚   β”œβ”€β”€ guards/        # Route guards
β”‚   β”‚   β”œβ”€β”€ hooks/         # Custom hooks (25+)
β”‚   β”‚   β”œβ”€β”€ layouts/       # Layout components
β”‚   β”‚   β”œβ”€β”€ lib/           # Utilities, axios, zod schemas
β”‚   β”‚   β”œβ”€β”€ pages/         # Page components
β”‚   β”‚   β”œβ”€β”€ types/         # TypeScript types
β”‚   β”‚   β”œβ”€β”€ store/         # Redux store
β”‚   β”‚   β”œβ”€β”€ utilities/     # Utility functions
β”‚   β”‚   β”œβ”€β”€ data/          # API calls
β”‚   β”‚   β”œβ”€β”€ App.tsx        # Main application component
β”‚   β”‚   β”œβ”€β”€ main.tsx       # Entry point
β”‚   β”‚   └── routes/        # Application routes
β”‚   β”œβ”€β”€ public/              # Static assets
β”‚   β”œβ”€β”€ package.json         # Dependencies and scripts
β”‚   β”œβ”€β”€ tsconfig.json        # TypeScript configuration
β”‚   └── vite.config.ts       # Vite configuration
β”œβ”€β”€ server/                  # Backend application
β”‚   β”œβ”€β”€ src/               # Source code
β”‚   β”‚   β”œβ”€β”€ app.ts            # Entry point
β”‚   β”‚   β”œβ”€β”€ server.ts         # Server setup
β”‚   β”‚   β”œβ”€β”€ AI/               # AI Assistant feature
β”‚   β”‚   β”œβ”€β”€ Auth/             # Authentication
β”‚   β”‚   β”œβ”€β”€ Categories/       # Categories feature
β”‚   β”‚   β”œβ”€β”€ Checkout/         # Checkout feature
β”‚   β”‚   β”œβ”€β”€ Orders/           # Orders feature
β”‚   β”‚   β”œβ”€β”€ Products/         # Products feature
β”‚   β”‚   β”œβ”€β”€ StoreCustomers/   # Store customers
β”‚   β”‚   └── shared/           # Shared modules
β”‚   β”œβ”€β”€ tests/         # Tests
β”‚   β”‚   β”œβ”€β”€ context/         # Unit & integration tests
β”‚   β”‚   β”œβ”€β”€ apps/            # E2E & black box tests
β”‚   β”‚   └── helpers/         # Factories, mocks, helpers
β”‚   β”œβ”€β”€ package.json         # Dependencies and scripts
β”‚   β”œβ”€β”€ tsconfig.json        # TypeScript configuration
β”‚   └── prisma/            # Prisma schema and migrations
β”œβ”€β”€ README.md                # Project documentation
└── .gitignore               # Specifies intentionally untracked files

Installation

  1. Clone the repository:
    git clone https://github.com/ValentinZoia/e-commerce.git
  2. Navigate to the client directory:
    cd e-commerce/client
  3. Install client dependencies:
    npm install
  4. Navigate to the server directory:
    cd ../server
  5. Install server dependencies:
    npm install
  6. Set up the database:
    • Ensure that you have a MongoDB database running.
    • Configure the database connection in the .env file in the server directory.
    DATABASE_URL="<your-mongodb-url>"
    
    • Generate the Prisma client:
    npm run prisma:generate

Usage

Client-side

  1. Navigate to the client directory:
    cd client
  2. Start the development server:
    npm run dev
    This will start the Vite development server, and you can access the application in your browser.

Server-side

  1. Navigate to the server directory:
    cd server
  2. Start the development server:
    npm run dev

Running Tests

cd server
npm test

Key Functionality and Usage Examples

  1. Product Display: Products are fetched and displayed using React components within the client/src/components directory. Data is fetched using TanStack React Query. Example usage:

    import { useQuery } from '@tanstack/react-query';
    import axios from 'axios';
    
    const fetchProducts = async () => {
      const { data } = await axios.get('/api/products');
      return data;
    };
    
    const ProductsComponent = () => {
      const { data, isLoading, error } = useQuery('products', fetchProducts);
    
      if (isLoading) return <p>Loading...</p>;
      if (error) return <p>Error: {error.message}</p>;
    
      return (
        <ul>
          {data.map(product => (
            <li key={product.id}>{product.name} - {product.price}</li>
          ))}
        </ul>
      );
    };
  2. Form Handling: React Hook Form is used for managing forms, with Zod for schema validation. Example usage from the client side:

    import { useForm } from 'react-hook-form';
    import { zodResolver } from '@hookform/resolvers/zod';
    import * as z from 'zod';
    
    const schema = z.object({
      username: z.string().min(3).max(20),
      email: z.string().email(),
    });
    
    type FormData = z.infer<typeof schema>;
    
    const MyForm = () => {
      const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
        resolver: zodResolver(schema)
      });
    
      const onSubmit = (data: FormData) => console.log(data);
    
      return (
        <form onSubmit={handleSubmit(onSubmit)}>
          <input type="text" {...register("username")} />
          {errors.username && <span>{errors.username.message}</span>}
          <input type="email" {...register("email")} />
          {errors.email && <span>{errors.email.message}</span>}
          <button type="submit">Submit</button>
        </form>
      );
    };
  3. Authentication: The application implements authentication using JWTs, with middleware for protecting routes. The AuthGuard component in client/src/guards/auth.guard.tsx handles route protection.

  4. Checkout Process: The checkout process is initiated using tokens, validated by the CheckoutGuard in client/src/guards/checkout.guard.tsx. The route /checkout/:token is used for checkout.


🀝 Contributing

  1. Fork repository
  2. Create feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add some AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open Pull Request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ“§ Contact


Built with ❀️ and best practices

About

πŸ›’E-commerce system, a full-stack web. The system enables customers to browse products, and receive WhatsApp notifications for order confirmations. It includes a admin panel with Data-Tables for managing products,categories, orders, and an AI-powered assistant.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages