Skip to main content

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:
AliasPathUsage
@/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

Build docs developers (and LLMs) love