Project Structure
Relevant source files
The following files were used as context for generating this wiki page: - [README.md](https://github.com/HaoNgo232/frontend-luan-van/blob/main/README.md) - [package.json](https://github.com/HaoNgo232/frontend-luan-van/blob/main/package.json) - [app/admin/layout.tsx](https://github.com/HaoNgo232/frontend-luan-van/blob/main/app/admin/layout.tsx) - [app/admin/products/new/page.tsx](https://github.com/HaoNgo232/frontend-luan-van/blob/main/app/admin/products/new/page.tsx) - [features/products/services/admin-products.service.ts](https://github.com/HaoNgo232/frontend-luan-van/blob/main/features/products/services/admin-products.service.ts) - [lib/api-client.ts](https://github.com/HaoNgo232/frontend-luan-van/blob/main/lib/api-client.ts) - [stores/](https://github.com/HaoNgo232/frontend-luan-van/blob/main/stores/) - [types/common.types.ts](https://github.com/HaoNgo232/frontend-luan-van/blob/main/types/common.types.ts) - [components/layout/admin-sidebar.tsx](https://github.com/HaoNgo232/frontend-luan-van/blob/main/components/layout/admin-sidebar.tsx) - [features/products/components/products-content.tsx](https://github.com/HaoNgo232/frontend-luan-van/blob/main/features/products/components/products-content.tsx)This project is a Next.js application for an eyewear e-commerce store. It follows a modular, feature-based architecture to promote separation of concerns, scalability, and maintainability. The structure is designed to keep business logic, UI components, and data handling organized within distinct feature domains.
Key architectural principles include a clear separation between feature-specific logic and shared utilities, a dedicated service layer for handling business logic and API communication, and centralized state management using Zustand. This approach ensures that the codebase is organized, type-safe, and easy for developers to navigate.
Sources: README.md:10-14, README.md:38-56
High-Level Directory Structure
The project's root contains several key directories that organize the application's code by its role and scope.
This diagram shows the main top-level directories in the project.
Sources: README.md:15-36
Directory Overview
| Directory | Purpose |
|---|---|
app/ | Contains all routes, pages, and layouts, following the Next.js App Router conventions. |
components/ | Holds globally shared, reusable React components, such as layouts, UI primitives, and skeletons. |
features/ | The core of the application, where each business domain (e.g., products, orders) is encapsulated as a module. |
lib/ | Contains shared utilities, helpers, and the main API client configuration. |
stores/ | Home to Zustand stores for managing global application state (e.g., auth, cart). |
types/ | Defines shared TypeScript types and interfaces used across the application. |
public/ | Stores static assets like images and fonts. |
Sources: README.md:15-36
app/ Directory (Routing)
The app/ directory uses the Next.js App Router for file-system-based routing. It includes pages, layouts, and route groups.
- Layouts: The root layout is defined in
app/layout.tsx, which sets up the global HTML structure, providers, and analytics. The admin section has its own nested layout inapp/admin/layout.tsx, which provides a consistent sidebar and header for all admin pages and implements aProtectedRouteto restrict access to users with theADMINrole. - Route Groups: The
README.mdindicates the use of route groups like(account)and(shop)to organize routes without affecting the URL path. - Pages: Each page is a
page.tsxfile within a route segment. For example,app/admin/products/new/page.tsxis the page for creating a new product. These pages are responsible for fetching data (often via hooks) and composing UI components from thefeatures/andcomponents/directories.
Sources: app/layout.tsx, app/admin/layout.tsx:1-83, app/admin/products/new/page.tsx, README.md:16-18
features/ Directory (Feature-based Modules)
This is the cornerstone of the project's architecture. Each business domain is a self-contained module within the features/ directory. This "feature-based organization" ensures that all code related to a specific feature (like "products" or "users") is co-located.
Sources: README.md:38-44, README.md:23-30
Standard Feature Module Structure
A typical feature module, such as features/products/, contains the following subdirectories:
| Sub-directory | Purpose | Example File |
|---|---|---|
components/ | React components specific to this feature. | features/products/components/products-content.tsx |
hooks/ | Custom React hooks for data fetching and state management. | features/products/hooks/use-admin-products.ts |
services/ | Contains the service class for API interactions and business logic. | features/products/services/admin-products.service.ts |
types/ | TypeScript types and interfaces specific to the feature. | features/products/types/product.types.ts |
schemas/ | Zod schemas for form validation. | features/products/schemas/product-form.schema.ts |
utils/ | Utility functions specific to the feature. | features/products/utils.ts |
Sources: README.md:24-28, app/admin/products/new/page.tsx:10-12
Service Layer
The service layer is a critical part of the architecture, abstracting away the details of API communication and data transformation. Each feature typically has a service class.
For example, AdminProductsService in features/products/services/admin-products.service.ts defines methods for product management (list, getById, create, update, delete). A key responsibility of this service is handling multipart/form-data for file uploads, which it achieves by constructing a FormData object from the request data.
This diagram illustrates the AdminProductsService class implementing the IAdminProductsService interface, encapsulating all admin-related product API calls.
Sources: features/products/services/admin-products.service.ts:25-199, README.md:46-51
lib/ Directory (Utilities & API Client)
The lib/ directory houses shared utilities, with lib/api-client.ts being the most significant file. It configures and exports a centralized Axios instance (apiClient) for all backend communication.
api-client.ts
This file establishes a robust HTTP client with several key features:
- Centralized Configuration: Defines
BASE_URL,TIMEOUT, and other constants. - Request Interceptor: Automatically attaches the JWT access token from the
useAuthStoreto theAuthorizationheader of outgoing requests. - Response Interceptor: Handles API errors, with a special focus on 401 (Unauthorized) errors. If a 401 is received, it attempts to refresh the access token using the refresh token. If successful, it retries the original request. If it fails, it clears user tokens and redirects to the login page.
- Helper Functions: Provides typed helper functions (
apiGet,apiPost, etc.) and validated versions (apiGetValidated) that parse the response against a Zod schema.
Sources: lib/api-client.ts:1-204
API Request Flow with Token Refresh
The following diagram shows the sequence of an API call that initially fails with a 401 error and is then successfully retried after a token refresh.
Sources: lib/api-client.ts:51-110
stores/ Directory (State Management)
Global state is managed using Zustand. The README.md specifies stores for cart, UI, and user state. The useAuthStore is a concrete example, used in app/admin/layout.tsx to get the user's role and in lib/api-client.ts to manage access and refresh tokens.
Sources: README.md:31-34, README.md:53-56, app/admin/layout.tsx:32, lib/api-client.ts:41
types/ Directory (Global Types)
This directory contains shared TypeScript definitions. A key file is types/common.types.ts, which defines application-wide interfaces and schemas:
ApiError: A standard structure for backend error responses.PaginatedResponse<T>: A generic wrapper for paginated API results, used extensively in services and hooks.- Zod schemas and helper functions for creating these types and for preprocessing data (e.g.,
cuidSchema,createPaginatedResponseSchema).
Sources: types/common.types.ts:1-120
Conclusion
The project's structure is a well-defined, modern frontend architecture built on Next.js. The strict feature-based organization, combined with a dedicated service layer and a robust API client, creates a scalable and maintainable codebase. This modularity allows developers to work on individual features in isolation while relying on a consistent set of shared utilities, types, and state management patterns.
Sources: README.md