import { useEffect, useMemo, useState } from 'react' import { Link, useParams } from 'react-router-dom' import { useLocale } from '@meshkee/dashboard-ui' import { Breadcrumbs } from '../components/Breadcrumbs' import { ImageLightbox } from '../components/ImageLightbox' import { ProductDetailsTabs } from '../components/ProductDetailsTabs' import { useT } from '../i18n/useT' import { ApiError } from '../lib/api' import { formatProductCategoryChip, getProduct, mapProductApiToUi, } from '../services/productService' import type { Product } from '../types/product' import { textLocaleAttrs } from '../utils/textLocale' import pageStyles from '../components/PageContent.module.css' import styles from './ProductDetailsPage.module.css' export function ProductDetailsPage() { const t = useT() const { locale } = useLocale() const isFa = locale === 'fa' const { id } = useParams() const [product, setProduct] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState('') const [activeIndex, setActiveIndex] = useState(0) const [lightboxOpen, setLightboxOpen] = useState(false) const [lightboxIndex, setLightboxIndex] = useState(0) useEffect(() => { if (!id) return const controller = new AbortController() async function loadProduct() { setIsLoading(true) setError('') try { const data = await getProduct(id!, controller.signal) setProduct(mapProductApiToUi(data)) setActiveIndex(0) } catch (err) { if (err instanceof DOMException && err.name === 'AbortError') return if (err instanceof ApiError) { setError(err.message) } else { setError(t('products.details.errorLoad')) } setProduct(null) } finally { setIsLoading(false) } } void loadProduct() return () => controller.abort() }, [id, t]) const galleryImages = useMemo(() => product?.images ?? [], [product]) const currentImage = galleryImages[activeIndex] ?? galleryImages[0] ?? '' function openLightbox(index: number) { setLightboxIndex(index) setLightboxOpen(true) } if (isLoading) { return (

{t('products.details.loading')}

) } if (error || !product) { return (

{error || t('products.details.notFound')}

{t('products.details.back')}
) } const primaryName = isFa ? product.nameFa?.trim() || product.nameEn : product.nameEn?.trim() || product.nameFa const secondaryName = isFa ? product.nameEn?.trim() && product.nameEn !== primaryName ? product.nameEn : '' : product.nameFa?.trim() && product.nameFa !== primaryName ? product.nameFa : '' const primaryLocale = textLocaleAttrs(primaryName) const secondaryLocale = textLocaleAttrs(secondaryName) const summaryLocale = textLocaleAttrs(product.summary) const descriptionLocale = textLocaleAttrs( product.description?.replace(/<[^>]+>/g, ' ') ?? '', ) const categoryLabel = formatProductCategoryChip(product, isFa) const categoryLocale = textLocaleAttrs(categoryLabel) return (
{galleryImages.length > 1 && (
{galleryImages.map((src, index) => ( ))}
)}
{categoryLabel ? ( {categoryLabel} ) : null}

{primaryName}

{secondaryName ? (

{secondaryName}

) : null} {product.summary && (

{product.summary}

)} {product.description && (
)} {product.tags.length > 0 && (
{product.tags.map((tag) => { const tagLocale = textLocaleAttrs(tag) return ( {tag} ) })}
)}
setLightboxOpen(false)} />
) }