import { useEffect, useMemo, useState } from 'react' import { Link, useNavigate, useParams } from 'react-router-dom' import { ImageOff, MapPin, Pencil, User } from 'lucide-react' import { useLocale } from '@meshkee/dashboard-ui' import { Breadcrumbs } from '../components/Breadcrumbs' import { PageTitle } from '../components/PageTitle' import { UserProductStatusModal } from '../components/UserProductStatusModal' import { useToast } from '../context/ToastContext' import { useT } from '../i18n/useT' import { ApiError, isAbortError } from '../lib/api' import { getUserProduct, getUserProductCategoryTechnicalForm, updateUserProductStatus, type TechnicalFormField, type UserProductDetail, type UserProductTechnicalValueInput, } from '../services/userProductsService' import type { UserProductStatus } from '../types/userProduct' import { formatIrtPrice } from '../utils/irtPrice' import pageStyles from '../components/PageContent.module.css' import styles from './CustomerProductDetailsPage.module.css' function formatTechnicalValue( field: TechnicalFormField, value: UserProductTechnicalValueInput | undefined, ): string { if (!value) return '—' if (value.textValue != null && value.textValue.trim()) return value.textValue if (value.optionId) { return field.options.find((option) => option.id === value.optionId)?.label ?? value.optionId } if (value.optionIds?.length) { return value.optionIds .map( (optionId) => field.options.find((option) => option.id === optionId)?.label ?? optionId, ) .join(', ') } return '—' } export function CustomerProductDetailsPage() { const { id } = useParams<{ id: string }>() const t = useT() const { locale } = useLocale() const navigate = useNavigate() const { showToast } = useToast() const isFa = locale === 'fa' const [product, setProduct] = useState(null) const [technicalFields, setTechnicalFields] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [statusOpen, setStatusOpen] = useState(false) const [statusSaving, setStatusSaving] = useState(false) useEffect(() => { if (!id) return const controller = new AbortController() async function load() { setLoading(true) setError('') try { const response = await getUserProduct(id!, controller.signal) if (controller.signal.aborted) return setProduct(response.product) if (response.product.categoryId) { const formResponse = await getUserProductCategoryTechnicalForm( response.product.categoryId, controller.signal, ) if (controller.signal.aborted) return setTechnicalFields(formResponse.form?.fields ?? []) } else { setTechnicalFields([]) } } catch (err) { if (isAbortError(err) || controller.signal.aborted) return const message = err instanceof ApiError ? err.message : t('customerProducts.error.loadDetail') setError(message) setProduct(null) } finally { if (!controller.signal.aborted) setLoading(false) } } void load() return () => controller.abort() }, [id, t]) const technicalRows = useMemo(() => { if (!product) return [] const byField = new Map( (product.technicalValues ?? []).map((item) => [item.fieldId, item]), ) return technicalFields.map((field) => ({ id: field.id, label: field.label, value: formatTechnicalValue(field, byField.get(field.id)), })) }, [product, technicalFields]) async function handleStatusSave(status: UserProductStatus) { if (!product) return setStatusSaving(true) try { const response = await updateUserProductStatus(product.id, status) setProduct((prev) => (prev ? { ...prev, ...response.product } : prev)) showToast(t('customerProducts.statusSuccess'), 'success') setStatusOpen(false) } catch (err) { showToast( err instanceof ApiError ? err.message : t('customerProducts.error.status'), 'error', ) } finally { setStatusSaving(false) } } if (loading) { return (

{t('customerProducts.loading')}

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

{error || t('customerProducts.error.loadDetail')}

{t('customerProducts.backToList')}
) } const title = isFa ? product.titleFa || product.title : product.titleEn || product.title const secondary = isFa ? product.titleEn || '' : product.titleFa || '' const city = isFa ? product.cityNameFa || product.cityName : product.cityName const country = isFa ? product.countryNameFa || product.countryName : product.countryName const category = isFa ? product.categoryNameFa || product.categoryName : product.categoryName const owner = isFa ? product.ownerNameFa || product.ownerName : product.ownerName const imageSrc = product.imageUrl?.trim() || '' const galleryImages = (product.images ?? []) .map((item) => item.url?.trim()) .filter((url): url is string => Boolean(url)) const statusLabel = product.status === 'published' ? t('customerProducts.status.published') : product.status === 'archived' ? t('customerProducts.status.archived') : product.status === 'rejected' ? t('customerProducts.status.rejected') : t('customerProducts.status.pending') const currency = (product.priceCurrency || 'IRT').toUpperCase() const priceLabel = product.price == null ? t('customerProducts.priceUnavailable') : currency === 'IRT' ? formatIrtPrice(product.price) : `${Number(product.price).toLocaleString('en-US')} ${currency}` const conditionLabel = product.condition === 'new' ? t('customerProducts.form.condition.new') : product.condition === 'stock' ? t('customerProducts.form.condition.stock') : product.condition === 'needs_repair' ? t('customerProducts.form.condition.needs_repair') : product.condition === 'scrap' ? t('customerProducts.form.condition.scrap') : '—' return (
{t('customerProducts.detailsTitle')}

{t('customerProducts.detailsSubtitle')}

{imageSrc ? ( {title} ) : (
)} {statusLabel}
{galleryImages.length > 0 ? (
{galleryImages.map((url) => (
))}
) : null}
{category ? {category} : null}

{title}

{secondary ?

{secondary}

: null}

{priceLabel}

{owner ? ( {owner} ) : null} {[city, country].filter(Boolean).join(isFa ? '، ' : ', ') || '—'}
{t('customerProducts.form.fields.country')}
{country || '—'}
{t('customerProducts.form.fields.city')}
{city || '—'}
{t('customerProducts.form.fields.condition')}
{conditionLabel}
{product.priceByExpert ? (
{t('customerProducts.form.fields.priceByExpert')}
{t('customerProducts.yes')}
) : null}
{product.description ? (

{t('customerProducts.form.fields.description')}

{product.description}

) : null} {product.deliveryNote ? (

{t('customerProducts.form.fields.deliveryNote')}

{product.deliveryNote}

) : null} {product.technicalNotes ? (

{t('customerProducts.form.fields.technicalNotes')}

{product.technicalNotes}

) : null} {technicalRows.length > 0 ? (

{t('customerProducts.form.technical.categoryForm')}

{technicalRows.map((row) => (
{row.label}
{row.value}
))}
) : null}
setStatusOpen(false)} onSave={(status) => void handleStatusSave(status)} />
) }