---
title: "Chapitre 1 : Structure du projet"
weight: 490
---

# Chapitre 1 : Structure du projet

## Vue d'ensemble

Un projet SmartMaker se compose de deux parties :

1. **mobile/** : Code source React (développement)
2. **pwa/** : Application compilée + API PHP (production)

## Arborescence complète

```
monmodule/                          # Module Dolibarr
├── mobile/                         # CODE SOURCE REACT
│   ├── src/
│   │   ├── App.jsx                # Composant racine
│   │   ├── main.jsx               # Point d'entrée
│   │   ├── appConfig.js           # Configuration
│   │   ├── components/
│   │   │   ├── app/
│   │   │   │   └── Router/        # Configuration routes
│   │   │   │       ├── index.jsx
│   │   │   │       └── Guards/    # Protection routes
│   │   │   └── pages/
│   │   │       ├── public/        # Pages sans auth
│   │   │       │   ├── LoginPage/
│   │   │       │   └── WelcomePage/
│   │   │       ├── private/       # Pages avec auth
│   │   │       │   ├── HomePage/
│   │   │       │   └── ItemPage/
│   │   │       └── errors/
│   │   │           └── Error404Page/
│   │   ├── redux/                 # Store Redux (optionnel)
│   │   │   └── reducers/
│   │   ├── i18n/                  # Configuration i18next
│   │   ├── utils/                 # Helpers, constantes
│   │   └── locales/               # Fichiers de traductions
│   ├── public/
│   │   ├── images/                # Icônes PWA
│   │   └── locales/               # Traductions
│   ├── index.html                 # Template HTML
│   ├── package.json               # Dépendances npm
│   ├── vite.config.js             # Configuration Vite
│   └── .env                       # Variables d'environnement
│
├── pwa/                           # APPLICATION COMPILÉE + API
│   ├── api.php                    # Point d'entrée API
│   └── dist/                      # Fichiers React compilés
│
├── smartmaker-api/                # BACKEND PHP
│   ├── Controllers/               # Logique métier
│   └── Mappers/                   # Conversion Dolibarr -> DTO
│
└── smartmaker-api-prepend.php     # Bootstrap PHP
```

## Détail des fichiers clés

### main.jsx - Point d'entrée

```javascript
// src/main.jsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './App';
import './index.css';

createRoot(document.getElementById('root')).render(
    <StrictMode>
        <App />
    </StrictMode>
);
```

C'est le fichier appelé par `index.html`. Il monte l'application React dans le DOM.

### App.jsx - Composant racine

```javascript
// src/App.jsx
import { Provider } from '@cap-rel/smartcommon';
import { Router } from './components/app/Router';
import { config } from './appConfig';

export const App = () => (
    <Provider config={config}>
        <Router />
    </Provider>
);
```

Le `Provider` de SmartCommon englobe toute l'application et fournit :

- Configuration globale
- État Redux
- Contexte API
- i18next

### appConfig.js - Configuration

```javascript
// src/appConfig.js
export const config = {
    debug: import.meta.env.DEV,

    api: {
        prefixUrl: import.meta.env.VITE_API_URL,
        timeout: 30000,
        paths: {
            login: "login",
            logout: "logout",
            refresh: "refresh"
        }
    },

    storage: {
        local: ["session", "settings"]
    },

    globalState: {
        reducers: {
            session: null,
            settings: { lng: "fr" },
            items: []
        }
    },

    pages: {
        "/": { "/settings": "slideLeft", "*": "fade" },
        "*": "fade"
    }
};
```

Détaillé dans le chapitre suivant.

### index.html - Template

```html
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Mon Application</title>
</head>
<body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
</body>
</html>
```

Vite injecte automatiquement les scripts compilés en production.

## Organisation des composants

### Structure recommandée pour une page

```
components/pages/private/ItemPage/
├── index.jsx           # Composant principal
├── ItemPage.module.css # Styles (optionnel)
└── components/         # Sous-composants locaux (optionnel)
    ├── ItemHeader.jsx
    └── ItemActions.jsx
```

### Exemple de page

```javascript
// components/pages/private/ItemPage/index.jsx
import { useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { Page, Block, Spinner } from '@cap-rel/smartcommon';
import { useApi, useStates } from '@cap-rel/smartcommon';

export const ItemPage = () => {
    const { id } = useParams();
    const api = useApi();

    const st = useStates({
        initialStates: {
            item: null,
            loading: true,
            error: null
        }
    });

    useEffect(() => {
        const fetchItem = async () => {
            try {
                const data = await api.private.get(`items/${id}`).json();
                st.set('item', data);
            } catch (err) {
                st.set('error', err.message);
            } finally {
                st.set('loading', false);
            }
        };
        fetchItem();
    }, [id]);

    if (st.get('loading')) {
        return <Page><Spinner /></Page>;
    }

    if (st.get('error')) {
        return <Page><Block>Erreur : {st.get('error')}</Block></Page>;
    }

    const item = st.get('item');

    return (
        <Page title={item.label}>
            <Block>
                <p>{item.description}</p>
            </Block>
        </Page>
    );
};
```

## Le Router

### Configuration des routes

```javascript
// components/app/Router/index.jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { PublicRoutes, PrivateRoutes } from './Guards';

// Pages
import { LoginPage } from '../../pages/public/LoginPage';
import { HomePage } from '../../pages/private/HomePage';
import { ItemPage } from '../../pages/private/ItemPage';
import { Error404Page } from '../../pages/errors/Error404Page';

export const Router = () => {
    return (
        <BrowserRouter>
            <Routes>
                {/* Routes publiques */}
                <Route element={<PublicRoutes />}>
                    <Route path="/login" element={<LoginPage />} />
                </Route>

                {/* Routes protégées */}
                <Route element={<PrivateRoutes />}>
                    <Route path="/" element={<HomePage />} />
                    <Route path="/items/:id" element={<ItemPage />} />
                </Route>

                {/* Fallback */}
                <Route path="*" element={<Error404Page />} />
            </Routes>
        </BrowserRouter>
    );
};
```

### Guards d'authentification

```javascript
// components/app/Router/Guards/index.jsx
import { Outlet, Navigate } from 'react-router-dom';
import { useGlobalStates } from '@cap-rel/smartcommon';

export const PrivateRoutes = () => {
    const gst = useGlobalStates();
    return gst.get('session') ? <Outlet /> : <Navigate to="/login" />;
};

export const PublicRoutes = () => {
    const gst = useGlobalStates();
    return gst.get('session') ? <Navigate to="/" /> : <Outlet />;
};
```

## Variables d'environnement

```bash
# .env
VITE_API_URL=https://mondomaine.com/modules/monmodule/pwa/api.php
```

Accès dans le code :

```javascript
const apiUrl = import.meta.env.VITE_API_URL;
const isDev = import.meta.env.DEV;
const isProd = import.meta.env.PROD;
```

**Important** : Les variables doivent commencer par `VITE_` pour être exposées au client.

## Dossier pwa/ - Production

Après compilation (`npm run build`), les fichiers sont générés dans `pwa/dist/` :

```
pwa/
├── api.php           # Point d'entrée API (à créer)
└── dist/
    ├── index.html    # HTML avec assets injectés
    ├── assets/
    │   ├── index-abc123.js   # Bundle JS
    │   └── index-def456.css  # Bundle CSS
    └── images/
```

## Points clés à retenir

1. **mobile/** = code source pour développement
2. **pwa/** = code compilé pour production
3. **App.jsx** englobe tout avec le Provider SmartCommon
4. **appConfig.js** centralise la configuration
5. **Router** gère les routes avec guards d'authentification
6. Variables d'environnement préfixées par **VITE_**

[← Retour au module](/training/module5-architecture-smartmaker) | [Chapitre suivant : Configuration ->](/training/module5-architecture-smartmaker/configuration)
