npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@graphiboxdev/app-shopping-cart

v1.2.52

Published

Shopping cart module for Autopartspro

Readme

@graphiboxdev/app-shopping-cart

Module Nuxt 4 — panier d'achat et tunnel de commande pour l'écosystème Autopartspro.

Nuxt 4 module — shopping cart and checkout flow for the Autopartspro ecosystem.


Navigation rapide / Quick navigation


Français

Présentation

@graphiboxdev/app-shopping-cart est un module Nuxt 4 clé-en-main qui fournit un panier d'achat complet et un tunnel de commande pour les applications Autopartspro.

Fonctionnalités principales :

  • Panier invité et connecté — persistance via localStorage / sessionStorage pour les visiteurs non connectés, migration automatique vers le panier serveur à la connexion.
  • Tunnel de commande 4 étapes — livraison → paiement → récapitulatif → confirmation, avec navigation et validation par étape.
  • Tarification HT/TTC — calcul des montants hors taxe et toutes taxes comprises, support multi-devise et multi-locale.
  • Consignes — gestion des articles à consigne (bouteilles, contenants) incluse dans les totaux.
  • Informations véhicule — association de plaque d'immatriculation et données véhicule par article.
  • Intégration ERP — envoi optionnel des commandes vers un système ERP tiers.
  • Passerelle bancaire — paiement par carte bancaire via une passerelle dédiée.
  • SSR — hydratation correcte côté serveur via onServerPrefetch.
  • 16 composants UI — basés sur Nuxt UI v4 et Tailwind CSS v4, responsive, mode sombre inclus.

Installation

npm install @graphiboxdev/app-shopping-cart

Ajouter le module dans nuxt.config.ts :

export default defineNuxtConfig({
  modules: ['@graphiboxdev/app-shopping-cart'],
})

Prérequis

| Dépendance | Version minimale | Rôle | |---|---|---| | Nuxt | ^4.0.0 | Framework requis | | @nuxt/ui | ^4.0.0 | Composants UI (requis pour les composants visuels) | | Tailwind CSS | ^4.0.0 | Styles (configuré automatiquement par le module) | | Node.js | LTS | Environnement d'exécution |

Le module injecte automatiquement une directive @source pour ses composants dans la feuille de style racine Tailwind de l'application (celle qui contient @import "tailwindcss"), via un plugin Vite. Aucune configuration Tailwind manuelle n'est nécessaire avec le pipeline Vite standard de Nuxt.

Si votre pipeline CSS ne passe pas par Vite (setup PostCSS pur), importez le fallback embarqué depuis cette même feuille racine :

@import "@graphiboxdev/app-shopping-cart/tailwind.css";

Configuration

Options du module (nuxt.config.ts)

export default defineNuxtConfig({
  modules: ['@graphiboxdev/app-shopping-cart'],

  graphiToolbox: {
    maxQuantity: 99,             // Quantité maximale par article (défaut : 99)
    persistence: 'localStorage', // 'localStorage' | 'sessionStorage' | 'none'
    checkout: {
      requireAccount: false,     // Forcer la connexion avant commande (défaut : false)
    },
  },
})

| Option | Type | Défaut | Description | |---|---|---|---| | maxQuantity | number | 99 | Quantité maximale par article | | persistence | 'localStorage' \| 'sessionStorage' \| 'none' | 'localStorage' | Mode de persistance panier invité | | checkout.requireAccount | boolean | false | Connexion obligatoire avant commande |

Configuration dynamique (runtime)

La configuration dynamique (devise, locale, endpoints API, identifiants client) est gérée via useBoxCartConfig() — un état global réactif mis à jour à l'exécution :

// Dans un plugin ou un layout
const cartConfig = useBoxCartConfig()

cartConfig.value = {
  currency: 'EUR',
  locale: 'fr-FR',
  isHt: true,                          // Affichage en HT (true) ou TTC (false)
  addToCartFeedback: 'slideover',       // Retour visuel à l'ajout : 'slideover' | 'toast' | 'none'
  addToCartModalAutoCloseDelay: 10000, // Délai de fermeture automatique en ms
  hidePurchasePrice: false,            // Masque les prix d'achat dans le retour visuel d'ajout
  email: '[email protected]',         // Email du client connecté
  establishmentId: 123,                // ID établissement
  entityId: 456,                       // ID entité
  api: {
    baseUrl: 'https://api.example.com',
    endpoints: {
      cart: {
        get: '/v3/cart/getCart',
        add: '/v3/cart/addProduct',
        update: '/v3/cart/updateProduct',
        delete: '/v3/cart/deleteProduct',
        kill: '/v3/cart/killCart',
      },
      bank: '/bank',
      order: '/orders',
      deliveries: '/deliveries',
      paymentMethods: '/payment-methods',
    },
  },
}

Synchronisation avec i18n :

const { locale } = useI18n()
const cartConfig = useBoxCartConfig()

watch(locale, (lang) => {
  cartConfig.value = {
    ...cartConfig.value,
    locale: lang,
    currency: lang === 'en' ? 'USD' : 'EUR',
  }
}, { immediate: true })

Utilisation rapide

Afficher le panier

<template>
  <BoxCart />
</template>

Ajouter un article au panier

const { addItem } = useBoxShoppingCart()

await addItem({
  id: 'REF-001',
  label: 'Filtre à huile',
  reference: 'FH-12345',
  quantity: 2,
  conditioning: 1,
  soldBy: 1,
  price: {
    ht: 12.50,
    ttc: 15.00,
    tva: 20,
  },
  stock: { available: true },
})

Formater un prix

const formatPrice = useBoxPriceFormatter()
formatPrice(19.99) // → '19,99 €'

Panier dans un panneau latéral

<template>
  <BoxCartSlideover />
</template>

Retour visuel à l'ajout au panier — slideover ou toast

<BoxCartAddedFeedback /> monte l'un ou l'autre selon addToCartFeedback (config panier), surchargeable par le prop mode :

<template>
  <!-- Suit la config : 'slideover' (défaut), 'toast' ou 'none' -->
  <BoxCartAddedFeedback
    show-checkout
    @checkout="navigateTo('/checkout')"
    @view-cart="navigateTo('/panier')"
    @continue-shopping="() => {}"
    @login-required="openLogin()"
  />
</template>

| Mode | Composant monté | Usage | | --- | --- | --- | | 'slideover' | <BoxCartSlideover /> | Panneau latéral : récapitulatif complet, article ajouté mis en évidence, quantités éditables, CTA commande | | 'toast' | <BoxCartAddedToast /> | Notification discrète : informe de l'ajout (visuel, référence, quantité, total panier) sans interrompre la navigation | | 'none' | — | Aucun retour visuel |

Le mode toast requiert <UApp /> à la racine de l'application (fournisseur de toasts Nuxt UI). Les ajouts successifs ne s'empilent pas : le toast en cours est complété avec le nouvel article, animé d'une pulsation, et son minuteur repart de zéro.

<template>
  <!-- Toast seul, sans passer par le wrapper -->
  <BoxCartAddedToast
    title="Ajouté à votre panier"
    :show-view-cart="true"
    :show-checkout="false"
    @view-cart="navigateTo('/panier')"
  />
</template>

Masquer les prix d'achathidePurchasePrice (config dynamique) retire le prix unitaire net, les remises et les totaux du retour visuel d'ajout (slideover et toast) ; seul le prix public reste affiché. Le reste du module (page panier, tunnel de commande) n'est pas concerné.

Le flag est réactif : un bouton de l'application peut le basculer, la fenêtre déjà ouverte se met à jour immédiatement.

<script setup lang="ts">
const cartConfig = useBoxCartConfig()

function togglePurchasePrices(): void {
  cartConfig.value.hidePurchasePrice = !cartConfig.value.hidePurchasePrice
}
</script>

<template>
  <UButton
    :icon="cartConfig.hidePurchasePrice ? 'i-heroicons-eye-slash' : 'i-heroicons-eye'"
    :label="cartConfig.hidePurchasePrice ? 'Afficher les prix d\'achat' : 'Masquer les prix d\'achat'"
    @click="togglePurchasePrices"
  />
</template>

Tunnel de commande

<template>
  <BoxOrderStepper />
</template>

API — Composables

Tous les composables sont auto-importés — aucun import explicite n'est nécessaire dans les composants ou pages.

useBoxCartConfig()

Retourne un Ref<BoxCartRuntimeConfig> — l'état global de configuration du module.

const cartConfig = useBoxCartConfig()
cartConfig.value.currency // 'EUR'
cartConfig.value.locale   // 'fr-FR'

useBoxPriceFormatter()

Retourne une fonction de formatage de prix basée sur la config courante.

const formatPrice = useBoxPriceFormatter()
formatPrice(1299.9) // '1 299,90 €'

useBoxShoppingCart()

État et opérations du panier.

const {
  items,              // Ref<CartItem[]> — articles du panier
  count,              // Ref<number> — nombre d'articles distincts
  quantity,           // Ref<number> — quantité totale
  totalHt,            // Ref<number> — total HT
  totalTtc,           // Ref<number> — total TTC
  totalVat,           // Ref<number> — total TVA
  weight,             // Ref<number> — poids total
  cartLoading,        // Ref<boolean> — état de chargement
  pricesLoading,      // Ref<boolean> — rafraîchissement des prix en cours
  isLogged,           // Ref<boolean> — utilisateur connecté

  isItemAdded,             // Ref<boolean> — un ajout vient d'avoir lieu (pilote le slideover)
  lastAddedItem,           // Ref<CartItem | null> — dernier article ajouté
  addToCartEventId,        // Ref<number> — incrémenté à chaque ajout (pilote le toast)
  cancelAddToCartAutoClose, // () => void — annule la fermeture automatique en attente

  addItem,            // (item: CartItem, mode?) => Promise<boolean>
  addItems,           // (items: CartItem[]) => Promise<boolean>
  deleteItem,         // (item: CartItem) => Promise<boolean>
  updateItemQuantity, // (item: CartItem, qty: number) => Promise<boolean>
  updateItemsPrices,  // (items: CartItem[]) => Promise<void> — maj des prix (ex: à la connexion)
  clearCart,          // () => Promise<void>
} = useBoxShoppingCart()

useBoxOrder()

État et navigation du tunnel de commande.

const {
  activeSteps,         // ComputedRef<CheckoutStep[]>
  currentStep,         // Ref<CheckoutStep>
  currentStepIndex,    // ComputedRef<number>
  isFirstStep,         // ComputedRef<boolean>
  isLastStep,          // ComputedRef<boolean>
  canGoNext,           // ComputedRef<boolean>

  selectedDelivery,    // Ref<DeliveryMethod | null>
  selectedPayment,     // Ref<PaymentMethod | null>
  summaryForm,         // Ref<{ comment: string, customerRef: string }>
  status,              // Ref<PaymentStatus>
  errorMessage,        // Ref<string>
  confirmationId,      // Ref<number | null>

  loadDeliveries,      // () => Promise<DeliveryMethod[]>
  loadPaymentMethods,  // () => Promise<PaymentMethod[]>
  selectDelivery,      // (method: DeliveryMethod) => void
  selectPayment,       // (method: PaymentMethod) => void
  goToStep,            // (step: CheckoutStep) => void
  nextStep,            // () => void
  prevStep,            // () => void
  submitOrder,         // (cartId: string, totalTtc: number) => Promise<void>
  resetOrder,          // () => void
} = useBoxOrder()

Types des étapes :

| Étape | Description | |---|---| | 'delivery' | Sélection du mode de livraison | | 'payment' | Sélection du moyen de paiement | | 'summary' | Récapitulatif et champs complémentaires | | 'confirmation' | Confirmation de commande |

Statuts de paiement (PaymentStatus) :

| Statut | Description | |---|---| | 'idle' | État initial | | 'pending' | Soumission en cours | | 'success' | Commande confirmée | | 'failed' | Erreur lors de la soumission | | 'refused' | Paiement refusé par la passerelle |


useBoxCartItemPrice(item)

Calcul des prix à l'article.

const { isHt, step, unitPrice, lineTotal } = useBoxCartItemPrice(item)
// step      → conditionnement (soldBy ou 1)
// unitPrice → prix unitaire selon mode HT/TTC
// lineTotal → total ligne = (unitPrice + consigne éventuelle) × quantity × soldBy

useBoxWsCart()

Appels HTTP vers le service panier (mapping interne ↔ API). Usage avancé — normalement consommé uniquement via useBoxShoppingCart().


useBoxWsBank()

Intégration passerelle bancaire.

const { createBankCheckout } = useBoxWsBank()
const result = await createBankCheckout(orderId, paymentMethodId, amountEuros)
// result → BankCheckoutResponse | null

API — Composants

Tous les composants sont auto-importés.

Composants panier

| Composant | Description | |---|---| | <BoxCart /> | Panier complet (tableau desktop + cartes mobile) | | <BoxCartItem /> | Article individuel du panier | | <BoxCartSkeleton /> | Squelette de chargement | | <BoxCartTotals /> | Bloc totaux (HT, TVA, TTC) | | <BoxCartProductImage /> | Image produit avec fallback | | <BoxCartVehicleInfo /> | Infos véhicule associé à un article | | <BoxCartDrawer /> | Panier en tiroir (drawer) | | <BoxCartSlideover /> | Panier en panneau latéral (slideover) | | <BoxCartAddedFeedback /> | Retour visuel à l'ajout : monte le slideover ou le toast selon addToCartFeedback | | <BoxCartAddedToast /> | Toast d'information « article ajouté » (Nuxt UI), sans empilement | | <BoxCartAddedToastBody /> | Contenu détaillé du toast (visuel, référence, quantité, totaux) |

Modales

| Composant | Description | |---|---| | <BoxCartLoginModal /> | Modale de connexion requise | | <BoxCartDeleteModal /> | Modale de confirmation de suppression | | <BoxCartClearModal /> | Modale de confirmation de vidage du panier |

Composants tunnel de commande

| Composant | Description | |---|---| | <BoxOrderStepper /> | Orchestrateur multi-étapes du tunnel | | <BoxOrderDeliveryStep /> | Étape sélection livraison | | <BoxOrderPaymentStep /> | Étape sélection paiement | | <BoxOrderSummaryStep /> | Étape récapitulatif et champs complémentaires | | <BoxOrderConfirmation /> | Page de confirmation finale |


API — Endpoints serveur

Le module expose les endpoints suivants via le serveur Nuxt (Nitro) :

| Méthode | Route | Description | |---|---|---| | GET | /api/_box/cart | Récupérer le panier | | POST | /api/_box/cart/addProduct | Ajouter un produit | | POST | /api/_box/cart/updateProduct | Modifier la quantité | | POST | /api/_box/cart/deleteProduct | Supprimer un produit | | POST | /api/_box/order | Soumettre une commande | | GET | /api/_box/order/deliveries | Récupérer les modes de livraison | | GET | /api/_box/order/payments | Récupérer les moyens de paiement | | POST | /api/_box/erp/order | Envoyer la commande à l'ERP | | POST | /api/_box/bank/checkout | Initier un paiement bancaire |

Ces routes sont des proxies vers l'API externe configurée dans useBoxCartConfig().api.


Bonnes pratiques

  • Initialiser useBoxCartConfig() tôt — dans un plugin Nuxt ou le layout racine, avant tout rendu du panier, avec les données utilisateur réelles (email, establishmentId, entityId).
  • Ne pas hardcoder les endpoints API dans nuxt.config.ts — utiliser useBoxCartConfig() pour les mettre à jour dynamiquement selon le contexte utilisateur.
  • Synchroniser avec i18n — mettre à jour locale et currency dans useBoxCartConfig() lors des changements de langue.
  • Mode HT vs TTC — configurer isHt selon le profil utilisateur (professionnel → HT, particulier → TTC).

Limites connues

  • Le module est conçu pour l'écosystème Autopartspro — certaines structures de données (consignes, infos véhicule, conditionnement) sont spécifiques à ce domaine.
  • La compatibilité est limitée à Nuxt ^4.0.0 < 5.0.0 — non compatible Nuxt 3.
  • Les endpoints serveur agissent comme des proxies : l'API externe doit être correctement configurée via useBoxCartConfig().
  • TODO: documenter le format exact des réponses d'erreur API pour la gestion d'erreur côté consommateur.

Contribution

Ce module est un package interne de l'écosystème Graphibox / Autopartspro.

# Installer les dépendances
npm install

# Préparer et lancer le playground
npm run dev

# Build
npm run prepack

# Tests
npm run test
npm run test:types

# Lint
npm run lint

Licence

MIT



English

Overview

@graphiboxdev/app-shopping-cart is a turnkey Nuxt 4 module providing a full-featured shopping cart and checkout flow for Autopartspro applications.

Key features:

  • Guest and authenticated cartlocalStorage / sessionStorage persistence for unauthenticated users, automatic migration to the server cart on login.
  • 4-step checkout flow — delivery → payment → summary → confirmation, with per-step navigation and validation.
  • HT/TTC pricing — pre-tax and tax-included amounts, multi-currency and multi-locale support.
  • Deposits (consignes) — deposit-item management included in totals.
  • Vehicle information — license plate and vehicle data associated per cart item.
  • ERP integration — optional order forwarding to a third-party ERP system.
  • Bank payment gateway — credit card payment via a dedicated gateway.
  • SSR — correct server-side hydration via onServerPrefetch.
  • 16 UI components — built on Nuxt UI v4 and Tailwind CSS v4, responsive with dark mode support.

Installation

npm install @graphiboxdev/app-shopping-cart

Add the module to nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@graphiboxdev/app-shopping-cart'],
})

Requirements

| Dependency | Minimum version | Role | |---|---|---| | Nuxt | ^4.0.0 | Required framework | | @nuxt/ui | ^4.0.0 | UI components (required for visual components) | | Tailwind CSS | ^4.0.0 | Styles (auto-configured by the module) | | Node.js | LTS | Runtime environment |

The module automatically injects a @source directive for its components into the app's Tailwind root stylesheet (the one containing @import "tailwindcss"), through a Vite plugin. No manual Tailwind configuration is needed with Nuxt's standard Vite pipeline.

If your CSS pipeline does not go through Vite (pure PostCSS setup), import the bundled fallback from that same root stylesheet:

@import "@graphiboxdev/app-shopping-cart/tailwind.css";

Configuration

Module options (nuxt.config.ts)

export default defineNuxtConfig({
  modules: ['@graphiboxdev/app-shopping-cart'],

  graphiToolbox: {
    maxQuantity: 99,             // Maximum quantity per item (default: 99)
    persistence: 'localStorage', // 'localStorage' | 'sessionStorage' | 'none'
    checkout: {
      requireAccount: false,     // Force login before checkout (default: false)
    },
  },
})

| Option | Type | Default | Description | |---|---|---|---| | maxQuantity | number | 99 | Maximum quantity per cart item | | persistence | 'localStorage' \| 'sessionStorage' \| 'none' | 'localStorage' | Guest cart persistence mode | | checkout.requireAccount | boolean | false | Require login before checkout |

Runtime configuration

Dynamic configuration (currency, locale, API endpoints, customer identifiers) is managed via useBoxCartConfig() — a global reactive state updated at runtime:

// In a Nuxt plugin or root layout
const cartConfig = useBoxCartConfig()

cartConfig.value = {
  currency: 'EUR',
  locale: 'fr-FR',
  isHt: true,                          // Display pre-tax (true) or tax-included (false)
  addToCartFeedback: 'slideover',       // Add-to-cart feedback: 'slideover' | 'toast' | 'none'
  addToCartModalAutoCloseDelay: 10000, // Auto-close delay in ms
  hidePurchasePrice: false,            // Hide purchase prices in the add-to-cart feedback
  email: '[email protected]',       // Logged-in customer email
  establishmentId: 123,                // Establishment ID
  entityId: 456,                       // Entity ID
  api: {
    baseUrl: 'https://api.example.com',
    endpoints: {
      cart: {
        get: '/v3/cart/getCart',
        add: '/v3/cart/addProduct',
        update: '/v3/cart/updateProduct',
        delete: '/v3/cart/deleteProduct',
        kill: '/v3/cart/killCart',
      },
      bank: '/bank',
      order: '/orders',
      deliveries: '/deliveries',
      paymentMethods: '/payment-methods',
    },
  },
}

Syncing with i18n:

const { locale } = useI18n()
const cartConfig = useBoxCartConfig()

watch(locale, (lang) => {
  cartConfig.value = {
    ...cartConfig.value,
    locale: lang,
    currency: lang === 'en' ? 'USD' : 'EUR',
  }
}, { immediate: true })

Quick start

Display the cart

<template>
  <BoxCart />
</template>

Add an item to the cart

const { addItem } = useBoxShoppingCart()

await addItem({
  id: 'REF-001',
  label: 'Oil filter',
  reference: 'FH-12345',
  quantity: 2,
  conditioning: 1,
  soldBy: 1,
  price: {
    ht: 12.50,
    ttc: 15.00,
    tva: 20,
  },
  stock: { available: true },
})

Format a price

const formatPrice = useBoxPriceFormatter()
formatPrice(19.99) // → '19.99 €' or '$19.99' depending on config

Cart in a slideover panel

<template>
  <BoxCartSlideover />
</template>

Add-to-cart feedback — slideover or toast

<BoxCartAddedFeedback /> mounts either one based on addToCartFeedback (cart config), overridable with the mode prop:

<template>
  <!-- Follows the config: 'slideover' (default), 'toast' or 'none' -->
  <BoxCartAddedFeedback
    show-checkout
    @checkout="navigateTo('/checkout')"
    @view-cart="navigateTo('/cart')"
    @continue-shopping="() => {}"
    @login-required="openLogin()"
  />
</template>

| Mode | Mounted component | Usage | | --- | --- | --- | | 'slideover' | <BoxCartSlideover /> | Side panel: full recap, added item highlighted, editable quantities, checkout CTA | | 'toast' | <BoxCartAddedToast /> | Discreet notification: confirms the add (image, reference, quantity, cart total) without interrupting browsing | | 'none' | — | No feedback |

Toast mode requires <UApp /> at the app root (Nuxt UI toast provider). Successive adds do not stack: the running toast is completed with the new item, pulses, and its timer restarts from zero.

<template>
  <!-- Toast on its own, without the wrapper -->
  <BoxCartAddedToast
    title="Added to your cart"
    :show-view-cart="true"
    :show-checkout="false"
    @view-cart="navigateTo('/cart')"
  />
</template>

Hiding purchase priceshidePurchasePrice (runtime config) removes the net unit price, the discounts and the totals from the add-to-cart feedback (slideover and toast); only the public price stays visible. The rest of the module (cart page, checkout flow) is unaffected.

The flag is reactive: an app-level button can toggle it and the already-open panel updates instantly.

<script setup lang="ts">
const cartConfig = useBoxCartConfig()

function togglePurchasePrices(): void {
  cartConfig.value.hidePurchasePrice = !cartConfig.value.hidePurchasePrice
}
</script>

<template>
  <UButton
    :icon="cartConfig.hidePurchasePrice ? 'i-heroicons-eye-slash' : 'i-heroicons-eye'"
    :label="cartConfig.hidePurchasePrice ? 'Show purchase prices' : 'Hide purchase prices'"
    @click="togglePurchasePrices"
  />
</template>

Checkout flow

<template>
  <BoxOrderStepper />
</template>

API — Composables

All composables are auto-imported — no explicit import needed in components or pages.

useBoxCartConfig()

Returns a Ref<BoxCartRuntimeConfig> — the module's global configuration state.

const cartConfig = useBoxCartConfig()
cartConfig.value.currency // 'EUR'
cartConfig.value.locale   // 'fr-FR'

useBoxPriceFormatter()

Returns a price formatting function based on the current config.

const formatPrice = useBoxPriceFormatter()
formatPrice(1299.9) // '1,299.90 €'

useBoxShoppingCart()

Cart state and operations.

const {
  items,              // Ref<CartItem[]> — cart items
  count,              // Ref<number> — number of distinct items
  quantity,           // Ref<number> — total item quantity
  totalHt,            // Ref<number> — pre-tax total
  totalTtc,           // Ref<number> — tax-included total
  totalVat,           // Ref<number> — total VAT
  weight,             // Ref<number> — total weight
  cartLoading,        // Ref<boolean> — loading state
  pricesLoading,      // Ref<boolean> — price refresh in progress
  isLogged,           // Ref<boolean> — user is authenticated

  isItemAdded,             // Ref<boolean> — an add just happened (drives the slideover)
  lastAddedItem,           // Ref<CartItem | null> — last added item
  addToCartEventId,        // Ref<number> — incremented on every add (drives the toast)
  cancelAddToCartAutoClose, // () => void — cancels the pending auto-close

  addItem,            // (item: CartItem, mode?) => Promise<boolean>
  addItems,           // (items: CartItem[]) => Promise<boolean>
  deleteItem,         // (item: CartItem) => Promise<boolean>
  updateItemQuantity, // (item: CartItem, qty: number) => Promise<boolean>
  updateItemsPrices,  // (items: CartItem[]) => Promise<void> — refresh prices (e.g. on login)
  clearCart,          // () => Promise<void>
} = useBoxShoppingCart()

useBoxOrder()

Checkout flow state and navigation.

const {
  activeSteps,         // ComputedRef<CheckoutStep[]>
  currentStep,         // Ref<CheckoutStep>
  currentStepIndex,    // ComputedRef<number>
  isFirstStep,         // ComputedRef<boolean>
  isLastStep,          // ComputedRef<boolean>
  canGoNext,           // ComputedRef<boolean>

  selectedDelivery,    // Ref<DeliveryMethod | null>
  selectedPayment,     // Ref<PaymentMethod | null>
  summaryForm,         // Ref<{ comment: string, customerRef: string }>
  status,              // Ref<PaymentStatus>
  errorMessage,        // Ref<string>
  confirmationId,      // Ref<number | null>

  loadDeliveries,      // () => Promise<DeliveryMethod[]>
  loadPaymentMethods,  // () => Promise<PaymentMethod[]>
  selectDelivery,      // (method: DeliveryMethod) => void
  selectPayment,       // (method: PaymentMethod) => void
  goToStep,            // (step: CheckoutStep) => void
  nextStep,            // () => void
  prevStep,            // () => void
  submitOrder,         // (cartId: string, totalTtc: number) => Promise<void>
  resetOrder,          // () => void
} = useBoxOrder()

Step types:

| Step | Description | |---|---| | 'delivery' | Delivery method selection | | 'payment' | Payment method selection | | 'summary' | Order summary and additional fields | | 'confirmation' | Final order confirmation |

Payment status (PaymentStatus):

| Status | Description | |---|---| | 'idle' | Default state | | 'pending' | Submission in progress | | 'success' | Order confirmed | | 'failed' | Submission error | | 'refused' | Payment refused by gateway |


useBoxCartItemPrice(item)

Per-item price calculations.

const { isHt, step, unitPrice, lineTotal } = useBoxCartItemPrice(item)
// step      → conditioning unit (soldBy or 1)
// unitPrice → unit price according to HT/TTC mode
// lineTotal → line total = (unitPrice + deposit if applicable) × quantity × soldBy

useBoxWsCart()

HTTP calls to the cart web service (internal ↔ API mapping). Advanced use — normally consumed only via useBoxShoppingCart().


useBoxWsBank()

Bank payment gateway integration.

const { createBankCheckout } = useBoxWsBank()
const result = await createBankCheckout(orderId, paymentMethodId, amountEuros)
// result → BankCheckoutResponse | null

API — Components

All components are auto-imported.

Cart components

| Component | Description | |---|---| | <BoxCart /> | Full cart (desktop table + mobile cards) | | <BoxCartItem /> | Individual cart item | | <BoxCartSkeleton /> | Loading skeleton | | <BoxCartTotals /> | Totals block (pre-tax, VAT, tax-included) | | <BoxCartProductImage /> | Product image with fallback | | <BoxCartVehicleInfo /> | Vehicle info associated with an item | | <BoxCartDrawer /> | Cart as a drawer | | <BoxCartSlideover /> | Cart as a side panel (slideover) | | <BoxCartAddedFeedback /> | Add-to-cart feedback: mounts the slideover or the toast based on addToCartFeedback | | <BoxCartAddedToast /> | "Item added" information toast (Nuxt UI), never stacks | | <BoxCartAddedToastBody /> | Toast detailed content (image, reference, quantity, totals) |

Modals

| Component | Description | |---|---| | <BoxCartLoginModal /> | Login required modal | | <BoxCartDeleteModal /> | Delete item confirmation modal | | <BoxCartClearModal /> | Clear cart confirmation modal |

Checkout components

| Component | Description | |---|---| | <BoxOrderStepper /> | Multi-step checkout orchestrator | | <BoxOrderDeliveryStep /> | Delivery selection step | | <BoxOrderPaymentStep /> | Payment method selection step | | <BoxOrderSummaryStep /> | Summary and additional fields step | | <BoxOrderConfirmation /> | Final confirmation screen |


API — Server endpoints

The module exposes the following server-side routes via Nitro:

| Method | Route | Description | |---|---|---| | GET | /api/_box/cart | Retrieve the cart | | POST | /api/_box/cart/addProduct | Add a product | | POST | /api/_box/cart/updateProduct | Update quantity | | POST | /api/_box/cart/deleteProduct | Remove a product | | POST | /api/_box/order | Submit an order | | GET | /api/_box/order/deliveries | Get available delivery methods | | GET | /api/_box/order/payments | Get available payment methods | | POST | /api/_box/erp/order | Forward order to ERP | | POST | /api/_box/bank/checkout | Initiate a bank payment |

These routes act as proxies to the external API configured via useBoxCartConfig().api.


Best practices

  • Initialize useBoxCartConfig() early — in a Nuxt plugin or root layout, before any cart component renders, with real user data (email, establishmentId, entityId).
  • Do not hardcode API endpoints in nuxt.config.ts — use useBoxCartConfig() to update them dynamically based on user context.
  • Sync with i18n — update locale and currency in useBoxCartConfig() on language changes.
  • HT vs TTC mode — set isHt based on the user profile (business customers → HT, consumers → TTC).

Known limitations

  • The module is designed for the Autopartspro ecosystem — some data structures (deposits/consignes, vehicle info, conditioning) are domain-specific.
  • Compatibility is limited to Nuxt ^4.0.0 < 5.0.0 — not compatible with Nuxt 3.
  • Server endpoints act as proxies: the external API must be correctly configured via useBoxCartConfig().
  • TODO: document the exact error response format for consumer-side error handling.

Contributing

This module is an internal package in the Graphibox / Autopartspro ecosystem.

# Install dependencies
npm install

# Prepare and start the playground
npm run dev

# Build
npm run prepack

# Tests
npm run test
npm run test:types

# Lint
npm run lint

License

MIT