Overview
MotorDesk follows a feature-based organization pattern with clear separation of concerns. This guide explains the purpose of each directory and the conventions used throughout the codebase.
Root Directory Structure
fleet-pwa/
├── public/ # Static assets served as-is
├── src/ # Application source code
├── .gitignore # Git ignore patterns
├── eslint.config.js # ESLint configuration
├── index.html # HTML entry point
├── package.json # Project dependencies and scripts
├── tsconfig.json # TypeScript base configuration
├── tsconfig.app.json # TypeScript app-specific settings
├── tsconfig.node.json # TypeScript Node.js configuration
└── vite.config.ts # Vite build configuration
Source Directory (src/)
The src/ directory contains all application code organized into logical modules:
src/
├── assets/ # Images, fonts, and other static assets
├── components/ # React components organized by feature
├── constants/ # Application constants and enums
├── data/ # Data layer (database, mock data)
├── hooks/ # Custom React hooks
├── pages/ # Top-level page components
├── routes/ # Routing configuration
├── services/ # External API services
├── store/ # Redux store configuration
├── styles/ # CSS modules and global styles
├── ui/ # UI utilities and icons
├── App.tsx # Root application component
├── index.css # Global styles
└── main.tsx # Application entry point
Directory Details
/src/components/ - Component Organization
Components are organized by domain/feature area:
components/
├── auth/ # Authentication components
│ └── LogoutConfirmModal.tsx
├── customers/ # Customer management
│ ├── CustomerDeleteModal.tsx
│ ├── CustomerDetailsModal.tsx
│ └── CustomerFormModal.tsx
├── layout/ # Layout components
│ └── MainLayout.tsx
├── products/ # Product management
│ ├── ProductDeleteModal.tsx
│ ├── ProductDetailsModal.tsx
│ └── ProductFormModal.tsx
├── sales/ # Sales/billing components
│ └── InlineActionButton.tsx
├── ui/ # Reusable UI components
│ ├── Autocomplete.tsx
│ ├── Button.tsx
│ ├── FormField.tsx
│ ├── Input.tsx
│ └── Select.tsx
└── vehicles/ # Vehicle management
├── VehicleDeleteModal.tsx
├── VehicleDetailsModal.tsx
└── VehicleFormModal.tsx
Feature-based organization : Each domain (customers, vehicles, products) has its own directory containing all related components.
/src/hooks/ - Custom Hooks
Business logic is extracted into custom hooks for reusability:
hooks/
├── useAuth.ts # Authentication logic
├── useCustomers.ts # Customer CRUD operations
├── useHomeStats.ts # Dashboard statistics
├── useMainLayout.ts # Layout state management
├── usePermissions.ts # Role-based permissions
├── useProducts.ts # Product management
├── useReports.ts # Report generation
├── useSales.ts # Sales/billing operations
├── useSettings.ts # Application settings
└── useVehicles.ts # Vehicle management
Each hook encapsulates:
State management
Data fetching/mutations
Business logic
Side effects
See Custom Hooks for detailed documentation.
/src/pages/ - Page Components
Top-level page components corresponding to routes:
pages/
├── Customers.tsx # Customer listing and management
├── Home.tsx # Dashboard/homepage
├── Login.tsx # Authentication page
├── Products.tsx # Product catalog management
├── Reports.tsx # Reporting interface
├── Sales.tsx # Sales/invoicing page
├── Settings.tsx # Application settings
└── Vehicles.tsx # Vehicle fleet management
Pages are container components that compose smaller components and hooks. They handle routing-level concerns.
/src/store/ - State Management
Redux Toolkit with Redux Saga for global state:
store/
├── slices/ # Redux Toolkit slices
├── index.ts # Store configuration and export
└── rootSaga.ts # Root saga combining all sagas
The store uses:
Redux Toolkit for simplified Redux logic
Redux Saga for side effects (async operations)
Redux Persist for persistence to LocalForage
Example store setup (src/main.tsx:9-16):
< Provider store = { store } >
< PersistGate loading = { null } persistor = { persistor } >
< App />
</ PersistGate >
</ Provider >
/src/data/ - Data Layer
Data management including mock data and database interface:
data/
├── mock/ # Mock data for development
│ ├── branches.ts
│ ├── company.ts
│ ├── customers.ts
│ ├── documentSeries.ts
│ ├── products.ts
│ ├── saleDetails.ts
│ ├── sales.ts
│ ├── users.ts
│ ├── vehicleUsualProducts.ts
│ └── vehicles.ts
└── db.ts # Database interface/abstraction
Mock data is used during development. In production, this will be replaced with actual API calls.
/src/constants/ - Application Constants
Shared constants and enumerations:
constants/
├── reports/
│ └── reports.ts # Report types and configurations
└── roles/
└── roles.ts # User roles and permissions
Example usage:
import { UserRole } from '@constants/roles/roles' ;
const newUser : User = {
rol: UserRole . OWNER ,
// ...
};
/src/routes/ - Routing Configuration
React Router configuration and route definitions:
routes/
└── [route configuration files]
Routing structure:
/ - Home dashboard
/vehicles - Vehicle management
/products - Product catalog
/clients - Customer database
/sales - Billing and invoices
/reports - Analytics and reports
/settings - App configuration
/src/services/ - External Services
API integrations and external service clients:
services/
└── [service modules]
This will include:
SUNAT electronic billing API
Decolecta validation API (RUC/DNI)
Backend API client (when available)
/src/styles/ - Styling
CSS modules and styling utilities:
styles/
├── modules/ # CSS modules for components
└── [global styles]
The project uses:
TailwindCSS for utility classes
CSS Modules for component-scoped styles
Example from MainLayout.tsx:3:
import styles from "../../styles/modules/main-layout.module.css" ;
/src/assets/ - Static Assets
Images, logos, and other media:
assets/
└── logo-empresa.png
Referenced in components:
< img src = "/assets/logo-empresa.png" alt = "Company Logo" />
/src/ui/ - UI Utilities
Icon components and other UI utilities:
ui/
└── icons/ # Icon components
The project primarily uses Lucide React for icons.
File Naming Conventions
PascalCase for component files: Button.tsx, CustomerFormModal.tsx
Component name matches filename
Use .tsx extension for components with JSX
// Button.tsx
export const Button = ({ ... }) => { ... }
camelCase with use prefix: useAuth.ts, useCustomers.ts
Use .ts extension (no JSX in hooks)
// useAuth.ts
export const useAuth = () => { ... }
PascalCase for type/interface names
Colocated with the component/hook that uses them
interface ButtonProps {
variant ?: "primary" | "secondary" ;
// ...
}
SCREAMING_SNAKE_CASE for true constants
PascalCase for enums
export const MAX_ITEMS_PER_PAGE = 100 ;
export enum UserRole {
OWNER = 'owner' ,
ADMIN = 'admin' ,
}
kebab-case with .module.css suffix
Matches component name: main-layout.module.css
/* main-layout.module.css */
.layoutContainer { ... }
.sidebar { ... }
Import Path Aliases
The project uses TypeScript path aliases for cleaner imports:
Alias Path Usage @/src/Root source directory @components/src/components/Component imports @pages/src/pages/Page components @hooks/src/hooks/Custom hooks @store/src/store/Redux store @services/src/services/API services @constants/src/constants/Constants and enums @data/src/data/Data layer @styles/src/styles/Styles and CSS modules @icons/src/ui/icons/Icon components @assets/src/assets/Static assets
Example Imports
// Using path aliases
import { Button } from '@components/ui/Button' ;
import { useAuth } from '@hooks/useAuth' ;
import { db } from '@data/db' ;
import { UserRole } from '@constants/roles/roles' ;
import styles from '@styles/modules/main-layout.module.css' ;
// Instead of relative paths
import { Button } from '../../../components/ui/Button' ;
import { useAuth } from '../../hooks/useAuth' ;
Architecture Patterns
Component Composition
Pages compose smaller components:
// pages/Customers.tsx
import { CustomerFormModal } from '@components/customers/CustomerFormModal' ;
import { Button } from '@components/ui/Button' ;
import { useCustomers } from '@hooks/useCustomers' ;
export const Customers = () => {
const { openModal } = useCustomers ();
return (
< div >
< Button onClick = {() => openModal ( 'add' )} > Add Customer </ Button >
< CustomerFormModal />
</ div >
);
};
Hooks for Business Logic
Custom hooks encapsulate state and logic:
// hooks/useCustomers.ts
export const useCustomers = () => {
const [ activeModal , setActiveModal ] = useState < ModalType >( null );
const openModal = ( type : ModalType ) => {
setActiveModal ( type );
};
return { activeModal , openModal };
};
Container/Presentational Pattern
Pages = Container components (smart, connected to state)
UI Components = Presentational components (dumb, pure)
Code Organization Best Practices
Colocation Keep related files close together. If a component has a specific hook or style, keep them in the same directory.
Single Responsibility Each file should have one clear purpose. Avoid large multi-purpose files.
Consistent Naming Follow naming conventions strictly. This makes the codebase predictable and easier to navigate.
Path Aliases Always use path aliases instead of relative imports. This prevents fragile import paths.
Next Steps