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.
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.
Açılış sayfası başlık başlığını gösterecek, mağazanın özelliklerini listeleyecek ve kahraman görselini içerecektir.
İlk mağaza bölümü Giyim'e ayrılacak.
İkinci mağaza bölümü Gear'ı içerecektir.
Öğelerin her birinin ayrıntıları içeren ayrı bir Önizleme sayfası olacaktır.
Zaten sepette bulunan ürünler, bunları kaldırma seçeneğine sahip olacaktır.
Sepet seçilen tüm öğeleri listeleyecek ve toplamı hesaplayacaktır.
Ö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 .
Bundan sonra oturum açın ve OneEntry kontrol paneline yönlendirileceksiniz.
Yeni bir proje oluşturarak başlayın.
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.
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.
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.
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.
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.
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:
Oluşturulduktan sonra aşağıdaki ekran görüntüsündeki gibi görünecektir:
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.
Ş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.
Ş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:
Daha sonra aynı yapıyı kullanacak olan Gear sayfası için de aynısını yapın:
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:
Ana Sayfa için düzenle düğmesine tıklayın. Bundan sonra Yatay menüdeki Nitelikler sekmesine tıklayın:
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.
Ş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:
Şimdi, Giyim için Ekle simgesine tıklayın ve birkaç öğe ekleyin.
Öncelikle eklemek istediğiniz Ürünün Başlığını ekleyin.
Şimdi Nitelikler sekmesine geçin, Nitelikler Grubu için Giyim'i seçin ve gerekli verileri doldurun.
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'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.
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.
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:
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:
Ş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;
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.
Ş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.
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.
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.
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.
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:
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.
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ı