---
title: "Interface publique en React (PWA)"
weight: 5
description: "Présentation et configuration de la nouvelle interface publique de prise de commande, introduite en version 2.0."
---

# Interface publique en React (PWA)

Depuis la version 2.0 du module, la prise de commande en ligne se fait via une **PWA** (Progressive Web App) écrite en React. Cette interface remplace l'ancien parcours basé sur TakePOS pour l'usage public, tout en conservant `phone.php` / `invoice.php` pour les bornes physiques en magasin.

## Vue d'ensemble du parcours client

1. Le client ouvre l'URL publique du module : `/custom/clickncollect/public/`.
2. Le serveur vérifie que la prise de commande est activée (`CLICKNCOLLECT_ONLINE_ORDER_ENABLED`) et que le magasin est ouvert selon le calendrier (`CLICKNCOLLECT_ORDER_CALENDAR`). Si ce n'est pas le cas, il redirige vers `CLICKNCOLLECT_REDIRECT_ORDER_CLOSED` (ou affiche un message d'attente si la redirection n'est pas configurée).
3. Sinon, le navigateur est redirigé vers `/custom/clickncollect/pwa/index.html` qui charge la PWA.
4. La PWA appelle l'API REST (`/custom/clickncollect/pwa/api.php`) pour le catalogue, les créneaux, le panier, la commande et le paiement.
5. Au moment du paiement, un nouvel onglet ouvre `newpayment.php` (système de paiement Dolibarr standard). La PWA reste en arrière-plan, polle le statut toutes les 3 secondes et bascule sur l'écran "Payée" dès que Dolibarr enregistre le règlement.

### Le parcours en images

La carte affiche les catégories de produits exposées au public :

![La carte de la boutique en ligne : catégories de produits et tarifs](screenshots/pwa-catalogue.webp)

Chaque fiche produit permet de choisir la quantité et, si le produit en propose, des options comme la sauce :

![Fiche produit avec choix d'une option (sauce à part) avant ajout au panier](screenshots/pwa-produit-options.webp)

Le panier liste les articles retenus, leurs options et le total :

![Le panier avec ses articles, leurs options et le bouton Commander](screenshots/pwa-panier.webp)

La prise de commande commence par les coordonnées du client :

![Écran de finalisation de commande : saisie des coordonnées du client](screenshots/pwa-commande-coordonnees.webp)

Puis le choix du créneau de retrait, limité aux horaires configurés :

![Choix de la date et du créneau de retrait avec le récapitulatif de la commande](screenshots/pwa-commande-creneau.webp)

Après validation, la page de suivi affiche la commande et le bouton de paiement :

![Page de suivi de commande : référence, créneau de retrait, articles et bouton de paiement](screenshots/pwa-suivi-commande.webp)

## URL publiques

| URL | Rôle |
|-----|------|
| `/custom/clickncollect/public/` | Point d'entrée client. Vérifie la disponibilité puis redirige vers la PWA. |
| `/custom/clickncollect/pwa/` | PWA React (servie statiquement). |
| `/custom/clickncollect/pwa/api.php` | API REST publique (catalogue, créneaux, commande, paiement). |
| `/custom/clickncollect/pwa/api.php?route=shop/status` | Endpoint utilisé par la PWA pour savoir si le magasin est ouvert. |

## Configuration

Les options pertinentes pour la PWA, gérées depuis l'admin Dolibarr :

| Constante | Effet |
|-----------|-------|
| `CLICKNCOLLECT_ONLINE_ORDER_ENABLED` | Active ou désactive la prise de commande en ligne. |
| `CLICKNCOLLECT_ORDER_CALENDAR` | Active la grille horaire (sinon le magasin est considéré comme toujours ouvert). |
| `CLICKNCOLLECT_ORDER_CALENDAR_DAYS` | Plages d'ouverture pour la prise de commande (format : `1@8h0:1@22h0,2@8h0:2@22h0,...`). |
| `CLICKNCOLLECT_OPEN_CALENDAR_DAYS` | Plages d'ouverture pour le retrait. |
| `CLICKNCOLLECT_DELAY_ORDER_PROD` | Délai minimum (en minutes) entre la commande et le créneau de retrait proposé. |
| `CLICKNCOLLECT_REDIRECT_ORDER_CLOSED` | URL vers laquelle rediriger les visiteurs quand le magasin est fermé. |
| `CLICKNCOLLECT_ROOT_CATEGORY` | Catégorie de produits Dolibarr exposée dans la carte (les produits doivent y être rattachés). |
| `CLICKNCOLLECT_CUSTOMER_CATEGORY` | Catégorie tiers à laquelle les nouveaux clients web sont automatiquement rattachés. |
| `CLICKNCOLLECT_ENABLE_PSEUDO_STOCK` | Active la gestion du pseudo-stock par jour (recommandé). |

Voir aussi la page [Horaires de vente en ligne](/clickncollect/horaires-vente-en-ligne) pour le format détaillé du calendrier.

## Multilingue (options produits)

Les options des produits (cuisson, sauce, taille...) sont stockées dans la table `c_clickncollect_var` avec les colonnes `code` (identifiant interne, jamais traduit) et `label` (libellé affiché par défaut).

Pour proposer la PWA dans plusieurs langues, ajoutez les traductions correspondantes dans `langs/<code-langue>/clickncollect.lang` en utilisant la valeur de `code` ou `categ` comme clé. L'API renvoie automatiquement le libellé localisé via `$langs->trans()`, avec retour sur `label` quand aucune traduction n'est définie.

Exemple :

```ini
# langs/fr_FR/clickncollect.lang
COOKING_RARE = Saignant
COOKING_MEDIUM = À point
COOKING_WELL_DONE = Bien cuit
```

avec dans `c_clickncollect_var` :

| code              | categ    | label    |
|-------------------|----------|----------|
| COOKING_RARE      | COOKING  | Saignant |
| COOKING_MEDIUM    | COOKING  | À point  |
| COOKING_WELL_DONE | COOKING  | Bien cuit|

## Personnalisation visuelle

La PWA suit le manifeste fourni par le module SmartAuth (en s'appuyant sur des constantes Dolibarr). Voir la documentation SmartAuth pour les variables `*_PWA_NAME`, `*_PWA_THEME_COLOR`, `*_PWA_BACKGROUND_COLOR`, etc.

Le panier est sauvegardé dans la base **IndexedDB** du navigateur (store `cart` de la base nommée d'après `VITE_APP_NAME`), via la classe `Db` de SmartCommon (wrapper Dexie). Le versioning du schéma est géré par Dexie (`db.version(N)`) : lorsqu'on incrémente la version, Dexie applique automatiquement la migration, sans avoir à purger côté navigateur.

## Limites par sécurité

Les endpoints publics `POST /customer` et `POST /order` sont **rate-limités par IP** (10 créations clients / 5 min, 5 commandes / 5 min) via la classe `SmartAuth\Api\RateLimiter`. Au-delà, l'API renvoie un code HTTP 429 avec un délai à attendre.

## Reprise de l'ancien flow TakePOS

Pour les bornes physiques en magasin, l'ancien parcours TakePOS reste accessible directement via les URL `/custom/clickncollect/phone.php?...` et `/custom/clickncollect/invoice.php?...`. Aucune modification n'est nécessaire de ce côté ; la PWA et les bornes coexistent.
