---
title: "Chapitre 1 : Mise en page"
weight: 530
---

# Chapitre 1 : Mise en page

## Page

Le composant `Page` est le conteneur principal de chaque écran. Il gère :

- Le titre de la page
- Les animations de transition
- Le scroll

### Syntaxe de base

```javascript
import { Page } from '@cap-rel/smartcommon';

function HomePage() {
    return (
        <Page title="Accueil">
            <p>Contenu de la page</p>
        </Page>
    );
}
```

### Props principales

| Prop | Type | Défaut | Description |
| --- | --- | --- | --- |
| title | string | - | Titre affiché dans la navbar |
| subtitle | string | - | Sous-titre optionnel |
| className | string | - | Classes CSS additionnelles |
| onRefresh | function | - | Callback pour pull-to-refresh |

### Page avec refresh

```javascript
function ItemsPage() {
    const [items, setItems] = useState([]);

    const handleRefresh = async () => {
        const data = await api.private.get('items').json();
        setItems(data);
    };

    return (
        <Page title="Mes items" onRefresh={handleRefresh}>
            {items.map(item => (
                <div key={item.id}>{item.label}</div>
            ))}
        </Page>
    );
}
```

## Block

Le composant `Block` structure le contenu en sections visuelles distinctes.

### Syntaxe de base

```javascript
import { Page, Block } from '@cap-rel/smartcommon';

function ProfilePage() {
    return (
        <Page title="Profil">
            <Block>
                <h2>Informations personnelles</h2>
                <p>Nom : Jean Dupont</p>
            </Block>

            <Block>
                <h2>Préférences</h2>
                <p>Langue : Français</p>
            </Block>
        </Page>
    );
}
```

### Props

| Prop | Type | Défaut | Description |
| --- | --- | --- | --- |
| title | string | - | Titre du block |
| className | string | - | Classes CSS additionnelles |
| padding | boolean | true | Ajouter du padding interne |

### Block avec titre

```javascript
<Block title="Informations">
    <p>Contenu du block</p>
</Block>
```

## Panel

Le composant `Panel` affiche un panneau coulissant depuis le côté de l'écran.

### Syntaxe

```javascript
import { useState } from 'react';
import { Page, Block, Button, Panel } from '@cap-rel/smartcommon';

function MyPage() {
    const [isPanelOpen, setIsPanelOpen] = useState(false);

    return (
        <Page title="Ma page">
            <Block>
                <Button onClick={() => setIsPanelOpen(true)}>
                    Ouvrir le panneau
                </Button>
            </Block>

            <Panel
                isOpen={isPanelOpen}
                onClose={() => setIsPanelOpen(false)}
                position="right"
            >
                <h2>Contenu du panneau</h2>
                <p>Informations supplémentaires</p>
            </Panel>
        </Page>
    );
}
```

### Props

| Prop | Type | Défaut | Description |
| --- | --- | --- | --- |
| isOpen | boolean | false | Contrôle l'affichage |
| onClose | function | - | Callback à la fermeture |
| position | string | 'right' | 'left', 'right', 'top', 'bottom' |
| title | string | - | Titre du panneau |

## Popup

Le composant `Popup` affiche une fenêtre modale centrée.

### Syntaxe

```javascript
import { useState } from 'react';
import { Page, Block, Button, Popup } from '@cap-rel/smartcommon';

function MyPage() {
    const [isPopupOpen, setIsPopupOpen] = useState(false);

    return (
        <Page title="Ma page">
            <Block>
                <Button onClick={() => setIsPopupOpen(true)}>
                    Supprimer
                </Button>
            </Block>

            <Popup
                isOpen={isPopupOpen}
                onClose={() => setIsPopupOpen(false)}
                title="Confirmation"
            >
                <p>Voulez-vous vraiment supprimer cet élément ?</p>
                <div className="flex gap-2 mt-4">
                    <Button onClick={() => setIsPopupOpen(false)}>
                        Annuler
                    </Button>
                    <Button variant="danger" onClick={handleDelete}>
                        Supprimer
                    </Button>
                </div>
            </Popup>
        </Page>
    );
}
```

### Props

| Prop | Type | Défaut | Description |
| --- | --- | --- | --- |
| isOpen | boolean | false | Contrôle l'affichage |
| onClose | function | - | Callback à la fermeture |
| title | string | - | Titre du popup |
| closeOnOverlay | boolean | true | Fermer au clic sur l'overlay |

## Exemple complet

```javascript
import { useState } from 'react';
import {
    Page,
    Block,
    Panel,
    Popup,
    Button,
    List,
    ListItem
} from '@cap-rel/smartcommon';

export const ProductsPage = () => {
    const [selectedProduct, setSelectedProduct] = useState(null);
    const [showDeletePopup, setShowDeletePopup] = useState(false);
    const [showFilters, setShowFilters] = useState(false);

    const products = [
        { id: 1, label: 'Produit A', price: 29.99 },
        { id: 2, label: 'Produit B', price: 49.99 },
        { id: 3, label: 'Produit C', price: 19.99 }
    ];

    const handleDelete = async () => {
        // Supprimer le produit
        console.log('Suppression de', selectedProduct);
        setShowDeletePopup(false);
        setSelectedProduct(null);
    };

    return (
        <Page title="Produits">
            {/* Actions */}
            <Block>
                <Button onClick={() => setShowFilters(true)}>
                    Filtres
                </Button>
            </Block>

            {/* Liste */}
            <Block title="Catalogue">
                <List>
                    {products.map(product => (
                        <ListItem
                            key={product.id}
                            title={product.label}
                            subtitle={`${product.price} €`}
                            onClick={() => setSelectedProduct(product)}
                            actions={
                                <Button
                                    size="sm"
                                    variant="danger"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        setSelectedProduct(product);
                                        setShowDeletePopup(true);
                                    }}
                                >
                                    Supprimer
                                </Button>
                            }
                        />
                    ))}
                </List>
            </Block>

            {/* Panneau filtres */}
            <Panel
                isOpen={showFilters}
                onClose={() => setShowFilters(false)}
                title="Filtres"
                position="right"
            >
                <p>Options de filtrage ici</p>
            </Panel>

            {/* Popup confirmation */}
            <Popup
                isOpen={showDeletePopup}
                onClose={() => setShowDeletePopup(false)}
                title="Confirmer la suppression"
            >
                <p>
                    Supprimer "{selectedProduct?.label}" ?
                </p>
                <div className="flex gap-2 mt-4">
                    <Button onClick={() => setShowDeletePopup(false)}>
                        Annuler
                    </Button>
                    <Button variant="danger" onClick={handleDelete}>
                        Supprimer
                    </Button>
                </div>
            </Popup>
        </Page>
    );
};
```

## Bonnes pratiques

1. **Une seule Page par composant de route**
2. **Utiliser Block pour regrouper** le contenu logiquement
3. **Panel pour les actions secondaires** (filtres, détails)
4. **Popup pour les confirmations** et actions critiques

## Points clés à retenir

1. **Page** = conteneur principal avec titre et animations
2. **Block** = section de contenu avec style
3. **Panel** = panneau coulissant latéral
4. **Popup** = modal centré pour confirmations

[← Retour au module](/training/module6-smartcommon-composants) | [Chapitre suivant : Navigation ->](/training/module6-smartcommon-composants/navigation)
