paint-brush
So verwenden Sie NextJS, TypeScript, Tailwind und OneEntry CMS zum Aufbau eines E-Commerce-Shops 🛒👨‍💻von@madzadev
1,553 Lesungen
1,553 Lesungen

So verwenden Sie NextJS, TypeScript, Tailwind und OneEntry CMS zum Aufbau eines E-Commerce-Shops 🛒👨‍💻

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

Zu lang; Lesen

Wir werden ein praktisches E-Commerce-Projekt erstellen, um zu sehen, wie NextJS, TypeScript, Tailwind CSS und OneEntry CMS zusammenarbeiten und wie sie zur Vereinfachung des Content-Managements eingesetzt werden können.
featured image - So verwenden Sie NextJS, TypeScript, Tailwind und OneEntry CMS zum Aufbau eines E-Commerce-Shops 🛒👨‍💻
Madza HackerNoon profile picture
0-item

Einführung

Dies ist ein Partnerschaftsartikel, der von OneEntry CMS gesponsert wird.


Der Aufbau einer E-Commerce-Anwendung ist oft eine herausfordernde Aufgabe. Bei so vielen verfügbaren Alternativen ist es nicht einfach, einen Technologie-Stack auszuwählen, der den Anforderungen, Skalierbarkeitsanforderungen und der langfristigen Nachhaltigkeit des Projekts entspricht.


Ein weiterer entscheidender Punkt ist, dass E-Commerce-Projekte mit vielen Daten und CRUD-Operationen zu tun haben. Die Erstellung eines soliden, skalierbaren und sicheren Backend-Systems kann selbst für die erfahrensten Entwickler viel Zeit in Anspruch nehmen.


Ich habe einen Tech-Stack ausgewählt, der auf NextJS, TypeScript, Tailwind CSS und OneEntry CMS basiert. Wir werden selbst ein praktisches E-Commerce-Projekt aufbauen, um zu sehen, wie es zusammenspielt und wie es zur Vereinfachung des Content-Managements genutzt werden kann.


Der Code für dieses Projekt wird im GitHub-Repository verfügbar sein.

Die Wahl des Tech-Stacks

NextJS ist ein React-Framework zum Erstellen schneller und effizienter Webanwendungen, das Funktionen wie Client- und Server-Rendering, Datenabruf, Routenhandler, Middleware, integrierte Optimierungen und vieles mehr bietet.


TypeScript fügt JavaScript statische Typisierung hinzu, was es einfacher macht, Fehler für skalierbare Projekte wie E-Commerce zu erkennen und zu beheben. Darüber hinaus steigert es die Produktivität durch Funktionen wie automatische Vervollständigung und Refactoring-Unterstützung.


Tailwind CSS beschleunigt den Styling-Teil der Web-Apps und ermöglicht es Entwicklern, die Elemente innerhalb des Markups zu formatieren, ohne zwischen externen CSS-Dateien wechseln und sich jeweils die Klassennamen ausdenken zu müssen.


OneEntry CMS ist ein Headless-Content-Management-System mit einer benutzerfreundlichen Oberfläche, einem leicht skalierbaren Backend, einer schnellen API und einer klaren Dokumentation, um Ihre Produktivität bei der Erstellung und Verwaltung von Website-Inhalten zu steigern.

Inhalt und Design

Auf der Zielseite wird der Überschriftentitel angezeigt, die Funktionen des Shops aufgelistet und das Heldenbild eingefügt.


Homepage des E-Commerce-Shops


Der erste Shop-Bereich ist der Bekleidung gewidmet.


Produktseite des E-Commerce-Shops


Der zweite Shop-Bereich wird die Ausrüstung umfassen.


E-Commerce-Shop-Produktseite Nr. 2


Für jedes Element gibt es eine eigene Vorschauseite mit Details.


Produktvorschauseite des E-Commerce-Shops


Für Artikel, die sich bereits im Warenkorb befinden, besteht die Möglichkeit, sie zu entfernen.


Produktvorschauseite Nr. 2 im E-Commerce-Shop


Der Warenkorb listet alle ausgewählten Artikel auf und berechnet die Gesamtsumme.


Warenkorbseite im E-Commerce-Shop

Erstellen Sie ein OneEntry-Projekt

Zunächst muss sich der Benutzer für ein neues Konto anmelden. Navigieren Sie dazu zur OneEntry-Homepage und melden Sie sich über Ihr E-Mail-Konto an .


OneEntry-Anmeldeseite


Melden Sie sich anschließend an und Sie werden zum OneEntry-Dashboard weitergeleitet.


Beginnen Sie mit der Erstellung eines neuen Projekts.


OneEntry-Dashboard-Seite


Sie erhalten den kostenlosen Code, um den Studienplan einen Monat lang zu nutzen. Sie haben die Möglichkeit, es während des Erstellungsprozesses des Projekts zu aktivieren.


OneEntry-Projektseite


Die Erstellung des Projekts wird einige Minuten dauern. Sobald es fertig ist, ändert sich der Projektstatus auf „In Arbeit“ und die Statusanzeige leuchtet grün.


OneEntry-Dashboard-Seite

Erstellen der Seiten

Nachdem das Projekt erstellt wurde, erhalten Sie eine E-Mail mit Anmeldedaten, um auf Ihr CMS-Portal zuzugreifen und die Daten für die App zu erstellen und zu speichern.


OneEntry CMS-Anmeldeseite


Nach dem Login können Sie Ihre erste Seite erstellen.


Navigieren Sie zu Content Management, klicken Sie auf Neue Seite erstellen und geben Sie alle erforderlichen Daten ein – Seitentypen, Seitentitel, Seiten-ULR und Name des Menüelements.


OneEntry CMS – Bearbeiten Sie eine Seite


Alle Daten werden bei der Eingabe automatisch gespeichert.


Erstellen Sie 4 verschiedene Seiten für Zuhause, Kleidung, Ausrüstung und Warenkorb. Nach der Erstellung sollten die Seiten wie im Screenshot unten aussehen.


Liste der OneEntry CMS-Seiten

Erstellen Sie Attribute

Als nächstes müssen wir die Datenstruktur erstellen, die wir speichern möchten. Im OneEntry CMS wird dies durch die Erstellung der Attribute für die Daten erreicht.


Navigieren Sie zu „Einstellungen“ und wählen Sie im horizontalen Menü „Attribute“. Erstellen Sie einen Attributsatz für die Startseite unter Angabe des Namens, der Markierung und des Typs:


OneEntry CMS-Seitentypen


Nach der Erstellung sieht es wie im folgenden Screenshot aus:


OneEntry CMS-Seitenattribute


Erstellen wir auf ähnliche Weise zwei separate Attributsätze für Kleidung und Ausrüstung. Nach der Erstellung sollte das Ergebnis wie im Screenshot unten aussehen.


OneEntry CMS-Attribute #2


Definieren wir nun für jeden Satz spezifische Attribute.


Basierend auf dem Inhalt, den wir zuvor im Wireframe des Abschnitts „Home“ eingefügt haben, möchten wir den Titel, die Beschreibung und das Bild anzeigen.


Klicken Sie auf das Zahnradelement für „Home“ und erstellen Sie die folgenden Attributnamen, Markierungen und Attributtypen, wie in der Liste unten gezeigt.


OneEntry CMS-Seiteneinstellungen


Gehen Sie nun zurück und klicken Sie auf das Zahnradsymbol für Kleidung.


Die Attribute für diese Seite werden etwas anders sein, da wir den Produkttitel, den Untertitel, die Beschreibung, das Bild und den Preis anzeigen möchten.


So würde die Attributstruktur aussehen:


OneEntry CMS-Seitenattribute


Machen Sie als Nächstes dasselbe für die Gear-Seite, die dieselbe Struktur verwenden wird:


OneEntry CMS-Seitenattribute #2

Inhalt hinzufügen

In dieser Phase des Projekts haben wir bereits die Inhaltsstruktur definiert und sind bereit, mit der Erstellung des Inhalts selbst zu beginnen.


Navigieren Sie zum Abschnitt „Content Management“, in dem Sie zuvor alle Ihre Seiten für die Website erstellt haben:


Liste der OneEntry CMS-Seiten


Klicken Sie auf die Schaltfläche „Bearbeiten“ für „Startseite“. Klicken Sie anschließend im Menü „Horizontal“ auf die Registerkarte „Attribute“:


OneEntry CMS-Auswahlattribute


Wählen Sie Home für den Attributsatz aus. Dadurch werden alle Attribute geladen, die wir zuvor in den Einstellungen für die Startseite erstellt haben.


Geben Sie nun einige Beispieldaten ein, die auf der Startseite angezeigt werden sollen.


Erstellung von OneEntry CMS-Inhalten


Fügen wir nun einige Inhalte für unsere Seiten „Bekleidung“ und „Ausrüstung“ hinzu.


Da wir den Seitentyp „Katalog“ ausgewählt haben, wählen Sie im linken Menü „Katalog“ aus. Beide Seiten sollten dort sichtbar sein:


OneEntry CMS-Katalog


Klicken Sie nun auf das Symbol „Hinzufügen“ für Kleidung und fügen Sie einige Artikel hinzu.


Fügen Sie zunächst die Kopfzeile für das Produkt hinzu, das Sie hinzufügen möchten.


Header des OneEntry CMS-Katalogs


Wechseln Sie nun zur Registerkarte „Attribute“, wählen Sie als Attributsatz „Kleidung“ aus und geben Sie die erforderlichen Daten ein.


OneEntry CMS Produkte hinzufügen


Gehen Sie zurück zum Katalogmenü und sehen Sie ein paar weitere Artikel für Kleidung und Ausrüstung. Für unsere Demo-App habe ich 4 Elemente hinzugefügt, wie im Screenshot unten gezeigt:


OneEntry CMS-Produktlisten

Erstellen Sie ein API-Zugriffstoken

Alle im OneEntry CMS erstellten Daten sind geschützt, daher müssen wir einen privaten Token erstellen, um darauf zugreifen zu können.


Navigieren Sie dazu zu „Einstellungen“ und wählen Sie „App-Tokens“ aus. Geben Sie den App-Namen und das Ablaufdatum ein und klicken Sie auf Erstellen. Dadurch wird ein eindeutiger API-Schlüssel generiert.


OneEntry CMS – App-Token erstellen


Klicken Sie in der Aktionsliste auf das Ansichtssymbol, um den Schlüssel anzuzeigen. Kopieren Sie es in die Zwischenablage, da wir es im nächsten Abschnitt des Tutorials benötigen.


OneEntry CMS – App-Token kopieren

Einrichten des NextJS-Projekts

In diesem Abschnitt des Tutorials beginnen wir mit der Arbeit mit dem Code und konfigurieren das NextJS-Projekt für die Zusammenarbeit mit OneEntry CMS.


Öffnen Sie das Terminal und führen Sie den Befehl npx create-next-app@latest aus.


Die CLI startet den Setup-Assistenten. Geben Sie den Namen Ihres Projekts ein und wählen Sie alle Standardwerte aus, wie unten gezeigt:


NextJS-Setup-Assistent im Terminal


Nehmen Sie sich eine Minute Zeit, um die Einrichtung abzuschließen, und Sie erhalten eine Benachrichtigung, wenn die NextJS-App erstellt wurde.


Wechseln Sie anschließend mit dem Befehl cd winter-sports das Verzeichnis in den neu erstellten Ordner und führen Sie dann npm run dev aus, um den Entwicklerserver zu starten.


Um darauf zuzugreifen, klicken Sie auf den Link auf dem Terminal oder öffnen Sie Ihren Webbrowser und navigieren Sie manuell zu http://localhost:3000 .


Die Zielseite des NextJS-Entwicklerservers sollte angezeigt werden:


Vorschau des NextJS-Entwicklerservers


Lassen Sie uns nun einen Umweltwert erstellen, den wir für unsere App benötigen. Wechseln Sie zurück zu Ihrem Code-Editor und erstellen Sie eine .env Datei im Stammverzeichnis Ihres Projekts.


Fügen Sie den API-Schlüssel, den Sie zuvor in die Zwischenablage kopiert haben, wie folgt ein:


 API_KEY=your-api-code-from-oneentry


Dadurch können wir über process.env.API_KEY auf den Schlüssel zugreifen, sobald wir die API-Aufrufe durchführen, um die Daten vom OneEntry-CMS abzurufen.


Wir müssen auch NextJS konfigurieren, damit wir die Medien von einer externen Domäne einbinden können. Wir benötigen dies, um auf Bilder von OneEntry CMS zuzugreifen.


Öffnen Sie die Datei next.config.js im Projektstammverzeichnis und bearbeiten Sie sie wie folgt:


 const nextConfig = { images: { remotePatterns: [ { hostname: "ecommerce.oneentry.cloud", }, ], }, }; module.exports = nextConfig;


Schließlich müssen wir den Tailwind-Standardstil für die App zurücksetzen, da wir alle Stile von Grund auf neu schreiben werden.


Öffnen Sie die Datei globals.css im app Verzeichnis im Ordner src und ändern Sie den Inhalt der Datei wie folgt:


 @tailwind base; @tailwind components; @tailwind utilities;

Erstellen Sie Typen

Da wir mit TypeScript arbeiten, müssen wir definieren, welche Datentypen wir in unserer Anwendung verwenden werden.


Wir könnten dies innerhalb der Seiten und Komponenten tun, aber um den Code sauberer zu halten und Wiederholungen zu vermeiden, erstellen Sie einen neuen Ordner „ interfaces im app Verzeichnis. Erstellen Sie eine Datei data.tsx im neu erstellten Ordner und fügen Sie den Code ein:


 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; }


Sowohl Produkte als auch Seitendaten verfügen über Typen für ihre Front-End-Rendering-Datenstruktur und die Antwort von der API über die Abrufmethode.


Außerdem haben wir die Datentypen für die Daten aus den URL-Parametern und den Textrenderer für die Daten definiert, die aus den Texteingabefeldern im CMS empfangen werden.

Erstellen Sie API-Abruffunktionen

Lassen Sie uns nun einige Funktionen erstellen, die wir zur Kommunikation mit OneEntry CMS verwenden, um die Daten für die Seiten und Produkte abzurufen.


Auch dies könnten wir in jeder Datei tun, aber um den Code sauberer zu halten, erstellen wir einen neuen Ordner „ services im app Verzeichnis mit einer Datei fetchData.tsx darin:


 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(); }


Die Funktion getPages ruft die Daten aller Seiten ab, die wir im OneEntry CMS erstellt haben.


Die Funktion getProducts ruft die Daten für eine bestimmte Produktsammlung basierend auf dem category ab. Wir übergeben den Parameter, wenn wir die Funktion in die Produktseite importieren.


Die Funktion getProduct ruft die Daten basierend auf der id des von uns geöffneten Produkts ab. Wir übergeben den Parameter, wenn wir die Funktion in die Vorschauseite für ein bestimmtes Produkt importieren.


Beachten Sie, dass wir process.env.API_KEY verwendet haben, um auf den API-Schlüssel zuzugreifen, den wir zuvor in der .env Datei definiert haben, um den Zugriff für das OneEntry CMS zu authentifizieren.

Erstellen Sie Hilfsfunktionen

Während wir uns noch im services Ordner befinden, erstellen wir darin eine weitere neue Datei mit dem Namen helpers.tsx , die kleine Hilfsfunktionen enthält:


 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); }


Die Funktion calculateTotal addiert die Preise der zum Warenkorb hinzugefügten Produkte und gibt den Gesamtwert zurück.


Der boughtStatus erkennt, ob die einzelnen Artikel in der Vorschauroute bereits zum Warenkorb hinzugefügt wurden.


Der cartIndex erkennt die Position des Artikels im Array für die Produkte, die dem Warenkorb hinzugefügt wurden.

Komponenten erstellen

Navigieren Sie zurück zum app Verzeichnis und erstellen Sie darin einen neuen Ordner components .


Öffnen Sie den neu erstellten Ordner und fügen Sie sieben separate Dateien darin ein: Header.tsx , Footer.tsx , Text.tsx , Card.tsx , Preview.tsx , Order.tsx , AddToCart.tsx .


Header-Komponente

Öffnen Sie die Datei Header.tsx und fügen Sie den folgenden Code ein:


 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> ); }

Für die Kopfzeile haben wir den Firmennamen angezeigt und die Navigationslinks durchlaufen, die wir von der API erhalten, sobald die Komponente in Seiten importiert wird.


Wir haben ein zweispaltiges Layout erstellt und beide Elemente horizontal an den gegenüberliegenden Seiten des Bildschirms positioniert, um den typischen Navigationslook zu erreichen.


Fußzeilenkomponente

Öffnen Sie die Datei Footer.tsx und fügen Sie den folgenden Code ein:


 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> ); }


In der Fußzeile haben wir den Beispielnamen des Unternehmens und die Inhaltsrechte mit der aktuellen Jahreszahl eingefügt. Wir haben den Inhalt zentriert und etwas Polsterung hinzugefügt.


Textkomponente

Öffnen Sie die Datei Text.tsx und fügen Sie den folgenden Code ein:


 import { TextProps } from "../interfaces/data"; export default function Text({ className, text }: TextProps) { return ( <div className={className} dangerouslySetInnerHTML={{ __html: text }} /> ); }


Die Textkomponente rendert die Textdaten, die wir vom OneEntry CMS erhalten, und zeigt sie ordnungsgemäß in unserer Anwendung ohne HTML-Tags an.


Kartenkomponente

Öffnen Sie die Datei Card.tsx und fügen Sie den folgenden Code ein:


 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> ); }


In der Kartenkomponente haben wir für jedes Produkt das Bild, den Titel, den Untertitel und den Preis angezeigt. Wir werden alle Elemente zuordnen, sobald sie in die Seiten importiert werden.


Das Bild wird oben auf der Karte angezeigt, gefolgt vom Titel und der Beschreibung sowie dem Preis unten rechts auf der Komponente.


Vorschau der Komponente

Öffnen Sie die Datei Preview.tsx und fügen Sie den folgenden Code ein:


 "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> ); }


Die Vorschaukomponente wird verwendet, um weitere Informationen zu jedem Produkt anzuzeigen, sobald der Benutzer darauf klickt.


Wir zeigen das Produktbild, den Titel, den Preis und die Beschreibung an. Das Layout wird in zwei Spalten unterteilt, wobei das Bild in der linken Spalte und der Rest des Inhalts in der rechten Spalte angezeigt wird.


Bestellkomponente

Öffnen Sie die Datei Order.tsx und fügen Sie den folgenden Code ein:


 "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> ); }


In der Bestellkomponente werden alle Artikel aufgelistet, die der Benutzer dem Warenkorb hinzugefügt hat. Für jeden Artikel werden Bild, Titel, Untertitel und Preis angezeigt.


Sobald die Komponente gerendert ist, greift die App auf alle derzeit im Warenkorb befindlichen Artikel zu, setzt sie auf die Statusvariable cardItems und rendert sie über die map auf dem Bildschirm.


Die Gesamtmenge der gerenderten Elemente wird über die Funktion calculateTotal berechnet, die wir aus der Datei helpers.tsx importiert haben.


AddToCart-Komponente

Öffnen Sie die Datei AddToCart.tsx und fügen Sie den folgenden Code ein:


 "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> ); }


Die addToCart-Komponente wird auf der Vorschauseite des einzelnen Produkts angezeigt und ermöglicht es dem Benutzer, das Produkt in den Warenkorb zu legen.


Beim Rendern erkennt die Funktion isPurchased , ob das Produkt bereits zuvor zum Warenkorb hinzugefügt wurde oder nicht. Wenn es sich nicht um die gerenderte Schaltfläche handelt, wird „In den Warenkorb“ angezeigt, andernfalls wird „Aus dem Warenkorb entfernen“ angezeigt.


Die Funktion handleButtonClick zum Klicken fügt das Produkt basierend auf dem obigen Status dem Array „Artikel“ hinzu oder entfernt es daraus.

Seiten erstellen

Abschließend importieren wir die Komponenten, die wir im vorherigen Abschnitt des Tutorials erstellt haben, und erstellen die Seitenlogik für die Anwendung.


Startseite

Öffnen Sie page.tsx im app Verzeichnis und bearbeiten Sie den Inhalt wie folgt:


 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> ); }


Auf der Startseite rufen wir zunächst die Funktion getPages auf, um die Daten für den Header abzurufen.


Dann verwenden wir die Funktion getValues , um die Hero-Seitendaten abzurufen und sie dann zur einfacheren Verarbeitung in ein pageContent Objekt umzuwandeln.


Anschließend rendern wir die importierten Kopf- und Fußzeilenkomponenten und übergeben die erforderlichen Werte für den Heldentitel, die Beschreibung und das Bild.


Produktseite

Erstellen Sie einen neuen Ordner [category] im app Verzeichnis und darin eine Datei page.tsx .


Die Verwendung spezifischer Dateinamen ist wichtig, da NextJS diese zur Verarbeitung von Routen und zum Zugriff auf URL-Parameter verwendet.


Fügen Sie den folgenden Code in die page.tsx ein:


 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> ); }


Für die Produktseite erhalten wir zunächst den category von der URL, den wir dann an die Funktion getProducts übergeben, um zu beschreiben, welche Kategorie der Produkte wir basierend auf der besuchten Seite der Website abrufen müssen.


Sobald die Daten empfangen wurden, erstellen wir ein Array von Objekten productItems , das zur einfacheren Verarbeitung alle notwendigen Attribute für die Seite enthält.


Dann durchlaufen wir es mit der map Methode und rendern es auf dem Bildschirm, indem wir Requisiten an die Card-Komponente übergeben, die wir aus dem component importiert haben.


Vorschauseite

Erstellen Sie im Ordner [category] einen weiteren Ordner mit dem Namen [productId] .


Öffnen Sie den neu erstellten Ordner und erstellen Sie darin eine Datei page.tsx mit dem 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> ); }


Auf dieser Seite können Benutzer weitere Details zu jedem einzelnen Produkt anzeigen, sobald sie auf der Produktseite auf ihre Karten klicken.


Wir rufen zunächst den Parameter productId von der URL ab, den wir dann an die Funktion getProduct übergeben, um abhängig davon, welches Produkt auf der Vorschauseite angezeigt wird, anzugeben, welches Produkt wir abrufen müssen.


Sobald die Daten empfangen wurden, erstellen wir ein Objekt productItem , das aus allen notwendigen Attributen besteht, die als Requisiten an die Preview-Komponente übergeben werden.


Wir erhalten auch den category , da wir ihn an die Komponente „Zum Warenkorb hinzufügen“ übergeben müssen, damit wir einen gültigen Link für den Artikel auf der Warenkorbseite erstellen können.


Warenkorbseite

Erstellen Sie abschließend einen neuen Ordner cart im app Verzeichnis.


Öffnen Sie es und erstellen Sie darin eine neue Datei page.tsx mit dem folgenden Code:


 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> ); }


Wir haben zuerst die notwendigen Daten abgerufen und sie dann als Requisiten an den Header übergeben.


Dann haben wir die Header-Komponente mit der Navigation gerendert, die Order-Komponente, die alle Artikel auflistet, die der Benutzer dem Warenkorb hinzugefügt hat, und auch die Footer-Komponente mit dem Firmennamen und den Copyright-Informationen.

Testen

Herzlichen Glückwunsch, Sie haben ein funktionierendes Projekt erstellt!


Überprüfen Sie zunächst, ob der Entwicklerserver noch läuft. Ist dies nicht der Fall, führen Sie den Befehl npm run dev aus, um es erneut zu starten, und greifen Sie auf localhost:3000 zu, um es anzuzeigen.


Ihr Projekt sollte nun so aussehen:


Abschließende Projektdurchführung


Wie Sie sehen können, wurde der Inhalt des Home-Abschnitts erfolgreich aus dem Home-Attributsatz abgerufen, den wir in den Datenfeldern angegeben haben.


Außerdem wurden alle Artikel aus dem OneEntry CMS-Katalog in den Abschnitten „Kleidung“ und „Ausrüstung“ abgerufen, wobei alle Informationen ordnungsgemäß wiedergegeben wurden.


Dank der Routenverwaltung und Produktparameter von NextJS können Benutzer auch jedes Produkt einzeln auf einer speziellen Seite in der Vorschau anzeigen.


Außerdem funktionieren alle Funktionen und Ereignisse wie erwartet und der Benutzer kann die Artikel zum Warenkorb hinzufügen und daraus entfernen, wobei die Gesamtsumme berechnet wird.

Abschluss

In diesem Tutorial haben wir ein E-Commerce-Projekt erstellt, das es Benutzern dank OneEntry CMS ermöglicht, Website-Seiten und deren Inhalte zu erstellen, zu aktualisieren und zu löschen sowie Produkte einfach über eine benutzerfreundliche Katalogoberfläche zu verwalten.


Der Code ist auf GitHub verfügbar. Sie können ihn also gerne klonen und je nach Bedarf weitere Funktionen hinzufügen. Sie könnten weitere Menüabschnitte hinzufügen, einzelne Komponenten erweitern oder sogar weitere Komponenten hinzufügen, um neue Funktionen zu implementieren.


Hoffentlich ist dies für Sie nützlich und Sie erhalten einen Einblick in die Verwendung von OneEntry CMS als Backend-Lösung, wie Sie es mit dem Frontend Ihrer Anwendung koppeln und wie Sie die besten Funktionen von NextJS, Typescript und Tailwind nutzen .


Stellen Sie sicher, dass Sie die besten Ressourcen, Tools, Produktivitätstipps und Tipps zur Karriereentwicklung erhalten, die ich entdecken kann, indem Sie meinen Newsletter abonnieren!


Vernetzen Sie sich auch mit mir auf Twitter , LinkedIn und GitHub !


Auch hier veröffentlicht