paint-brush
Como usar NextJS, TypeScript, Tailwind e OneEntry CMS para construir uma loja de comércio eletrônico 🛒👨‍💻by@madzadev
1,519
1,519

Como usar NextJS, TypeScript, Tailwind e OneEntry CMS para construir uma loja de comércio eletrônico 🛒👨‍💻

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

Construiremos um projeto prático de comércio eletrônico para ver como NextJS, TypeScript, Tailwind CSS e OneEntry CMS funcionam juntos e como podem ser usados para simplificar o gerenciamento de conteúdo.
featured image - Como usar NextJS, TypeScript, Tailwind e OneEntry CMS para construir uma loja de comércio eletrônico 🛒👨‍💻
Madza HackerNoon profile picture
0-item

Introdução

Este é um artigo de parceria patrocinado pela OneEntry CMS .


Construir um aplicativo de comércio eletrônico costuma ser uma tarefa desafiadora. Com tantas alternativas disponíveis, não é fácil escolher uma pilha de tecnologia que atenda aos requisitos do projeto, às necessidades de escalabilidade e à sustentabilidade a longo prazo.


Outro ponto crucial é que os projetos de comércio eletrônico lidam com muitos dados e operações CRUD. Criar um sistema back-end sólido, escalável e seguro pode levar muito tempo, mesmo para os desenvolvedores mais experientes.


Escolhi uma pilha de tecnologia baseada em NextJS, TypeScript, Tailwind CSS e OneEntry CMS. Nós mesmos construiremos um projeto prático de comércio eletrônico para ver como ele funciona em conjunto e como pode ser usado para simplificar o gerenciamento de conteúdo.


O código deste projeto estará disponível no repositório GitHub .

A escolha da pilha de tecnologia

NextJS é uma estrutura React para construção de aplicativos web rápidos e eficientes, que vem com recursos como renderização de cliente e servidor, busca de dados, manipuladores de rota, middleware, otimizações integradas e muito mais.


TypeScript adiciona digitação estática ao JavaScript, o que torna mais fácil detectar e corrigir erros em projetos escalonáveis como comércio eletrônico. Ele também aumenta a produtividade por meio de recursos como preenchimento automático e assistência à refatoração.


Tailwind CSS acelera a parte de estilo dos aplicativos da web, permitindo que os desenvolvedores estilizem os elementos dentro da marcação sem a necessidade de alternar entre arquivos CSS externos e criar os nomes de classe para cada um.


OneEntry CMS é um sistema de gerenciamento de conteúdo headless com uma interface fácil de usar, back-end facilmente escalonável, API rápida e documentação clara para aumentar sua produtividade na criação de conteúdo de site e experiência de gerenciamento.

Conteúdo e Design

A página de destino exibirá o título do título, listará os recursos da loja e incluirá a imagem principal.


Página inicial da loja de comércio eletrônico


A primeira seção da loja será dedicada ao Vestuário.


Página de produtos da loja de comércio eletrônico


A segunda seção da loja incluirá o Gear.


Página 2 de produtos da loja de comércio eletrônico


Cada um dos itens terá uma página de visualização individual com detalhes.


Página de visualização do produto da loja de comércio eletrônico


Os itens que já estão no carrinho terão a opção de removê-los.


Página 2 de visualização do produto da loja de comércio eletrônico


O carrinho listará todos os itens selecionados e calculará o total.


Página do carrinho da loja de comércio eletrônico

Criar projeto OneEntry

Primeiro, o usuário precisará se inscrever em uma nova conta. Para fazer isso, navegue até a página inicial do OneEntry e cadastre-se através de sua conta de e-mail.


Página de inscrição do OneEntry


Depois disso, faça login e você será direcionado para o painel do OneEntry.


Comece criando um novo projeto.


Página do painel OneEntry


Você receberá o código gratuito para usar o plano de estudos por um mês. Você terá a oportunidade de ativá-lo durante o processo de criação do projeto.


Página do projeto OneEntry


A criação do projeto levará alguns minutos. Quando estiver pronto, o status do projeto mudará para “Em funcionamento” e o indicador de status ficará verde.


Página do painel OneEntry

Criando as páginas

Após a criação do projeto, você receberá um e-mail com dados de login para acessar seu portal CMS para criar e armazenar os dados do aplicativo.


Página de login do OneEntry CMS


Após o login, você poderá criar sua primeira página.


Navegue até Gerenciamento de Conteúdo, clique em Criar uma nova página e preencha todos os dados necessários - tipos de páginas, título da página, ULR da página e nome do item de menu.


OneEntry CMS - editar uma página


Todos os dados são salvos automaticamente ao entrar.


Crie 4 páginas diferentes para Casa, Roupas, Equipamentos e Carrinho. Depois de criadas, as páginas deverão ficar como na imagem abaixo.


Lista de páginas do OneEntry CMS

Criar atributos

A seguir, precisamos criar a estrutura de dados que iremos armazenar. No OneEntry CMS, isso é conseguido criando os atributos para os dados.


Navegue até Configurações e escolha Atributos no menu horizontal. Crie um conjunto de atributos para a página inicial fornecendo o nome, o marcador e o tipo:


Tipos de página OneEntry CMS


Depois de criado, ficará como na imagem abaixo:


Atributos da página OneEntry CMS


Da mesma forma, vamos criar dois conjuntos de atributos separados para roupas e equipamentos. Depois de criado, o resultado deve ser semelhante ao da imagem abaixo.


Atributos OneEntry CMS nº 2


Agora, vamos definir atributos específicos para cada conjunto.


Com base no conteúdo que incluímos anteriormente no wireframe da seção Home, queremos exibir o título, a descrição e a imagem.


Clique no item de engrenagem para Home e crie os seguintes nomes de atributos, marcadores e tipos de atributos conforme mostrado na lista abaixo.


Configurações da página OneEntry CMS


Agora volte e clique no ícone de engrenagem para Roupas.


Os atributos desta página serão um pouco diferentes, pois queremos exibir o título, subtítulo, descrição, imagem e preço do produto.


Esta é a aparência da estrutura de atributos:


Atributos da página OneEntry CMS


A seguir, faça o mesmo para a página Gear, que usará a mesma estrutura:


Atributos da página OneEntry CMS nº 2

Adicionar conteúdo

Nesta fase do projeto já definimos a estrutura do conteúdo e estamos prontos para começar a criar o próprio conteúdo.


Navegue até a seção Gerenciamento de conteúdo onde você criou anteriormente todas as páginas do site:


Lista de páginas do OneEntry CMS


Clique no botão de edição para Home. Depois disso, clique na aba Atributos no menu Horizontal:


Atributos de seleção do OneEntry CMS


Selecione Home para o conjunto de atributos. Isso carregará todos os atributos que criamos anteriormente em Configurações da página inicial.


Agora preencha alguns dados de amostra que deseja exibir na página inicial.


Criação de conteúdo CMS OneEntry


Agora, vamos adicionar algum conteúdo para nossas páginas de Roupas e Equipamentos.


Como selecionamos o tipo de página como Catálogo, selecione Catálogo no menu esquerdo e ambas as páginas deverão estar visíveis lá:


Catálogo OneEntry CMS


Agora, clique no ícone Adicionar para Roupas e adicione alguns itens.


Primeiro, adicione o cabeçalho do produto que deseja adicionar.


Cabeçalho do catálogo OneEntry CMS


Agora mude para a guia Atributos, selecione Roupas para o Conjunto de atributos e preencha os dados necessários.


OneEntry CMS adicionar produtos


Volte ao menu Catálogo e mais alguns itens para roupas e equipamentos. Para nosso aplicativo de demonstração, adicionei 4 itens conforme mostrado na captura de tela abaixo:


Listas de produtos OneEntry CMS

Crie um token de acesso à API

Todos os dados criados no OneEntry CMS estão protegidos, portanto teremos que criar um token privado para podermos acessá-los.


Para fazer isso, navegue até Configurações e selecione Tokens de aplicativo. Insira o nome do aplicativo e a data de expiração e clique em Criar. Isso irá gerar uma chave de API exclusiva.


OneEntry CMS - criar token de aplicativo


Clique no ícone de visualização na lista de ações e você poderá ver a chave. Copie-o para a área de transferência, pois precisaremos dele na próxima seção do tutorial.


OneEntry CMS - copiar token do aplicativo

Configurando o projeto NextJS

Nesta seção do tutorial, começaremos a trabalhar com o código e configuraremos o projeto NextJS para funcionar com OneEntry CMS.


Abra o terminal e execute o comando npx create-next-app@latest .


A CLI iniciará o assistente de configuração. Insira o nome do seu projeto e selecione todos os valores padrão conforme mostrado abaixo:


Assistente de configuração NextJS no terminal


Aguarde um minuto para que a configuração seja concluída e você receberá uma notificação quando o aplicativo NextJS for criado.


Depois disso, altere o diretório para a pasta recém-criada usando o comando cd winter-sports e execute npm run dev para iniciar o servidor do desenvolvedor.


Para acessá-lo, clique no link fornecido no terminal ou abra seu navegador e navegue até http://localhost:3000 manualmente.


Você deverá ver a página inicial do servidor do desenvolvedor NextJS:


Visualização do servidor do desenvolvedor NextJS


Agora, vamos criar um valor ambiental que precisaremos para nosso aplicativo. Volte para o seu editor de código e crie um arquivo .env na raiz do seu projeto.


Cole a chave de API que você copiou anteriormente na área de transferência da seguinte maneira:


 API_KEY=your-api-code-from-oneentry


Isso nos permitirá acessar a chave via process.env.API_KEY assim que fizermos as chamadas de API para buscar os dados do OneEntry CMS.


Também precisamos configurar o NextJS, para que possamos incluir a mídia de um domínio externo. Precisaremos disso para acessar imagens do OneEntry CMS.


Abra o arquivo next.config.js na raiz do projeto e edite-o da seguinte forma:


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


Por fim, precisaremos redefinir o estilo padrão do Tailwind para o aplicativo, pois escreveremos todos os estilos do zero.


Abra o arquivo globals.css no diretório app localizado na pasta src e altere o conteúdo do arquivo para o seguinte:


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

Criar tipos

Como trabalharemos com TypeScript, precisaremos definir quais tipos de dados usaremos em nossa aplicação.


Poderíamos fazer isso dentro das páginas e componentes, mas para manter o código mais limpo e evitar repetições, crie uma nova pasta interfaces dentro do diretório app . Crie um arquivo data.tsx dentro da pasta recém-criada e inclua o código:


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


Os dados de produtos e páginas terão tipos para sua estrutura de dados de renderização de front-end e a resposta da API por meio do método de busca.


Além disso, definimos os tipos de dados para os dados dos parâmetros de URL e o renderizador de texto para os dados recebidos dos campos de entrada de texto no CMS.

Criar funções de busca de API

Agora, vamos criar algumas funções que usaremos para nos comunicarmos com o OneEntry CMS para buscar os dados das páginas e produtos.


Novamente, poderíamos fazer isso em cada arquivo, mas para manter o código mais limpo, vamos criar uma nova pasta services dentro do diretório app com um arquivo fetchData.tsx dentro dela:


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


A função getPages irá buscar os dados sobre todas as páginas que criamos no OneEntry CMS.


A função getProducts buscará os dados de uma coleção específica de produtos com base no parâmetro category . Passaremos o parâmetro quando importarmos a função para a página de produtos.


A função getProduct irá buscar os dados com base no id do produto que abrimos. Passaremos o parâmetro quando importarmos a função para a página de visualização de qualquer produto específico.


Observe que usamos process.env.API_KEY para acessar a chave API que definimos no arquivo .env anteriormente para autenticar o acesso ao OneEntry CMS.

Criar funções auxiliares

Além disso, enquanto ainda estamos na pasta services , vamos criar outro novo arquivo dentro dela chamado helpers.tsx que incluirá pequenas funções utilitárias:


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


A função calculateTotal irá somar os preços dos produtos adicionados ao carrinho e retornar o valor total.


O boughtStatus detectará se os itens individuais na rota de visualização já foram adicionados ao carrinho.


O cartIndex detectará a posição do item na matriz dos produtos que foram adicionados ao carrinho.

Criando Componentes

Navegue de volta para o diretório app e crie uma nova pasta de components dentro dele.


Abra a pasta recém-criada e inclua sete arquivos separados nela: Header.tsx , Footer.tsx , Text.tsx , Card.tsx , Preview.tsx , Order.tsx , AddToCart.tsx .


Componente de cabeçalho

Abra o arquivo Header.tsx e inclua o seguinte código:


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

Para o cabeçalho, exibimos o nome da empresa e percorremos os links de navegação que obteremos da API assim que o componente for importado para as páginas.


Criamos um layout de duas colunas e posicionamos ambos os elementos em lados opostos da tela horizontalmente para obter a aparência típica de navegação.


Componente de rodapé

Abra o arquivo Footer.tsx e inclua o seguinte código:


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


No rodapé, incluímos o exemplo do nome da empresa e os direitos do conteúdo do ano em curso. Centralizamos o conteúdo e adicionamos algum preenchimento.


Componente de texto

Abra o arquivo Text.tsx e inclua o seguinte código:


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


O componente Texto renderizará os dados de texto que recebemos do OneEntry CMS e os exibirá corretamente em nosso aplicativo sem tags HTML.


Componente de cartão

Abra o arquivo Card.tsx e inclua o seguinte código:


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


No componente cartão, exibimos imagem, título, subtítulo e preço de cada produto. Mapearemos todos os itens assim que forem importados para as páginas.


A imagem será exibida na parte superior do cartão, seguida do título e da descrição, e o preço no canto inferior direito do componente.


Componente de visualização

Abra o arquivo Preview.tsx e inclua o seguinte código:


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


O componente de visualização será usado para exibir mais informações sobre cada produto assim que o usuário clicar nele.


Exibiremos a imagem do produto, título, preço e descrição. O layout será dividido em 2 colunas, sendo a imagem exibida na coluna da esquerda e o restante do conteúdo na direita.


Componente de pedido

Abra o arquivo Order.tsx e inclua o seguinte código:


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


O componente de pedido listará todos os itens que o usuário adicionou ao carrinho. Para cada item serão exibidos imagem, título, subtítulo e preço.


Depois que o componente for renderizado, o aplicativo acessará todos os itens atualmente no carrinho, os definirá para a variável de estado cardItems e os renderizará na tela por meio do método map .


A quantidade total de itens renderizados será calculada por meio da função calculateTotal , que importamos do arquivo helpers.tsx .


Componente AddToCart

Abra o arquivo AddToCart.tsx e inclua o seguinte código:


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


O componente addToCart será exibido na página de visualização do produto individual e permitirá ao usuário adicionar o produto ao carrinho de compras.


Após a renderização, a função isPurchased detectará se o produto já foi adicionado ao carrinho ou não. Se não for o botão renderizado, será exibido "Adicionar ao carrinho", caso contrário, será exibido "Remover do carrinho".


O recurso de clique da função handleButtonClick adicionará ou removerá o produto da matriz de itens com base no estado acima.

Criar páginas

Por fim, vamos importar os componentes que criamos na seção anterior do tutorial e criar a lógica da página para a aplicação.


Pagina inicial

Abra page.tsx no diretório app e edite seu conteúdo da seguinte maneira:


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


Na página inicial, primeiro chamaremos a função getPages para obter os dados do cabeçalho.


Em seguida, usamos a função getValues para buscar os dados da página Hero e, em seguida, transformá-los no objeto pageContent para facilitar o processamento.


Em seguida, renderizamos os componentes de cabeçalho e rodapé importados, bem como passamos os valores necessários para o título, descrição e imagem do herói.


Página de produtos

Crie uma nova pasta [category] no diretório app e dentro dela - um arquivo page.tsx .


O uso de nomes de arquivos específicos é importante, pois é isso que o NextJS usa para lidar com rotas e acessar parâmetros de URL.


Inclua o seguinte código no page.tsx :


 import Header from "../components/Header"; import Footer from "../components/Footer"; import Card from "../components/Card"; import { getPages, getProducts } from "../services/fetchData"; import { ProductAPI, URLProps } from "../interfaces/data"; export default async function Product({ params }: URLProps) { const { category } = params; const pages = await getPages(); const products = await getProducts(category); const getValues = (products: ProductAPI[]) => { return products.map((el) => { const { producttitle, productsubtitle, productdescription, productimage, productprice, } = el.attributeValues.en_US; return { id: el.id, category: category, title: producttitle.value[0].htmlValue, subtitle: productsubtitle.value[0].htmlValue, description: productdescription.value[0].htmlValue, image: productimage.value[0].downloadLink, price: productprice.value, }; }); }; const productItems = getValues(products.items); return ( <div className="flex flex-col min-h-screen"> <Header pages={pages} /> <div className="mx-auto max-w-screen-xl px-8"> <h2 className="text-4xl text-gray-900 mb-12"> Browse our {category} collection: </h2> <div className="grid gap-x-6 gap-y-10 grid-cols-4 mt-6"> {productItems.map((product) => { return <Card key={product.id} product={product} />; })} </div> </div> <Footer /> </div> ); }


Para a página de produtos, primeiro obtemos o parâmetro category do URL, que posteriormente passamos para a função getProducts , para descrever qual categoria de produtos precisamos buscar com base em qual página do site é visitada.


Uma vez recebidos os dados, criamos um array de objetos productItems que consiste em todos os atributos necessários para a página para facilitar o processamento.


Em seguida, percorremos ele por meio do método map e o renderizamos na tela, passando adereços para o componente Card que importamos da pasta do component .


Página de visualização

Dentro da pasta [category] , crie outra pasta chamada [productId] .


Abra a pasta recém-criada e crie um arquivo page.tsx dentro dela com o código:


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


Esta página permitirá que os usuários vejam mais detalhes de qualquer produto individual assim que clicarem em seus cartões na página de produtos.


Primeiro obtemos o parâmetro productId do URL, que posteriormente passamos para a função getProduct , para especificar qual produto precisamos buscar com base em qual produto é visualizado na página de visualização.


Assim que os dados forem recebidos, criamos um objeto productItem que consiste em todos os atributos necessários para serem passados para o componente Preview como adereços.


Também obtemos o parâmetro category , pois precisamos passá-lo para o componente Adicionar ao carrinho, para que possamos criar um link válido para o item na página do carrinho.


Página do carrinho

Por fim, crie uma nova pasta cart no diretório app .


Abra-o, crie um novo arquivo page.tsx dentro dele com o seguinte código:


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


Primeiro buscamos os dados necessários e depois os passamos para o cabeçalho como adereços.


Em seguida renderizamos o componente Header com a navegação, o componente Order que listará todos os itens que o usuário adicionou ao carrinho e também o componente Footer com o nome da empresa e as informações de copyright.

Teste

Parabéns, você fez um projeto funcional!


Primeiro, verifique se o servidor do desenvolvedor ainda está em execução. Caso contrário, execute o comando npm run dev para iniciá-lo novamente e acesse localhost:3000 para visualizá-lo.


Seu projeto agora deve ficar assim:


Passo a passo do projeto final


Como você pode ver, o conteúdo da seção Home foi obtido com sucesso do conjunto de atributos Home que especificamos nos campos de dados.


Além disso, todos os itens do catálogo OneEntry CMS foram obtidos nas seções Roupas e Equipamentos com todas as informações devidamente renderizadas.


Os usuários também podem visualizar cada produto separadamente em sua página dedicada, graças ao gerenciamento de rotas e parâmetros do produto NextJS.


Além disso, todas as funções e eventos funcionam conforme o esperado, e o usuário pode adicionar e retirar os itens do carrinho de compras, sendo calculado o total.

Conclusão

Neste tutorial, criamos um projeto de comércio eletrônico que permite aos usuários criar, atualizar e excluir páginas do site e seu conteúdo, bem como gerenciar produtos facilmente com uma interface de catálogo fácil de usar, graças ao OneEntry CMS .


O código está disponível no GitHub , então fique à vontade para cloná-lo e adicionar mais funcionalidades para atender às suas necessidades. Você pode adicionar mais seções de menu, estender componentes individuais ou até mesmo adicionar mais componentes para implementar novos recursos.


Esperançosamente, isso será útil para você e você terá uma ideia de como usar o OneEntry CMS como uma solução de back-end, como combiná-lo com o front-end do seu aplicativo e como usar os melhores recursos de NextJS, Typescript e Tailwind .


Certifique-se de receber os melhores recursos, ferramentas, dicas de produtividade e dicas de crescimento de carreira que descobri assinando meu boletim informativo !


Além disso, conecte-se comigo no Twitter , LinkedIn e GitHub !


Também publicado aqui