Skip to content

cinblockchain91/cuonghv91-main

Repository files navigation

React Tasks Application

Live Demo: View Application

Overview

This project is a refactored React application designed with long-term maintainability, scalability, and robustness as first-class goals. The main objective of this refactor is to transform the original codebase into a clean, well-structured, and future-proof architecture, suitable for continuous expansion over many years.

All architectural decisions prioritize clarity, separation of concerns, and predictable data flow. The application is built using React + TypeScript + Vite, with a feature-oriented structure and modern best practices.

Table of Contents

Tech Stack

  • React 19 - UI library
  • TypeScript - Type safety
  • Vite - Build tool and dev server
  • Zustand - State management
  • Zod - Runtime schema validation
  • Axios - HTTP client
  • React Router DOM - Routing
  • Tailwind CSS - Styling
  • Radix UI - Accessible UI primitives (shadcn-inspired components)
  • Lucide React - Icon library
  • Vitest - Unit testing framework

Prerequisites

  • Node.js (v18 or higher recommended)
  • npm or yarn package manager

Getting Started

  1. Clone the repository

    git clone <repository-url>
    cd ReactTaskTS-cuonghv91
  2. Install dependencies

    npm install
  3. Start the development server

    npm run dev
  4. Open your browser Navigate to http://localhost:5173 (or the port shown in your terminal)

Available Scripts

  • npm run dev - Start development server
  • npm run build - Build for production
  • npm run preview - Preview production build locally
  • npm run lint - Run ESLint
  • npm run test - Run unit tests with Vitest

Project Structure

src/
├─ components/
│  ├─ ui/
│  │  └─ Reusable, framework-agnostic UI components
│  └─ error-boundary.tsx
│     └─ React Error Boundary for graceful error handling
│
├─ features/
│  ├─ product/
│  │  ├─ api.ts          - Product API interface
│  │  ├─ hook.ts         - Zustand store with localStorage persistence
│  │  ├─ schema.ts       - Zod schemas for runtime validation
│  │  ├─ type-guards.ts  - Type guards with Zod validation
│  │  ├─ factory.ts      - Centralized product construction
│  │  ├─ validation.ts   - Form validation logic
│  │  └─ statistics.ts   - Business logic for statistics
│  └─ theme/
│     └─ Application theming and UI state
│
├─ https/
│  └─ axios.ts
│     └─ Centralized Axios instance with global configuration
│
├─ lib/
│  ├─ constant.ts
│  ├─ helpers.ts
│  └─ utils.ts
│     └─ Shared utilities and constants
│
├─ pages/
│  ├─ not-found/
│  │  └─ 404 handling (components, hooks, types isolated)
│  │
│  ├─ product/
│  │  ├─ components/
│  │  │  ├─ common-fields.tsx (Shared form fields)
│  │  │  ├─ product-form.tsx
│  │  │  ├─ product-list.tsx
│  │  │  ├─ product-card.tsx
│  │  │  └─ Type-specific field components
│  │  ├─ registry/
│  │  │  └─ display.registry.tsx (Registry pattern for product display)
│  │  ├─ types/
│  │  │  └─ product.types.ts
│  │  └─ index.tsx
│  │     └─ Product listing and creation page
│  │
│  └─ product-detail/
│     └─ Product detail page
│
├─ routes/
│  ├─ layouts/
│  │  └─ Application layout definitions
│  └─ index.tsx
│     └─ Centralized route configuration
│
├─ App.tsx
│  └─ Root application component
│
├─ providers.tsx
│  └─ Global providers (state, theme, etc.)
│
├─ main.tsx
│  └─ Application bootstrap
│
└─ global.css
   └─ Global styles

Architecture

1. Feature-Based Organization

Instead of grouping code by technical type only (components, hooks, services), the application groups logic by business domain:

  • features/product
  • features/theme

This approach:

  • Scales naturally as the app grows
  • Keeps related logic close together
  • Prevents massive shared folders over time

2. UI Components vs Domain Logic

  • components/ui → Pure, reusable UI primitives with no business logic

  • components/common-fields.tsx → Shared form fields (name, price, brand) to reduce duplication (DRY principle)

  • features/_ and pages/_ → Own all domain-specific behavior

This ensures UI components remain stable even as business rules evolve.

3. Centralized HTTP Layer

src/https/axios.ts

  • Single Axios instance
  • Global configuration
  • Easy to add: interceptors, authentication, logging, retries, error normalization

This avoids scattered API logic and makes backend changes safer.

4. Explicit Routing Layer

src/routes/

  • Routes are declared in one place
  • Layouts are reusable and composable
  • Easy to introduce: protected routes, role-based access, lazy loading

5. Predictable State Management

Zustand is used intentionally for:

  • Simplicity
  • Explicit state ownership
  • Minimal boilerplate

State logic is colocated with the feature it belongs to.

6. Registry Pattern for Extensibility

src/pages/product/registry/display.registry.tsx

The application uses a registry pattern for product display logic:

  • OCP Compliant: New product types can be added without modifying existing code
  • Centralized Display Logic: Product subtitles, size displays, and additional info are managed through a registry
  • Type-Safe: Full TypeScript support with discriminated unions

This pattern replaces switch statements and enables easy extension of product types.

8. Runtime Validation with Zod

src/features/product/schema.ts

Zod schemas provide runtime type safety at all system boundaries:

  • Schema Validation: All external data (localStorage, JSON imports) is validated
  • Type Guards: Type guards use Zod for actual validation, not just type assertions
  • Centralized Factory: Product construction through factory pattern with validation
  • Form Validation: Centralized validation logic with detailed error messages

This ensures invalid data cannot propagate through the application.

7. Error Handling

src/components/error-boundary.tsx

React Error Boundaries are implemented throughout the application:

  • Graceful Degradation: Errors in components don't crash the entire app
  • User-Friendly Messages: Clear error messages with retry functionality
  • Development Support: Detailed error information in development mode

Error boundaries wrap critical sections like forms, lists, and detail pages.

Key Design Principles

  • Feature-first architecture for scalability
  • Clear separation of concerns
  • Explicit ownership of logic (UI vs domain vs infrastructure)
  • Type safety end-to-end (no any or unknown types)
  • Minimal coupling, high cohesion
  • DRY principle (common fields extracted to shared components)
  • Registry pattern for extensibility (OCP compliance)
  • Error boundaries for robust error handling
  • Easy onboarding for new developers

Maintainability & Long-Term Expansion

This architecture supports:

  • Adding new features without touching existing ones
  • Adding new product types through registry pattern (no code modifications needed)
  • Refactoring safely with strong TypeScript guarantees
  • Graceful error handling that doesn't break user experience
  • Onboarding new developers quickly
  • Migrating to SSR or backend integration later
  • Replacing UI libraries without rewriting business logic
  • Shared components reduce duplication and maintenance burden

About

Front end assignment test

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors