paint-brush
Comment utiliser NextJS, TypeScript, Tailwind et OneEntry CMS pour créer une boutique de commerce électronique 🛒👨‍💻par@madzadev
1,553 lectures
1,553 lectures

Comment utiliser NextJS, TypeScript, Tailwind et OneEntry CMS pour créer une boutique de commerce électronique 🛒👨‍💻

par Madza2024/01/24
Read on Terminal Reader
Read this story w/o Javascript

Trop long; Pour lire

Nous construirons un projet de commerce électronique pratique pour voir comment NextJS, TypeScript, Tailwind CSS et OneEntry CMS fonctionnent ensemble et comment ils pourraient être utilisés pour simplifier la gestion de contenu.
featured image - Comment utiliser NextJS, TypeScript, Tailwind et OneEntry CMS pour créer une boutique de commerce électronique 🛒👨‍💻
Madza HackerNoon profile picture
0-item

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

NextJS est 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.


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


Tailwind CSS 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.


OneEntry CMS 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.

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.


Page d'accueil de la boutique e-commerce


La première section boutique sera dédiée aux Vêtements.


Page produits de la boutique e-commerce


La deuxième section de la boutique comprendra le Gear.


Produits de la boutique e-commerce page #2


Chacun des éléments aura une page d'aperçu individuelle avec des détails.


Page d'aperçu des produits de la boutique de commerce électronique


Les articles déjà dans le panier auront la possibilité de les supprimer.


Page d'aperçu des produits de la boutique de commerce électronique #2


Le panier listera tous les articles sélectionnés et calculera le total.


Page du panier du magasin de commerce électronique

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 inscrivez-vous via votre compte de messagerie.


Page d'inscription à OneEntry


Après cela, connectez-vous et vous serez dirigé vers le tableau de bord OneEntry.


Commencez par créer un nouveau projet.


Page du tableau de bord OneEntry


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.


Page du projet OneEntry


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.


Page du tableau de bord OneEntry

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.


Page de connexion au CMS OneEntry


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.


CMS OneEntry - modifier une page


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.


Liste des pages du CMS OneEntry

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 :


Types de pages du CMS OneEntry


Une fois créé, il ressemblera à la capture d'écran ci-dessous :


Attributs de la page OneEntry CMS


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.


Attributs du CMS OneEntry #2


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.


Paramètres de la page OneEntry CMS


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 :


Attributs de la page OneEntry CMS


Ensuite, faites de même pour la page Gear, qui utilisera la même structure :


Attributs de la page OneEntry CMS #2

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 :


Liste des pages du CMS OneEntry


Cliquez sur le bouton Modifier pour Accueil. Après cela, cliquez sur l'onglet Attributs du menu Horizontal :


Attributs de sélection du CMS OneEntry


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.


Création de contenu OneEntry CMS


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 :


Catalogue CMS OneEntry


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.


En-tête du catalogue OneEntry CMS


Passez maintenant à l'onglet Attributs, sélectionnez Vêtements pour l'ensemble d'attributs et remplissez les données requises.


OneEntry CMS ajouter des produits


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 :


Listes de produits OneEntry CMS

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.


OneEntry CMS - créer un jeton d'application


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.


OneEntry CMS - copier le jeton d'application

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 :


Assistant de configuration NextJS dans le terminal


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 cd winter-sports , puis exécutez npm run dev pour démarrer le serveur de développement.


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 :


Aperçu du serveur de développement NextJS


Maintenant, créons une valeur environnementale dont nous aurons besoin pour notre application. Revenez à votre éditeur de code et créez un fichier .env à la racine de votre projet.


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 process.env.API_KEY une fois que nous aurons effectué les appels d'API pour récupérer les données du CMS OneEntry.


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 next.config.js à la racine du projet et modifiez-le comme suit :


 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 globals.css dans le répertoire app situé dans le dossier src et modifiez le contenu du fichier comme suit :


 @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 interfaces dans le répertoire app . Créez un fichier data.tsx dans le dossier nouvellement créé et incluez le code :


 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 services dans le répertoire app avec un fichier fetchData.tsx à l'intérieur :


 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 getPages récupérera les données sur toutes les pages que nous avons créées dans le CMS OneEntry.


La fonction getProducts récupérera les données d'une collection spécifique de produits en fonction du paramètre category . Nous transmettrons le paramètre lorsque nous importerons la fonction dans la page produits.


La fonction getProduct récupérera les données en fonction de l' id 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.


Notez que nous avons utilisé process.env.API_KEY pour accéder à la clé API que nous avons définie précédemment dans le fichier .env afin d'authentifier l'accès au CMS OneEntry.

Créer des fonctions d'assistance

De plus, pendant que nous sommes toujours dans le dossier services , créons un autre nouveau fichier appelé helpers.tsx qui comprendra de petites fonctions utilitaires :


 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 calculateTotal additionnera les prix des produits ajoutés au panier et renverra la valeur totale.


Le boughtStatus détectera si les articles individuels de l'itinéraire d'aperçu ont déjà été ajoutés au panier.


Le cartIndex détectera la position de l'article dans le tableau pour les produits qui ont été ajoutés au panier.

Création de composants

Revenez au répertoire app et créez un nouveau dossier components à l'intérieur.


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 Header.tsx et incluez le code suivant :


 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 Footer.tsx et incluez le code suivant :


 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 Text.tsx et incluez le code suivant :


 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 Card.tsx et incluez le code suivant :


 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 Preview.tsx et incluez le code suivant :


 "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 Order.tsx et incluez le code suivant :


 "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 cardItems et les affichera à l'écran via la méthode map .


Le montant total des éléments rendus sera calculé via la fonction calculateTotal , que nous avons importée du fichier helpers.tsx .


Composant AddToCart

Ouvrez le fichier AddToCart.tsx et incluez le code suivant :


 "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 isPurchased 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".


La fonction de clic de la fonction handleButtonClick ajoutera ou supprimera le produit du tableau d'éléments en fonction de l'état ci-dessus en conséquence.

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 page.tsx dans le répertoire app et modifiez-en le contenu comme suit :


 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 getPages pour obtenir les données de l'en-tête.


Ensuite, nous utilisons la fonction getValues pour récupérer les données de la page Hero, puis les transformons en objet pageContent pour un traitement plus facile.


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 [category] dans le répertoire app et à l'intérieur - un fichier 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 category de l'URL, que nous transmettons ensuite à la fonction getProducts , pour décrire la catégorie de produits que nous devons récupérer en fonction de la page du site visitée.


Une fois les données reçues, nous créons un tableau d'objets productItems qui comprend tous les attributs nécessaires à la page pour un traitement plus facile.


Ensuite, nous le parcourons via la méthode map et le restituons à l'écran en passant des accessoires au composant Card que nous avons importé depuis le dossier du component .


Page d'aperçu

Dans le dossier [category] , créez un autre dossier appelé [productId] .


Ouvrez le dossier nouvellement créé et créez un fichier page.tsx à l'intérieur avec le code :


 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 productId de l'URL, que nous transmettons ensuite à la fonction getProduct , pour spécifier le produit que nous devons récupérer en fonction du produit affiché sur la page d'aperçu.


Une fois les données reçues, nous créons un objet productItem qui comprend tous les attributs nécessaires à transmettre au composant Preview en tant qu'accessoires.


Nous obtenons également le paramètre category , 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.


Page du panier

Enfin, créez un nouveau cart de dossiers dans le répertoire app .


Ouvrez-le, créez un nouveau fichier page.tsx à l'intérieur avec le code suivant :


 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 npm run dev pour le redémarrer et accédez à localhost:3000 pour le visualiser.


Votre projet devrait maintenant ressembler à ceci :


Présentation pas à pas du projet final


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 GitHub , 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.


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 Twitter , LinkedIn et GitHub !


Également publié ici