One momentβ¦
Building the next page.
One momentβ¦
Building the next page.
Full-Stack Customer Management
A full-stack Customer Management application with a React and TypeScript dashboard backed by a Node.js and Express REST API, focused on clean architecture, reusable components, validation and reliable error handling.
ManageConnectOrganizeScale!
Idea to ImpactOne Sprint at a Time
This project is a full-stack Customer Management System built with a React + TypeScript frontend and a Node.js + Express backend.
The goal was to build a clean and scalable customer management experience while following practical frontend and backend engineering patterns.
The project focuses on more than simply displaying customer data. It demonstrates how a frontend application, reusable UI architecture and REST API can work together through clearly separated responsibilities.
The application provides a dashboard where users can manage customer records through a simple and responsive interface.
The main functionality includes:
The backend exposes a versioned REST API for managing the customer data.
The dashboard provides the core operations required for managing customers.
Users can:
The customer interface is designed around reusable components so additional customer functionality can be introduced without restructuring the entire application.
The frontend is built with React, TypeScript and Vite.
The codebase follows a structured architecture separating:
This keeps application responsibilities separated and makes the codebase easier to maintain.
The application uses custom hooks to isolate reusable application logic.
Examples include:
useCustomers for customer data operationsuseToast for notification handlingThis keeps page and UI components focused on rendering and interaction rather than mixing them with API and notification logic.
Forms and tables use configuration-driven patterns.
Instead of hardcoding every field or table configuration directly inside individual components, configuration can define how the UI should behave.
This makes the application easier to extend and reduces repetitive code.
Customer forms use Zod for validation.
The application provides:
This keeps validation rules centralized and makes form behavior more predictable.
The frontend communicates with the backend REST API using Axios.
The backend API is versioned under:
/api/v1
Available customer operations include:
GET /customersPOST /customersDELETE /customers/:idThe backend also provides a health check endpoint:
GET /healthThe backend is built with Node.js and Express.
The project follows a structured backend architecture with separate responsibilities for:
Business logic is handled through controllers while validation and error handling are handled through middleware.
The backend includes request validation middleware and centralized error handling.
A custom AppError class is used for application-level errors.
API responses follow a standardized structure.
Successful responses use:
{
"success": true,
"message": "Success",
"data": {}
}
Errors use:
{
"success": false,
"message": "Error message",
"code": "ERROR_CODE"
}
This provides a predictable API contract for the frontend.
The dashboard includes several UX-focused features:
The project also uses theme-based styling rather than relying on hardcoded colors throughout the UI.
The UI follows a theme-based styling approach.
Instead of directly embedding colors throughout individual components, styling is connected to the application's theme system.
This makes visual changes easier to manage and helps maintain consistency throughout the dashboard.
The frontend also includes SEO considerations along with a global error boundary and dedicated 404 page.
These features help the application handle unexpected UI errors and invalid routes more gracefully.
The current backend uses in-memory storage rather than a persistent database.
This keeps the project lightweight while maintaining a structure that can later be extended to a database such as MongoDB or PostgreSQL.
This project was a practical exercise in understanding how frontend and backend responsibilities fit together.
Rather than treating the frontend and backend as separate pieces, the project helped reinforce the importance of having a clear contract between them.
From API response structures and validation to reusable React components and error handling, each layer has a specific responsibility.
The current architecture leaves room for additional functionality.
Potential improvements include:
The backend is already structured in a way that allows the current in-memory storage to be replaced with a persistent database in the future.