Introduction Il s'agit d'un article de partenariat sponsorisé par . OneEntry CMS Créer une application de commerce électronique est souvent une tâche difficile. Avec autant d'alternatives disponibles, il n'est pas facile de choisir une pile technologique qui répond aux exigences du projet, aux besoins d'évolutivité et à la durabilité à long terme. Un autre point crucial est que les projets de commerce électronique traitent de nombreuses données et opérations CRUD. Créer un système backend solide, évolutif et sécurisé peut prendre beaucoup de temps, même pour les développeurs les plus expérimentés. J'ai choisi une pile technologique basée sur NextJS, TypeScript, Tailwind CSS et OneEntry CMS. Nous construirons nous-mêmes un projet de commerce électronique pratique pour voir comment il fonctionne ensemble et comment il pourrait être utilisé pour simplifier la gestion de contenu. Le code de ce projet sera disponible dans le . référentiel GitHub Le choix de la pile technologique un framework React permettant de créer des applications Web rapides et efficaces, doté de fonctionnalités telles que le rendu client et serveur, la récupération de données, les gestionnaires de routes, le middleware, les optimisations intégrées et bien plus encore. NextJS est ajoute un typage statique à JavaScript, ce qui facilite la détection et la correction des erreurs pour les projets évolutifs comme le commerce électronique. Il augmente également la productivité grâce à des fonctionnalités telles que la saisie semi-automatique et l'assistance à la refactorisation. TypeScript accélère la partie style des applications Web, permettant aux développeurs de styliser les éléments dans le balisage sans avoir besoin de basculer entre les fichiers CSS externes et de proposer les noms de classe pour chacun. Tailwind CSS est un système de gestion de contenu sans tête avec une interface facile à utiliser, un backend facilement évolutif, une API rapide et une documentation claire pour augmenter votre productivité pour la création et l'expérience de gestion de contenu de sites Web. OneEntry CMS Contenu et conception La page de destination affichera le titre du titre, répertoriera les fonctionnalités de la boutique et inclura l'image du héros. La première section boutique sera dédiée aux Vêtements. La deuxième section de la boutique comprendra le Gear. Chacun des éléments aura une page d'aperçu individuelle avec des détails. Les articles déjà dans le panier auront la possibilité de les supprimer. Le panier listera tous les articles sélectionnés et calculera le total. Créer un projet OneEntry Tout d’abord, l’utilisateur devra créer un nouveau compte. Pour ce faire, accédez à la page d'accueil de OneEntry et via votre compte de messagerie. inscrivez-vous Après cela, et vous serez dirigé vers le tableau de bord OneEntry. connectez-vous Commencez par créer un nouveau projet. Vous recevrez le code gratuit pour utiliser le plan Study pendant un mois. Vous aurez la possibilité de l'activer lors du processus de création du projet. La création du projet prendra quelques minutes. Une fois prêt, l'état du projet passera à « En cours » et l'indicateur d'état sera vert. Création des pages Une fois le projet créé, vous recevrez un e-mail avec les informations de connexion pour accéder à votre portail CMS afin de créer et stocker les données de l'application. Après vous être connecté, vous pourrez créer votre première page. Accédez à Gestion de contenu, cliquez sur Créer une nouvelle page et remplissez toutes les données requises : types de pages, titre de la page, ULR de la page et nom de l'élément de menu. Toutes les données sont automatiquement enregistrées lors de la saisie. Créez 4 pages différentes pour la maison, les vêtements, l'équipement et le panier. Une fois créées, les pages devraient ressembler à la capture d'écran ci-dessous. Créer des attributs Ensuite, nous devons créer la structure de données que nous allons stocker. Dans OneEntry CMS, cela est réalisé en créant les attributs des données. Accédez à Paramètres et choisissez Attributs dans le menu horizontal. Créez un ensemble d'attributs pour la page d'accueil en fournissant le nom, le marqueur et le type : Une fois créé, il ressemblera à la capture d'écran ci-dessous : De même, créons deux ensembles d'attributs distincts pour les vêtements et l'équipement. Une fois créé, le résultat devrait ressembler à la capture d'écran ci-dessous. Définissons maintenant des attributs spécifiques pour chaque ensemble. Sur la base du contenu que nous avons inclus précédemment dans le wireframe de la section Accueil, nous souhaitons afficher le titre, la description et l'image. Cliquez sur l'élément d'engrenage pour Accueil et créez les noms d'attributs, marqueurs et types d'attributs suivants, comme indiqué dans la liste ci-dessous. Maintenant, revenez en arrière et cliquez sur l’icône d’engrenage pour les vêtements. Les attributs de cette page seront un peu différents puisque nous souhaitons afficher le titre, le sous-titre, la description, l'image et le prix du produit. Voici à quoi ressemblerait la structure des attributs : Ensuite, faites de même pour la page Gear, qui utilisera la même structure : Ajouter du contenu À ce stade du projet, nous avons déjà défini la structure du contenu et sommes prêts à commencer à créer le contenu lui-même. Accédez à la section Gestion de contenu où vous avez précédemment créé toutes vos pages pour le site : Cliquez sur le bouton Modifier pour Accueil. Après cela, cliquez sur l'onglet Attributs du menu Horizontal : Sélectionnez Accueil pour l'ensemble d'attributs. Cela chargera tous les attributs que nous avons créés précédemment dans les paramètres de la page d'accueil. Remplissez maintenant quelques exemples de données que vous souhaitez afficher sur la page d'accueil. Maintenant, ajoutons du contenu pour nos pages Vêtements et Équipement. Puisque nous avons sélectionné le type de page comme catalogue, sélectionnez Catalogue dans le menu de gauche et les deux pages devraient y être visibles : Maintenant, cliquez sur l'icône Ajouter pour les vêtements et ajoutez quelques éléments. Tout d’abord, ajoutez l’en-tête du produit que vous souhaitez ajouter. Passez maintenant à l'onglet Attributs, sélectionnez Vêtements pour l'ensemble d'attributs et remplissez les données requises. Revenez au menu Catalogue et à quelques éléments supplémentaires pour les vêtements et l'équipement. Pour notre application de démonstration, j'ai ajouté 4 éléments comme indiqué dans la capture d'écran ci-dessous : Créer un jeton d'accès à l'API Toutes les données créées dans le CMS OneEntry sont protégées, nous devrons donc créer un jeton privé pour pouvoir y accéder. Pour ce faire, accédez à Paramètres et sélectionnez Jetons d'application. Entrez le nom de l'application et la date d'expiration, puis cliquez sur Créer. Cela générera une clé API unique. Cliquez sur l'icône d'affichage dans la liste d'actions et vous pourrez voir la clé. Copiez-le dans le presse-papiers car nous en aurons besoin dans la prochaine section du didacticiel. Configuration du projet NextJS Dans cette section du didacticiel, nous allons commencer à travailler avec le code et configurer le projet NextJS pour qu'il fonctionne avec OneEntry CMS. Ouvrez le terminal et exécutez la commande . npx create-next-app@latest La CLI démarrera l’assistant de configuration. Entrez le nom de votre projet et sélectionnez toutes les valeurs par défaut comme indiqué ci-dessous : Donnez une minute à la configuration et vous recevrez une notification lorsque l'application NextJS aura été créée. Après cela, remplacez le répertoire par le dossier nouvellement créé à l'aide de la commande , puis exécutez pour démarrer le serveur de développement. cd winter-sports npm run dev Pour y accéder, cliquez sur le lien fourni sur le terminal ou ouvrez votre navigateur Web et accédez manuellement à . http://localhost:3000 La page de destination du serveur de développement NextJS devrait vous être présentée : Maintenant, créons une valeur environnementale dont nous aurons besoin pour notre application. Revenez à votre éditeur de code et créez un fichier à la racine de votre projet. .env Collez la clé API que vous avez copiée précédemment dans le presse-papiers comme suit : API_KEY=your-api-code-from-oneentry Cela nous permettra d'accéder à la clé via une fois que nous aurons effectué les appels d'API pour récupérer les données du CMS OneEntry. process.env.API_KEY Nous devons également configurer NextJS, cela nous permet donc d'inclure les médias d'un domaine externe. Nous en aurons besoin pour accéder aux images de OneEntry CMS. Ouvrez le fichier à la racine du projet et modifiez-le comme suit : next.config.js const nextConfig = { images: { remotePatterns: [ { hostname: "ecommerce.oneentry.cloud", }, ], }, }; module.exports = nextConfig; Enfin, nous devrons réinitialiser le style par défaut de Tailwind pour l'application puisque nous allons écrire tous les styles à partir de zéro. Ouvrez le fichier dans le répertoire situé dans le dossier et modifiez le contenu du fichier comme suit : globals.css app src @tailwind base; @tailwind components; @tailwind utilities; Créer des types Puisque nous travaillerons avec TypeScript, nous devrons définir les types de données que nous utiliserons dans notre application. Nous pourrions le faire dans les pages et les composants, mais pour garder le code plus propre et éviter les répétitions, créez un nouveau dossier dans le répertoire . Créez un fichier dans le dossier nouvellement créé et incluez le code : interfaces app data.tsx export interface Product { id: string; category: string; title: string; subtitle: string; description: string; image: string; price: number; } export interface ProductAPI { id: string; attributeValues: { en_US: { producttitle: { value: { htmlValue: string }[]; }; productsubtitle: { value: { htmlValue: string }[]; }; productdescription: { value: { htmlValue: string }[]; }; productimage: { value: { downloadLink: string }[]; }; productprice: { value: number; }; }; }; } export interface Page { pageUrl: string; title: string; description: string; image: string; localizeInfos: { en_US: { title: string; }; }; } export interface PageAPI { attributeValues: { en_US: { herotitle: { value: { htmlValue: string }[]; }; herodescription: { value: { htmlValue: string }[]; }; heroimage: { value: { downloadLink: string }[]; }; }; }; } export interface URLProps { params: { category: string; productId: string; }; } export interface TextProps { className: string; text: string; } Les produits et les données de page auront tous deux des types pour leur structure de données de rendu frontal et la réponse de l'API via la méthode fetch. Nous avons également défini les types de données pour les données des paramètres URL et le moteur de rendu de texte pour les données reçues des champs de saisie de texte dans le CMS. Créer des fonctions de récupération d'API Créons maintenant quelques fonctions que nous utiliserons pour communiquer avec OneEntry CMS afin de récupérer les données des pages et des produits. Encore une fois, nous pourrions faire cela dans chaque fichier, mais pour garder le code plus propre, créons un nouveau dossier dans le répertoire avec un fichier à l'intérieur : services app fetchData.tsx export async function getPages() { const response = await fetch( "https://ecommerce.oneentry.cloud/api/content/pages", { method: "GET", headers: { "x-app-token": `${process.env.API_KEY}`, }, } ); return await response.json(); } export async function getProducts(category: string) { const response = await fetch( `https://ecommerce.oneentry.cloud/api/content/products/page/url/${category}?limit=4&offset=0&langCode=en_US&sortOrder=DESC&sortKey=id`, { method: "GET", headers: { "x-app-token": `${process.env.API_KEY}`, }, } ); return await response.json(); } export async function getProduct(id: string) { const response = await fetch( `https://ecommerce.oneentry.cloud/api/content/products/${id}`, { method: "GET", headers: { "x-app-token": `${process.env.API_KEY}`, }, } ); return await response.json(); } La fonction récupérera les données sur toutes les pages que nous avons créées dans le CMS OneEntry. getPages La fonction récupérera les données d'une collection spécifique de produits en fonction du paramètre . Nous transmettrons le paramètre lorsque nous importerons la fonction dans la page produits. getProducts category La fonction récupérera les données en fonction de l' du produit que nous ouvrons. Nous transmettrons le paramètre lorsque nous importerons la fonction dans la page d'aperçu d'un produit spécifique. getProduct id Notez que nous avons utilisé pour accéder à la clé API que nous avons définie précédemment dans le fichier afin d'authentifier l'accès au CMS OneEntry. process.env.API_KEY .env Créer des fonctions d'assistance De plus, pendant que nous sommes toujours dans le dossier , créons un autre nouveau fichier appelé qui comprendra de petites fonctions utilitaires : services helpers.tsx export function calculateTotal(items: { price: number }[]) { return items.reduce((total, item) => total + Number(item.price), 0); } export function boughtStatus(items: { id: string }[], id: string) { return items.some((item) => item.id === id); } export function cartIndex(items: { id: string }[], id: string) { return items.findIndex((item) => item.id === id); } La fonction additionnera les prix des produits ajoutés au panier et renverra la valeur totale. calculateTotal Le détectera si les articles individuels de l'itinéraire d'aperçu ont déjà été ajoutés au panier. boughtStatus Le détectera la position de l'article dans le tableau pour les produits qui ont été ajoutés au panier. cartIndex Création de composants Revenez au répertoire et créez un nouveau dossier à l'intérieur. app components Ouvrez le dossier nouvellement créé et incluez-y sept fichiers distincts : , , , , , , . Header.tsx Footer.tsx Text.tsx Card.tsx Preview.tsx Order.tsx AddToCart.tsx Composant d'en-tête Ouvrez le fichier et incluez le code suivant : Header.tsx import Link from "next/link"; import { Page } from "../interfaces/data"; export default function Header({ pages }: { pages: Page[] }) { return ( <div className="flex justify-between items-center mb-10 p-6"> <Link href="/"> <h1 className="text-xl">🏂 Alpine Sports</h1> </Link> <div className="flex space-x-4 list-none"> {pages.map((page, index: number) => ( <Link key={index} href={page.pageUrl === "home" ? "/" : `/${page.pageUrl}`} > {page.localizeInfos.en_US.title} </Link> ))} </div> </div> ); } Pour l'en-tête, nous avons affiché le nom de l'entreprise et parcouru les liens de navigation que nous obtiendrons de l'API une fois le composant importé dans les pages. Nous avons créé une disposition à deux colonnes et positionné horizontalement les deux éléments sur les côtés opposés de l'écran pour obtenir l'apparence de navigation typique. Composant de pied de page Ouvrez le fichier et incluez le code suivant : Footer.tsx export default function Footer() { return ( <div className="text-center mt-auto p-6"> <h1>Alpine Sports, Inc.</h1> <p>All rights reserved, {new Date().getFullYear()}</p> </div> ); } Dans le pied de page, nous avons inclus un exemple de nom de l'entreprise et les droits de contenu pour l'année en cours. Nous avons centré le contenu et ajouté du remplissage. Composant texte Ouvrez le fichier et incluez le code suivant : Text.tsx import { TextProps } from "../interfaces/data"; export default function Text({ className, text }: TextProps) { return ( <div className={className} dangerouslySetInnerHTML={{ __html: text }} /> ); } Le composant Texte restituera les données texte que nous recevons du CMS OneEntry et les affichera correctement dans notre application sans balises HTML. Composant de carte Ouvrez le fichier et incluez le code suivant : Card.tsx import Link from "next/link"; import Text from "../components/Text"; import { Product } from "../interfaces/data"; export default function Card({ product }: { product: Product }) { return ( <Link href={`/${product.category}/${product.id}`}> <div className="group relative"> <div className="group-hover:opacity-75 h-80"> <img src={product.image} alt="Product card image" className="h-full w-full object-cover object-center" /> </div> <div className="mt-4 flex justify-between"> <div> <h3 className="text-sm text-gray-700"> <Text className="" text={product.title} /> </h3> <Text className="mt-1 text-sm text-gray-500" text={product.subtitle} /> </div> <p className="text-sm font-medium text-gray-900">${product.price}</p> </div> </div> </Link> ); } Dans le composant carte, nous avons affiché l'image, le titre, le sous-titre et le prix de chaque produit. Nous cartographierons tous les éléments une fois importés dans les pages. L'image sera affichée en haut de la carte, suivie du titre et de la description, ainsi que du prix en bas à droite du composant. Composant d'aperçu Ouvrez le fichier et incluez le code suivant : Preview.tsx "use-client"; import Image from "next/image"; import Text from "./Text"; import { Product } from "../interfaces/data"; export default function Preview({ children, productItem, }: { children: React.ReactNode; productItem: Product; }) { return ( <div className="flex mx-auto max-w-screen-xl"> <div className="flex-1 flex justify-start items-center"> <Image src={productItem.image} alt="Product preview image" width="450" height="900" /> </div> <div className="flex-1"> <Text className="text-5xl pb-8" text={productItem.title} /> <Text className="text-4xl pb-8 text-gray-700" text={`$${productItem.price}`} /> <Text className="pb-8 text-gray-500 text-justify" text={productItem.description} /> {children} </div> </div> ); } Le composant d'aperçu sera utilisé pour afficher des informations supplémentaires sur chaque produit une fois que l'utilisateur aura cliqué dessus. Nous afficherons l'image du produit, le titre, le prix et la description. La mise en page sera divisée en 2 colonnes, l'image étant affichée dans la colonne de gauche et le reste du contenu dans la colonne de droite. Composant de commande Ouvrez le fichier et incluez le code suivant : Order.tsx "use client"; import { useState, useEffect } from "react"; import Link from "next/link"; import Image from "next/image"; import Text from "./Text"; import { calculateTotal } from "../services/helpers"; import { Product } from "../interfaces/data"; export default function Order() { const [cartItems, setCartItems] = useState<Product[]>([]); useEffect(() => { const storedCartItems = localStorage.getItem("cartItems"); const cartItems = storedCartItems ? JSON.parse(storedCartItems) : []; setCartItems(cartItems); }, []); return ( <div> {cartItems.map((item, index) => ( <div key={index} className="flex items-center border-b border-gray-300 py-2" > <div className="w-20 h-20 mr-12"> <Image src={item.image} alt={item.title} width={80} height={80} /> </div> <div> <Link href={`/${item.category}/${item.id}`} className="text-lg font-semibold" > <Text className="" text={item.title} /> </Link> <Text className="text-gray-600" text={item.subtitle} /> <p className="text-gray-800">Price: ${item.price}</p> </div> </div> ))} <div className="mt-4 text-end"> <h2 className="text-xl font-semibold mb-8"> Total Amount: ${calculateTotal(cartItems)} </h2> <button className="bg-blue-500 hover:bg-blue-700 py-2 px-8 rounded"> Proceed to checkout </button> </div> </div> ); } Le composant de commande répertoriera tous les articles que l'utilisateur a ajoutés au panier. Pour chaque article, l'image, le titre, le sous-titre et le prix seront affichés. Une fois le composant rendu, l'application accédera à tous les articles actuellement dans le panier, les définira sur la variable d'état et les affichera à l'écran via la méthode . cardItems map Le montant total des éléments rendus sera calculé via la fonction , que nous avons importée du fichier . calculateTotal helpers.tsx Composant AddToCart Ouvrez le fichier et incluez le code suivant : AddToCart.tsx "use client"; import React, { useState, useEffect } from "react"; import { boughtStatus, cartIndex } from "../services/helpers"; import { Product } from "../interfaces/data"; export default function AddToCart({ category, id, title, subtitle, image, price, }: Product) { const storedCartItems = JSON.parse(localStorage.getItem("cartItems") || "[]"); const isPurchased = boughtStatus(storedCartItems, id); const indexInCart = cartIndex(storedCartItems, id); const [btnState, setBtnState] = useState(false); useEffect(() => { isPurchased && setBtnState(true); }, []); const handleButtonClick = () => { const updatedCartItems = [...storedCartItems]; if (!btnState && !isPurchased) { updatedCartItems.push({ category, id, title, subtitle, image, price }); } else if (isPurchased) { updatedCartItems.splice(indexInCart, 1); } localStorage.setItem("cartItems", JSON.stringify(updatedCartItems)); setBtnState(!btnState); }; return ( <button className={`${ !btnState ? "bg-blue-500 hover:bg-blue-600" : "bg-yellow-300 hover:bg-yellow-400" } py-2 px-8 rounded`} onClick={handleButtonClick} > {!btnState ? "Add to Cart" : "Remove from Cart"} </button> ); } Le composant addToCart sera affiché sur la page d'aperçu du produit individuel et permettra à l'utilisateur d'ajouter le produit au panier. Lors du rendu, la fonction détectera si le produit a déjà été ajouté au panier auparavant. Si ce n'est pas le bouton rendu, affichera "Ajouter au panier", sinon il dira "Supprimer du panier". isPurchased La fonction de clic de la fonction ajoutera ou supprimera le produit du tableau d'éléments en fonction de l'état ci-dessus en conséquence. handleButtonClick Créer des pages Enfin, importons les composants que nous avons créés dans la section précédente du didacticiel et créons la logique de page pour l'application. Page d'accueil Ouvrez dans le répertoire et modifiez-en le contenu comme suit : page.tsx app import Image from "next/image"; import Header from "./components/Header"; import Text from "./components/Text"; import Footer from "./components/Footer"; import { getPages } from "./services/fetchData"; import { PageAPI } from "./interfaces/data"; export default async function Home() { const pages = await getPages(); const getValues = (el: PageAPI) => { const { herotitle, herodescription, heroimage } = el.attributeValues.en_US; return { title: herotitle.value[0].htmlValue, description: herodescription.value[0].htmlValue, image: heroimage.value[0].downloadLink, }; }; const pageContent = getValues(pages[0]); return ( <div className="flex flex-col min-h-screen"> <Header pages={pages} /> <div className="flex flex-row mx-auto max-w-screen-xl"> <div className="flex-1"> <Text className="text-6xl pb-10 text-gray-900" text={pageContent.title} /> <Text className="text-xl pb-8 text-gray-500 text-justify" text={pageContent.description} /> </div> <div className="flex-1 flex justify-end items-center"> <Image src={pageContent.image} alt="Photo by Karsten Winegeart on Unsplash" width={450} height={900} /> </div> </div> <Footer /> </div> ); } Sur la page d'accueil, nous appellerons d'abord la fonction pour obtenir les données de l'en-tête. getPages Ensuite, nous utilisons la fonction pour récupérer les données de la page Hero, puis les transformons en objet pour un traitement plus facile. getValues pageContent Ensuite, nous rendons les composants d'en-tête et de pied de page importés et transmettons les valeurs nécessaires pour le titre, la description et l'image du héros. Page produits Créez un nouveau dossier dans le répertoire et à l'intérieur - un fichier . [category] app page.tsx L'utilisation de noms de fichiers spécifiques est importante puisque c'est ce que NextJS utilise pour gérer les routes et accéder aux paramètres d'URL. Incluez le code suivant dans le : page.tsx import Header from "../components/Header"; import Footer from "../components/Footer"; import Card from "../components/Card"; import { getPages, getProducts } from "../services/fetchData"; import { ProductAPI, URLProps } from "../interfaces/data"; export default async function Product({ params }: URLProps) { const { category } = params; const pages = await getPages(); const products = await getProducts(category); const getValues = (products: ProductAPI[]) => { return products.map((el) => { const { producttitle, productsubtitle, productdescription, productimage, productprice, } = el.attributeValues.en_US; return { id: el.id, category: category, title: producttitle.value[0].htmlValue, subtitle: productsubtitle.value[0].htmlValue, description: productdescription.value[0].htmlValue, image: productimage.value[0].downloadLink, price: productprice.value, }; }); }; const productItems = getValues(products.items); return ( <div className="flex flex-col min-h-screen"> <Header pages={pages} /> <div className="mx-auto max-w-screen-xl px-8"> <h2 className="text-4xl text-gray-900 mb-12"> Browse our {category} collection: </h2> <div className="grid gap-x-6 gap-y-10 grid-cols-4 mt-6"> {productItems.map((product) => { return <Card key={product.id} product={product} />; })} </div> </div> <Footer /> </div> ); } Pour la page de produits, nous obtenons d'abord le paramètre de l'URL, que nous transmettons ensuite à la fonction , pour décrire la catégorie de produits que nous devons récupérer en fonction de la page du site visitée. category getProducts Une fois les données reçues, nous créons un tableau d'objets qui comprend tous les attributs nécessaires à la page pour un traitement plus facile. productItems Ensuite, nous le parcourons via la méthode et le restituons à l'écran en passant des accessoires au composant Card que nous avons importé depuis le dossier du . map component Page d'aperçu Dans le dossier , créez un autre dossier appelé . [category] [productId] Ouvrez le dossier nouvellement créé et créez un fichier à l'intérieur avec le code : page.tsx import Header from "../../components/Header"; import Preview from "../../components/Preview"; import AddToCart from "../../components/AddToCart"; import Footer from "../../components/Footer"; import { getPages, getProduct } from "../../services/fetchData"; import { ProductAPI, URLProps } from "../../interfaces/data"; export default async function Product({ params }: URLProps) { const { category, productId } = params; const pages = await getPages(); const product = await getProduct(productId); const getValues = (el: ProductAPI) => { const { producttitle, productsubtitle, productdescription, productimage, productprice, } = el.attributeValues.en_US; return { id: el.id, category: category, title: producttitle.value[0].htmlValue, subtitle: productsubtitle.value[0].htmlValue, description: productdescription.value[0].htmlValue, image: productimage.value[0].downloadLink, price: productprice.value, }; }; const productItem = getValues(product); return ( <div className="flex flex-col min-h-screen"> <Header pages={pages} /> <div className="flex mx-auto max-w-screen-xl"> <div className="flex-1 flex justify-start items-center"> <Preview productItem={productItem}> <AddToCart id={productId} category={category} title={productItem.title} subtitle={productItem.subtitle} description={productItem.description} image={productItem.image} price={productItem.price} /> </Preview> </div> </div> <Footer /> </div> ); } Cette page permettra aux utilisateurs d'afficher plus de détails sur n'importe quel produit individuel une fois qu'ils auront cliqué sur leurs cartes sur la page des produits. Nous récupérons d'abord le paramètre de l'URL, que nous transmettons ensuite à la fonction , pour spécifier le produit que nous devons récupérer en fonction du produit affiché sur la page d'aperçu. productId getProduct Une fois les données reçues, nous créons un objet qui comprend tous les attributs nécessaires à transmettre au composant Preview en tant qu'accessoires. productItem Nous obtenons également le paramètre , car nous devons le transmettre au composant Ajouter au panier, afin que nous puissions créer un lien valide pour l'article dans la page Panier. category Page du panier Enfin, créez un nouveau de dossiers dans le répertoire . cart app Ouvrez-le, créez un nouveau fichier à l'intérieur avec le code suivant : page.tsx import Header from "../components/Header"; import Order from "../components/Order"; import Footer from "../components/Footer"; import { getPages } from "../services/fetchData"; export default async function Cart() { const pages = await getPages(); return ( <div className="flex flex-col min-h-screen"> <Header pages={pages} /> <div className="container mx-auto max-w-screen-xl px-8"> <h2 className="text-4xl text-gray-900 mb-12">Shopping cart summary:</h2> <Order /> </div> <Footer /> </div> ); } Nous avons d'abord récupéré les données nécessaires, puis les avons transmises dans l'en-tête en tant qu'accessoires. Ensuite, nous avons rendu le composant Header avec la navigation, le composant Order qui listera tous les articles que l'utilisateur a ajoutés au panier et également le composant Footer avec le nom de l'entreprise et les informations de copyright. Essai Félicitations, vous avez réalisé un projet fonctionnel ! Tout d’abord, vérifiez si le serveur de développement est toujours en cours d’exécution. Si ce n'est pas le cas, exécutez la commande pour le redémarrer et accédez pour le visualiser. npm run dev à localhost:3000 Votre projet devrait maintenant ressembler à ceci : Comme vous pouvez le constater, le contenu de la section Accueil a été récupéré avec succès à partir de l'ensemble d'attributs Accueil que nous avons spécifié dans les champs de données. De plus, tous les articles du catalogue OneEntry CMS ont été récupérés dans les sections Vêtements et Équipement avec toutes les informations correctement restituées. Les utilisateurs peuvent également prévisualiser chaque produit séparément sur sa page dédiée, grâce à la gestion des itinéraires NextJS et aux paramètres du produit. De plus, toutes les fonctions et événements fonctionnent comme prévu, et l'utilisateur peut ajouter et supprimer des articles du panier, le total étant calculé. Conclusion Dans ce didacticiel, nous avons créé un projet de commerce électronique qui permet aux utilisateurs de créer, mettre à jour et supprimer des pages de sites Web et leur contenu, ainsi que de gérer facilement des produits avec une interface de catalogue facile à utiliser, grâce au . CMS OneEntry Le code est disponible sur , alors n'hésitez pas à le cloner et à lui ajouter plus de fonctionnalités en fonction de vos besoins. Vous pouvez y ajouter plus de sections de menu, étendre des composants individuels ou même ajouter plus de composants pour implémenter de nouvelles fonctionnalités. GitHub J'espère que cela vous sera utile et que vous aurez un aperçu de la façon d'utiliser OneEntry CMS comme solution backend, comment l'associer au front-end de votre application et comment utiliser les meilleures fonctionnalités de NextJS, Typescript et Tailwind. . Assurez-vous de recevoir les meilleures ressources, outils, conseils de productivité et conseils d'évolution de carrière que je découvre en vous abonnant à ! ma newsletter Connectez-vous également avec moi sur , et ! Twitter LinkedIn GitHub Également publié ici