Antes de começar vamos criar alguns componentes antes para nosso código ficar mais organizado.
Criando o componente de card de produto
Dentro da pasta components
crie um arquivo ProductCard.vue
e cole o seguinte código:
<script setup lang="ts">
defineProps<{
image: string;
title: string;
price: number;
handle: string;
variantId: string;
}>()
</script>
<template>
<nuxt-link :to="{path: `/produtos/${handle}`, query: {variant: variantId}}" class="cursor-pointer group">
<div class="w-full h-auto aspect-[16/12] overflow-hidden rounded-lg">
<img :src="image" :alt="title" class="w-full h-full object-center object-cover group-hover:scale-105 transition">
</div>
<div class="py-4 px-4">
<h3 class="mb-1">
{{ title }}
</h3>
<div class="font-bold">
{{ new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(price) }}
</div>
</div>
</nuxt-link>
</template>
Uma coisa interessante desse componente de produto que criamos é que, o link que o usuário vai ser redirecionado ao clicar no card, contém duas propriedades: uma chamada handle
que é a URL do produto (exemplo: se o nome do produto é Camisa Florida, a url vai ser camisa-florida para ajudar no SEO) e outra propriedade chamada variant
que vai pré selecionar a variante do produto ao carregar a página.
Essa variant
define as opções do produto, ou seja, se o produto tem "Tamanho" e "Cor", a variante vai selecionar um tamanho e cor automaticamente quando o usuário clicar no card.
Criando a página inicial da loja
Dentro do projeto medusa-storefront
crie uma pasta chamada pages
, dentro dessa pasta crie um arquivo index.vue
e cole o seguinte código:
<script setup lang="ts">
const client = useMedusaClient();
const { products } = await client.products.list();
</script>
<template>
<section class="h-screen relative mb-20">
<div class="items-center container relative h-full grid grid-cols-2">
<div class="py-20 flex-1 pr-10">
<h1 class="text-6xl font-extrabold text-zinc-900 mb-4">
Bota na cabeça que estilo não é marra
</h1>
<p class="flex-1 text-zinc-600 text-base mb-10">
Usando a nova coleção da Umbrella você fica pronto para qualquer tempestade.
</p>
<nuxt-link to="/colecoes">
<Button size="lg">
Nova Coleção
</Button>
</nuxt-link>
</div>
</div>
<div class="absolute w-full h-full top-0 left-0 grid grid-cols-2 pointer-events-none">
<div class="col-start-2 w-full h-full overflow-hidden">
<img src="/hero.png" class="w-full h-full object-center object-cover" />
</div>
</div>
</section>
<section class="container my-40">
<h2 class="font-extrabold mb-4 text-3xl">
Só no precinho 🔥
</h2>
<div class="grid grid-cols-[repeat(auto-fill,_minmax(280px,_1fr))] gap-4">
<ProductCard v-for="product in products"
:key="product.id"
:image="product.images ? product.images[0].url : ''"
:title="(product.title as string)"
:price="product.variants[0].prices[0].amount / 100"
:handle="(product.handle as string)"
:variant-id="(product.variants[0].id as string)"
/>
</div>
</section>
</template>
Perceba que chamamos a função client.products.list()
para acessar a api e listar os produtos
Além disso nós estamos usando um componente <Button></Button>
que instalamos nas aulas anteriores com o shadcn.
Para finalizar também chamamos o componente <ProductCard></ProductCard>
com um v-for
para listar todos os cards de produto na parte inferior da página inicial.