feat(saleor): Phase 2 - Product Migration

- Update ProductCard to use Saleor Product type
- Update products listing page to fetch from Saleor
- Update product detail page with Saleor integration
- Add language switching support (SR/EN)
- Add SEO metadata generation
- Implement static params generation for all product slugs
- Add availability checking based on variant quantity
This commit is contained in:
Unchained
2026-03-21 12:38:24 +02:00
parent 7b94537670
commit 5706792980
3 changed files with 160 additions and 48 deletions

View File

@@ -3,15 +3,20 @@
import { motion } from "framer-motion";
import Image from "next/image";
import Link from "next/link";
import { WooProduct, formatPrice, getProductImage } from "@/lib/woocommerce";
import type { Product } from "@/types/saleor";
import { getProductPrice, getProductImage, getLocalizedProduct } from "@/lib/saleor";
interface ProductCardProps {
product: WooProduct;
product: Product;
index?: number;
locale?: string;
}
export default function ProductCard({ product, index = 0 }: ProductCardProps) {
export default function ProductCard({ product, index = 0, locale = "SR" }: ProductCardProps) {
const image = getProductImage(product);
const price = getProductPrice(product);
const localized = getLocalizedProduct(product, locale);
const isAvailable = product.variants?.[0]?.quantityAvailable > 0;
return (
<motion.div
@@ -20,29 +25,31 @@ export default function ProductCard({ product, index = 0 }: ProductCardProps) {
viewport={{ once: true }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Link href={`/products/${product.slug}`} className="group block">
<Link href={`/products/${localized.slug}`} className="group block">
<div className="relative aspect-[4/5] bg-background-ice overflow-hidden mb-4">
{image && (
<Image
src={image}
alt={product.name}
alt={localized.name}
fill
className="object-cover transition-transform duration-500 group-hover:scale-105"
/>
)}
{product.stock_status === "outofstock" && (
{!isAvailable && (
<div className="absolute inset-0 bg-black/50 flex items-center justify-center">
<span className="text-white font-medium">Out of Stock</span>
<span className="text-white font-medium">
{locale === "en" ? "Out of Stock" : "Nema na stanju"}
</span>
</div>
)}
</div>
<h3 className="font-serif text-lg mb-1 group-hover:text-accent-dark transition-colors">
{product.name}
{localized.name}
</h3>
<p className="text-foreground-muted">
{product.price ? formatPrice(product.price) : "Contact for price"}
{price || (locale === "en" ? "Contact for price" : "Kontaktirajte za cenu")}
</p>
</Link>
</motion.div>