SmarMaker - Documentation
Docs» 15_training:module5-architecture-smartmaker:structure-projet

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

snippet.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

snippet.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

snippet.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

snippet.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

snippet.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

snippet.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

snippet.javascript
// components/app/Router/Guards/index.jsx
import { Outlet, Navigate } from 'react-router-dom';
import { useGlobalStates } from '@cap-rel/smartcommon';
 
export const PrivateRoutes = () => {
    const [session] = useGlobalStates('session');
    return session ? <Outlet /> : <Navigate to="/login" />;
};
 
export const PublicRoutes = () => {
    const [session] = useGlobalStates('session');
    return session ? <Navigate to="/" /> : <Outlet />;
};

Variables d'environnement

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

Accès dans le code :

snippet.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 | Chapitre suivant : Configuration →

Previous Next

Made with ❤ by CAP-REL · SmartMaker · GNU AGPL v3+
Code source · Faire un don
SmarMaker - Documentation
Traductions de cette page:
  • Français
  • Deutsch
  • English
  • Español
  • Italiano
  • Nederlands

Table of Contents

Table des matières

  • Chapitre 1 : Structure du projet
    • Vue d'ensemble
    • Arborescence complète
    • Détail des fichiers clés
      • main.jsx - Point d'entrée
      • App.jsx - Composant racine
      • appConfig.js - Configuration
      • index.html - Template
    • Organisation des composants
      • Structure recommandée pour une page
      • Exemple de page
    • Le Router
      • Configuration des routes
      • Guards d'authentification
    • Variables d'environnement
    • Dossier pwa/ - Production
    • Points clés à retenir
  • SmartAuth
  • SmartMaker - Back (PHP)
    • Mapping Dolibarr - React
  • SmartMaker - Front (React)
    • Animations de pages
    • Architecture
    • Astuces
    • Calendar
    • Composants et pages
    • Configuration du Provider
    • Debug et Logs
    • Hooks SmartCommon
    • PWA (Progressive Web App)
    • Requêtes API
    • Routage
    • SmartCommon
    • Stockage de données
    • Thèmes
    • Traductions
  • HowTo - Pas à pas - Votre première application
    • Développement PHP (back)
    • Développement React (front)
    • Première étape : Module Builder Dolibarr
    • SmartAuth
    • SmartBoot : Un "squelette" quasiment prêt à l'emploi
  • Formation SmartMaker
    • Module 1 : Fondamentaux JavaScript ES6+
      • Chapitre 1 : Variables et Scope
      • Chapitre 2 : Fonctions
      • Chapitre 3 : Programmation Asynchrone
      • Chapitre 4 : Modules ES6
    • Module 2 : Introduction à React
      • Chapitre 1 : Philosophie React
      • Chapitre 2 : JSX
      • Chapitre 3 : Composants
    • Module 3 : Hooks React Fondamentaux
      • Chapitre 1 : useState
      • Chapitre 2 : useEffect
      • Chapitre 3 : useRef
      • Chapitre 4 : useContext
    • Module 4 : React Avancé
      • Chapitre 1 : useCallback et useMemo
      • Chapitre 2 : Custom Hooks
      • Chapitre 3 : Redux et Redux Toolkit
    • Module 5 : Architecture SmartMaker
      • Chapitre 1 : Structure du projet
      • Chapitre 2 : Configuration
      • Chapitre 3 : Flux de données
    • Module 6 : SmartCommon - Composants
      • Chapitre 1 : Mise en page
      • Chapitre 2 : Navigation
      • Chapitre 3 : Formulaires
      • Chapitre 4 : Affichage
    • Module 7 : SmartCommon - Hooks
      • Chapitre 1 : useApi
      • Chapitre 2 : Gestion d'état
      • Chapitre 3 : Hooks utilitaires
    • Module 8 : Backend API (PHP)
      • Chapitre 1 : Routage
      • Chapitre 2 : Controllers
      • Chapitre 3 : Mappers
      • Extrafields et formulaires dynamiques
    • Module 9 : Intégration complète
      • Chapitre 1 : Backend
      • Chapitre 2 : Frontend
      • Chapitre 3 : Déploiement
    • Module 10 : Fonctionnalités avancées
      • Chapitre 1 : Mode offline
      • Chapitre 2 : Internationalisation (i18n)
      • Chapitre 3 : Autres fonctionnalités
    • Module 11 : Bonnes pratiques
  • Démonstration
  • Start
  • Composants et pages
  • Afficher le texte source
  • Anciennes révisions
  • Liens de retour
  • Haut de page