paint-brush
Bir e-Ticaret Mağazası Oluşturmak için NextJS, TypeScript, Tailwind ve OneEntry CMS Nasıl Kullanılır 🛒👨‍💻ile@madzadev
1,553 okumalar
1,553 okumalar

Bir e-Ticaret Mağazası Oluşturmak için NextJS, TypeScript, Tailwind ve OneEntry CMS Nasıl Kullanılır 🛒👨‍💻

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

Çok uzun; Okumak

NextJS, TypeScript, Tailwind CSS ve OneEntry CMS'nin birlikte nasıl çalıştığını ve bunların içerik yönetimini basitleştirmek için nasıl kullanılabileceğini görmek için pratik bir e-Ticaret projesi oluşturacağız.
featured image - Bir e-Ticaret Mağazası Oluşturmak için NextJS, TypeScript, Tailwind ve OneEntry CMS Nasıl Kullanılır 🛒👨‍💻
Madza HackerNoon profile picture
0-item

giriiş

Bu, OneEntry CMS'nin sponsor olduğu bir ortaklık makalesidir.


Bir e-Ticaret uygulaması oluşturmak genellikle zorlu bir iştir. Bu kadar çok alternatif varken projenin gereksinimlerine, ölçeklenebilirlik ihtiyaçlarına ve uzun vadeli sürdürülebilirliğe uygun bir teknoloji yığını seçmek kolay değil.


Bir diğer önemli nokta ise e-Ticaret projelerinin çok fazla veri ve CRUD işlemiyle uğraşmasıdır. Sağlam, ölçeklenebilir ve güvenli bir arka uç sistemi oluşturmak, çoğu deneyimli geliştirici için bile çok zaman alabilir.


NextJS, TypeScript, Tailwind CSS ve OneEntry CMS'yi temel alan bir teknoloji yığını seçtim. Birlikte nasıl çalıştığını ve içerik yönetimini basitleştirmek için nasıl kullanılabileceğini görmek için kendimiz pratik bir e-Ticaret projesi oluşturacağız.


Bu projenin kodu GitHub deposunda mevcut olacak.

Tech Stack Seçimi

NextJS, istemci ve sunucu oluşturma, veri getirme, rota işleyicileri, ara yazılım, yerleşik optimizasyonlar ve çok daha fazlası gibi özelliklerle birlikte gelen, hızlı ve verimli web uygulamaları oluşturmaya yönelik bir React çerçevesidir.


TypeScript, JavaScript'e statik yazma özelliği ekleyerek e-Ticaret gibi ölçeklenebilir projelerde hataları yakalamayı ve düzeltmeyi kolaylaştırır. Ayrıca otomatik tamamlama ve yeniden düzenleme yardımı gibi özellikler aracılığıyla verimliliği artırır.


Tailwind CSS, web uygulamalarının stil oluşturma bölümünü hızlandırarak geliştiricilerin, harici CSS dosyaları arasında geçiş yapmaya ve her biri için sınıf adları bulmaya gerek kalmadan işaretleme içindeki öğelere stil vermelerine olanak tanır.


OneEntry CMS, web sitesi içeriği oluşturma ve yönetim deneyiminde üretkenliğinizi artırmak için kullanımı kolay bir arayüze, kolayca ölçeklendirilebilen arka uca, hızlı API'ye ve net belgelere sahip, başsız bir içerik yönetim sistemidir.

İçerik ve Tasarım

Açılış sayfası başlık başlığını gösterecek, mağazanın özelliklerini listeleyecek ve kahraman görselini içerecektir.


E-ticaret mağazası ana sayfası


İlk mağaza bölümü Giyim'e ayrılacak.


E-ticaret mağazası ürünleri sayfası


İkinci mağaza bölümü Gear'ı içerecektir.


E-ticaret mağazası ürünleri sayfa #2


Öğelerin her birinin ayrıntıları içeren ayrı bir Önizleme sayfası olacaktır.


E-ticaret mağazası ürün önizleme sayfası


Zaten sepette bulunan ürünler, bunları kaldırma seçeneğine sahip olacaktır.


E-ticaret mağazası ürün önizleme sayfası #2


Sepet seçilen tüm öğeleri listeleyecek ve toplamı hesaplayacaktır.


E-ticaret mağaza sepeti sayfası

OneEntry Projesi Oluşturun

Öncelikle kullanıcının yeni bir hesaba kaydolması gerekecektir. Bunu yapmak için OneEntry ana sayfasına gidin ve e-posta hesabınızla kaydolun .


OneEntry kayıt sayfası


Bundan sonra oturum açın ve OneEntry kontrol paneline yönlendirileceksiniz.


Yeni bir proje oluşturarak başlayın.


OneEntry kontrol paneli sayfası


Bir ay boyunca Çalışma planını kullanmak için ücretsiz kod alacaksınız. Projenin oluşturulma sürecinde etkinleştirme şansınız olacak.


OneEntry proje sayfası


Projenin oluşturulması birkaç dakika sürecektir. Hazır olduğunda proje durumu "Çalışıyor" olarak değişecek ve durum göstergesi yeşil olacaktır.


OneEntry kontrol paneli sayfası

Sayfaları Oluşturma

Proje oluşturulduktan sonra, uygulama verilerini oluşturmak ve depolamak üzere CMS portalınıza erişmeniz için oturum açma ayrıntılarını içeren bir e-posta alacaksınız.


OneEntry CMS giriş sayfası


Giriş yaptıktan sonra ilk sayfanızı oluşturabileceksiniz.


İçerik Yönetimi'ne gidin, Yeni sayfa oluştur'a tıklayın ve gerekli tüm verileri (sayfa türleri, sayfa başlığı, sayfa ULR'si ve menü öğesinin adı) doldurun.


OneEntry CMS - sayfayı düzenleme


Tüm veriler girildiğinde otomatik olarak kaydedilir.


Ev, Giyim, Ekipman ve Sepet için 4 farklı sayfa oluşturun. Sayfalar oluşturulduktan sonra aşağıdaki ekran görüntüsündeki gibi görünmelidir.


OneEntry CMS sayfaları listesi

Nitelikler Oluştur

Daha sonra saklayacağımız veri yapısını oluşturmamız gerekiyor. OneEntry CMS'de bu, verilere ilişkin niteliklerin oluşturulmasıyla gerçekleştirilir.


Ayarlar'a gidin ve yatay menüden Nitelikler'i seçin. Ana sayfa için adı, işaretçiyi ve türü sağlayan bir özellik seti oluşturun:


OneEntry CMS sayfa türleri


Oluşturulduktan sonra aşağıdaki ekran görüntüsündeki gibi görünecektir:


OneEntry CMS sayfa özellikleri


Benzer şekilde Giyim ve Teçhizat için iki ayrı özellik seti oluşturalım. Oluşturulduktan sonra sonuç aşağıdaki ekran görüntüsündeki gibi görünmelidir.


OneEntry CMS özellikleri #2


Şimdi her küme için belirli nitelikleri tanımlayalım.


Daha önce Ana Sayfa bölümünde tel çerçeveye eklediğimiz içeriğe dayanarak başlığı, açıklamayı ve resmi görüntülemek istiyoruz.


Ana Sayfa için dişli öğesine tıklayın ve aşağıdaki listede gösterildiği gibi aşağıdaki özellik adlarını, işaretçileri ve özellik türlerini oluşturun.


OneEntry CMS sayfası ayarları


Şimdi geri dönün ve Giyim için dişli simgesine tıklayın.


Ürün başlığını, alt başlığını, açıklamasını, resmini ve fiyatını görüntülemek istediğimiz için bu sayfanın özellikleri biraz farklı olacaktır.


Öznitelik yapısının nasıl görüneceği aşağıda açıklanmıştır:


OneEntry CMS sayfa özellikleri


Daha sonra aynı yapıyı kullanacak olan Gear sayfası için de aynısını yapın:


OneEntry CMS sayfa özellikleri #2

İçerik Ekle

Projenin bu aşamasında içerik yapısını zaten tanımladık ve içeriğin kendisini oluşturmaya başlamaya hazırız.


Daha önce site için tüm sayfalarınızı oluşturduğunuz İçerik Yönetimi bölümüne gidin:


OneEntry CMS sayfaları listesi


Ana Sayfa için düzenle düğmesine tıklayın. Bundan sonra Yatay menüdeki Nitelikler sekmesine tıklayın:


OneEntry CMS özniteliklerini seç


Nitelikler kümesi için Ana Sayfa'yı seçin. Bu, daha önce Ana Sayfa Ayarlarında oluşturduğumuz tüm özellikleri yükleyecektir.


Şimdi Ana sayfada görüntülenmesini istediğiniz bazı örnek verileri girin.


OneEntry CMS içeriği oluşturma


Şimdi Giyim ve Teçhizat sayfalarımıza biraz içerik ekleyelim.


Sayfa türünü Katalog olarak seçtiğimiz için soldaki menüden Katalog'u seçin; burada her iki sayfanın da görünmesi gerekir:


OneEntry CMS kataloğu


Şimdi, Giyim için Ekle simgesine tıklayın ve birkaç öğe ekleyin.


Öncelikle eklemek istediğiniz Ürünün Başlığını ekleyin.


OneEntry CMS katalog başlığı


Şimdi Nitelikler sekmesine geçin, Nitelikler Grubu için Giyim'i seçin ve gerekli verileri doldurun.


OneEntry CMS ürün ekleme


Katalog menüsüne geri dönün ve hem Giyim hem de Teçhizat için birkaç öğeye daha bakın. Demo uygulamamız için aşağıdaki ekran görüntüsünde gösterildiği gibi 4 öğe ekledim:


OneEntry CMS ürün listeleri

API Erişim Jetonu Oluşturun

OneEntry CMS'de oluşturulan tüm veriler korunmaktadır, dolayısıyla bunlara erişebilmek için özel bir belirteç oluşturmamız gerekecektir.


Bunu yapmak için Ayarlar'a gidin ve Uygulama belirteçleri'ni seçin. Uygulama adını ve son kullanma tarihini girin ve Oluştur'a tıklayın. Bu benzersiz bir API anahtarı oluşturacaktır.


OneEntry CMS - uygulama belirteci oluşturun


Eylem listesindeki görünüm simgesini tıkladığınızda anahtarı görebileceksiniz. Öğreticinin bir sonraki bölümünde ihtiyacımız olacağı için panoya kopyalayın.


OneEntry CMS - uygulama belirtecini kopyala

NextJS Projesini Kurma

Eğitimin bu bölümünde kodla çalışmaya başlayacağız ve NextJS projesini OneEntry CMS ile çalışacak şekilde yapılandıracağız.


Terminali açın ve npx create-next-app@latest komutunu çalıştırın.


CLI kurulum sihirbazını başlatacaktır. Projenizin adını girin ve aşağıda gösterildiği gibi tüm varsayılan değerleri seçin:


Terminalde NextJS kurulum sihirbazı


Kurulumun tamamlanması için bir dakika verin; NextJS uygulaması oluşturulduğunda bir bildirim alacaksınız.


Bundan sonra, cd winter-sports komutunu kullanarak dizini yeni oluşturulan klasörle değiştirin ve ardından geliştirici sunucusunu başlatmak için npm run dev komutunu çalıştırın.


Erişmek için terminalde verilen bağlantıya tıklayın veya web tarayıcınızı açın ve manuel olarak http://localhost:3000 adresine gidin.


NextJS geliştirici sunucusu açılış sayfası size sunulmalıdır:


NextJS geliştirici sunucusu önizlemesi


Şimdi uygulamamız için ihtiyaç duyacağımız çevresel değeri yaratalım. Kod düzenleyicinize geri dönün ve projenizin kökünde bir .env dosyası oluşturun.


Daha önce panoya kopyaladığınız API anahtarını aşağıdaki gibi yapıştırın:


 API_KEY=your-api-code-from-oneentry


Bu, OneEntry CMS'den veri almak için API çağrıları yaptığımızda, process.env.API_KEY aracılığıyla anahtara erişmemize olanak tanıyacaktır.


Ayrıca NextJS'yi de yapılandırmamız gerekiyor, böylece medyayı harici bir etki alanından dahil etmemize olanak tanıyor. OneEntry CMS'deki görsellere erişmek için buna ihtiyacımız olacak.


Proje kökünde next.config.js dosyasını açın ve aşağıdaki şekilde düzenleyin:


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


Son olarak, tüm stilleri sıfırdan yazacağımız için uygulamanın Tailwind varsayılan stilini sıfırlamamız gerekecek.


src klasöründe bulunan app dizininde globals.css dosyasını açın ve dosya içeriğini aşağıdaki şekilde değiştirin:


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

Türler Oluştur

TypeScript ile çalışacağımız için uygulamamızda hangi veri türlerini kullanacağımızı tanımlamamız gerekecek.


Bunu sayfaların ve bileşenlerin içinde yapabiliriz, ancak kodu daha temiz tutmak ve tekrarı önlemek için app dizininde yeni bir arayüz interfaces oluşturun. Yeni oluşturulan klasörün içinde bir data.tsx dosyası oluşturun ve kodu ekleyin:


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


Ürünler ve Sayfa verileri, hem ön uç oluşturma veri yapısına hem de getirme yöntemi aracılığıyla API'den gelen yanıta yönelik türlere sahip olacaktır.


Ayrıca CMS'de URL parametrelerinden gelen veriler için veri türlerini, metin giriş alanlarından alınan veriler için ise Metin oluşturucuyu tanımladık.

API Getirme İşlevleri Oluşturun

Şimdi sayfalara ve ürünlere ilişkin verileri getirmek üzere OneEntry CMS ile iletişim kurmak için kullanacağımız bazı işlevleri oluşturalım.


Yine, bunu her dosyada yapabiliriz, ancak kodu daha temiz tutmak için, app dizini içinde içinde fetchData.tsx dosyası bulunan yeni bir services klasörü oluşturalım:


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


getPages işlevi, OneEntry CMS'de oluşturduğumuz tüm sayfalarla ilgili verileri getirecektir.


getProducts işlevi, category parametresine dayalı olarak belirli bir ürün koleksiyonuna ilişkin verileri getirecektir. Fonksiyonu ürünler sayfasına aktardığımızda parametreyi geçeceğiz.


getProduct işlevi, açtığımız ürünün id göre verileri getirecektir. Herhangi bir belirli ürünün önizleme sayfasına işlevi aktardığımızda parametreyi ileteceğiz.


OneEntry CMS erişimini doğrulamak amacıyla daha önce .env dosyasında tanımladığımız API anahtarına erişmek için process.env.API_KEY kullandığımıza dikkat edin.

Yardımcı İşlevler Oluşturun

Ayrıca, hâlâ services klasöründeyken, içinde helpers.tsx adında küçük yardımcı işlevler içeren yeni bir dosya oluşturalım:


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


calculateTotal işlevi, sepete eklenen ürünlerin fiyatlarını toplayacak ve toplam değeri döndürecektir.


boughtStatus önizleme rotasındaki bireysel öğelerin zaten sepete eklenip eklenmediğini tespit edecektir.


cartIndex sepete eklenen ürünler için dizideki ürünün konumunu tespit edecektir.

Bileşenler Oluşturma

app dizinine geri dönün ve içinde yeni bir klasör components oluşturun.


Yeni oluşturulan klasörü açın ve içine yedi ayrı dosya ekleyin: Header.tsx , Footer.tsx , Text.tsx , Card.tsx , Preview.tsx , Order.tsx , AddToCart.tsx .


Başlık bileşeni

Header.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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

Başlık için şirket adını görüntüledik ve bileşen sayfalara aktarıldığında API'den alacağımız gezinme bağlantılarını döngüye aldık.


İki sütunlu bir düzen oluşturduk ve tipik gezinme görünümünü elde etmek için her iki öğeyi de ekranın karşıt taraflarına yatay olarak yerleştirdik.


Altbilgi bileşeni

Footer.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


Altbilgide şirkete ait örnek adı ve içerik haklarını cari yılla birlikte ekledik. İçeriği ortaladık ve biraz dolgu ekledik.


Metin bileşeni

Text.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


Metin bileşeni, OneEntry CMS'den aldığımız metin verilerini oluşturacak ve uygulamamızda HTML etiketleri olmadan düzgün bir şekilde görüntüleyecektir.


Kart bileşeni

Card.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


Kart bileşeninde her ürünün görselini, başlığını, alt başlığını ve fiyatını gösterdik. Sayfalara aktarıldıktan sonra tüm öğelerin haritasını çıkaracağız.


Resim, kartın üst kısmında görüntülenecek, ardından başlık ve açıklama ve bileşenin sağ alt tarafında fiyat görüntülenecektir.


Önizleme bileşeni

Preview.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


Önizleme bileşeni, kullanıcı tıkladığında her ürün hakkında daha fazla bilgi görüntülemek için kullanılacaktır.


Ürün görselini, başlığını, fiyatını ve açıklamasını göstereceğiz. Düzen, sol sütunda resim ve sağda içeriğin geri kalanı görüntülenecek şekilde 2 sütuna bölünecektir.


Sipariş bileşeni

Order.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


Sipariş bileşeni, kullanıcının sepete eklediği tüm ürünleri listeleyecektir. Her öğe için resim, başlık, alt başlık ve fiyat görüntülenecektir.


Bileşen oluşturulduktan sonra uygulama, o anda sepette bulunan tüm öğelere erişecek, bunları cardItems durum değişkenine ayarlayacak ve bunları map yöntemi aracılığıyla ekrana aktaracaktır.


Oluşturulan öğelerin toplam miktarı, helpers.tsx dosyasından içe aktardığımız calculateTotal işlevi aracılığıyla hesaplanacaktır.


AddToCart bileşeni

AddToCart.tsx dosyasını açın ve aşağıdaki kodu ekleyin:


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


addToCart bileşeni, bireysel ürün önizleme sayfasında görüntülenecek ve kullanıcının ürünü alışveriş sepetine eklemesine olanak tanıyacaktır.


Oluşturma sonrasında isPurchased işlevi, ürünün daha önce sepete eklenip eklenmediğini tespit edecektir. Oluşturulan düğme değilse "Sepete ekle" görüntülenir, aksi takdirde "Sepete kaldır" yazacaktır.


handleButtonClick işlevi tıklama özelliği, yukarıdaki duruma göre ürünü öğeler dizisine ekleyecek veya bu diziden kaldıracaktır.

Sayfa Oluştur

Son olarak öğreticinin önceki bölümünde oluşturduğumuz bileşenleri içe aktaralım ve uygulamanın sayfa mantığını oluşturalım.


Ana sayfa

app dizininde page.tsx dosyasını açın ve içeriğini aşağıdaki gibi düzenleyin:


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


Ana sayfada, Başlığa ilişkin verileri almak için ilk önce getPages işlevini çağıracağız.


Daha sonra Hero sayfası verilerini getirmek için getValues işlevini kullanırız ve ardından bunları daha kolay işlenmesi için pageContent nesnesine dönüştürürüz.


Daha sonra içe aktarılan Üstbilgi ve Altbilgi bileşenlerini oluşturuyoruz ve ayrıca Kahraman başlığı, açıklaması ve görseli için gerekli değerleri iletiyoruz.


Ürünler sayfası

app dizininde ve içinde yeni bir klasör [category] oluşturun - page.tsx dosyası.


Belirli dosya adlarının kullanılması önemlidir çünkü NextJS, rotaları yönetmek ve URL parametrelerine erişmek için bu adı kullanır.


Aşağıdaki kodu page.tsx dosyasına ekleyin:


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


Ürünler sayfası için, sitenin hangi sayfasının ziyaret edildiğine bağlı olarak hangi ürün kategorisini getirmemiz gerektiğini açıklamak için önce URL'den category parametresini alırız ve bunu ayrıca getProducts işlevine aktarırız.


Veriler alındıktan sonra, daha kolay işlenmesi için sayfanın gerekli tüm niteliklerini içeren bir ürün productItems dizisi yaratırız.


Daha sonra map metodu ile döngü yapıp, component klasöründen içe aktardığımız Card bileşenine props'ı geçirerek ekrana aktarıyoruz.


Önizleme sayfası

[category] klasörünün içinde [productId] adında başka bir klasör oluşturun.


Yeni oluşturulan klasörü açın ve içinde aşağıdaki kodu içeren bir page.tsx dosyası oluşturun:


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


Bu sayfa, kullanıcıların ürünler sayfasındaki kartlarına tıkladıklarında herhangi bir ürün için daha fazla ayrıntı görmesine olanak tanıyacaktır.


Önizleme sayfasında hangi ürünün görüntülendiğine bağlı olarak hangi ürünü getirmemiz gerektiğini belirtmek için önce URL'den productId parametresini alırız ve bunu daha sonra getProduct işlevine aktarırız.


Veriler alındıktan sonra, Önizleme bileşenine destek olarak aktarılacak tüm gerekli özniteliklerden oluşan bir ürün productItem yaratırız.


Ayrıca category parametresini de alıyoruz, çünkü bunu Sepete Ekle bileşenine aktarmamız gerekiyor, böylece Sepet sayfasındaki ürün için geçerli bir bağlantı oluşturabiliriz.


Sepet sayfası

Son olarak app dizininde yeni bir klasör cart oluşturun.


Açın, içinde aşağıdaki kodla yeni bir page.tsx dosyası oluşturun:


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


Önce gerekli verileri getirdik ve ardından bunları sahne donanımı olarak Başlığa aktardık.


Daha sonra navigasyonlu Başlık bileşenini, kullanıcının sepete eklediği tüm ürünleri listeleyecek Sipariş bileşenini ve ayrıca şirket adının ve telif hakkı bilgilerinin yer aldığı Altbilgi bileşenini render ettik.

Test yapmak

Tebrikler, çalışan bir proje yaptınız!


Öncelikle geliştirici sunucusunun hala çalışıp çalışmadığını kontrol edin. Değilse, yeniden başlatmak için npm run dev komutunu çalıştırın ve görüntülemek için localhost:3000'e erişin.


Projeniz artık şöyle görünmeli:


Nihai proje özeti


Görüldüğü gibi veri alanlarında belirttiğimiz Home öznitelik setinden Home bölümü içeriği başarıyla getirildi.


Ayrıca OneEntry CMS kataloğundaki tüm öğeler, tüm bilgiler doğru şekilde aktarılarak Giyim ve Teçhizat bölümlerine getirildi.


Kullanıcılar ayrıca NextJS rota işleme ve ürün parametreleri sayesinde her ürünü kendi özel sayfasında ayrı ayrı önizleyebilir.


Ayrıca, tüm işlevler ve olaylar beklendiği gibi çalışır ve kullanıcı, toplam hesaplanarak alışveriş sepetine ürün ekleyip çıkarabilir.

Çözüm

Bu eğitimde, OneEntry CMS sayesinde kullanıcıların web sitesi sayfalarını ve içeriklerini oluşturmasına, güncellemesine ve silmesine ve ayrıca ürünleri kullanımı kolay bir katalog arayüzü ile kolayca yönetmesine olanak tanıyan bir e-Ticaret projesi oluşturduk.


Kod GitHub'da mevcuttur, bu nedenle onu kopyalamaktan ve ihtiyaçlarınıza uyacak şekilde daha fazla işlevsellik eklemekten çekinmeyin. Daha fazla menü bölümü ekleyebilir, tek tek bileşenleri genişletebilir ve hatta yeni özellikleri uygulamak için daha fazla bileşen ekleyebilirsiniz.


Umarız bu sizin için yararlı olur ve OneEntry CMS'yi arka uç çözümü olarak nasıl kullanacağınız, uygulamanızın ön ucuyla nasıl eşleştireceğiniz ve NextJS, Typescript ve Tailwind'in en iyi özelliklerini nasıl kullanacağınız konusunda fikir sahibi olursunuz. .


Bültenime abone olarak keşfettiğim en iyi kaynakları, araçları, üretkenlik ipuçlarını ve kariyer geliştirme ipuçlarını aldığınızdan emin olun!


Ayrıca benimle Twitter , LinkedIn ve GitHub üzerinden bağlantı kurun!


Burada da yayınlandı