canina/frontend/application/components/catalog/ProductDetailModal.tsx
parsaaghayi bd49fbc4a0
Some checks failed
Deploy Canina / deploy (push) Successful in 2m25s
E2E Playwright Tests / Run Full E2E & Security Suites (push) Failing after 7s
fix(security): remediate audit vulnerabilities SEC-001 through SEC-023
2026-09-23 23:00:25 +03:30

183 lines
8.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React from "react";
import DOMPurify from "dompurify";
import SafeImage from "../SafeImage";
import { Product } from "../../lib/data/products";
import { X, ShieldCheck, CheckCircle2, Award, Stethoscope, Sparkles, Layers, Info } from "lucide-react";
interface ProductDetailModalProps {
product: Product | null;
categoryColor?: string;
onClose: () => void;
}
export default function ProductDetailModal({ product, categoryColor = "#0284C7", onClose }: ProductDetailModalProps) {
if (!product) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-900/70 backdrop-blur-md animate-fadeIn" dir="rtl">
<div
className="bg-white w-full max-w-3xl max-h-[90vh] rounded-3xl shadow-2xl overflow-hidden flex flex-col border border-slate-200 relative animate-scaleUp"
onClick={(e) => e.stopPropagation()}
>
{/* Modal Header */}
<div
className="p-6 text-white flex items-start justify-between relative overflow-hidden"
style={{ backgroundColor: categoryColor }}
>
<div className="absolute -left-10 -bottom-10 w-40 h-40 bg-white/10 rounded-full blur-2xl pointer-events-none" />
<div className="relative z-10 space-y-1">
<div className="flex items-center gap-2 text-xs font-bold bg-white/15 px-3 py-1 rounded-full w-fit backdrop-blur-sm border border-white/20">
<Sparkles className="w-3.5 h-3.5" />
<span>{product.category}</span>
<span className="opacity-60"></span>
<span>کد کالا: {product.artNo}</span>
</div>
<h2 className="text-2xl md:text-3xl font-black font-lalezar mt-2 leading-tight">
{product.name}
</h2>
{product.scientificTagline && (
<p className="text-xs md:text-sm text-white/90 font-medium">
{product.scientificTagline}
</p>
)}
</div>
<button
onClick={onClose}
className="p-2.5 rounded-full bg-white/10 hover:bg-white/20 text-white transition-colors relative z-10 cursor-pointer"
aria-label="بستن"
>
<X className="w-5 h-5" />
</button>
</div>
{/* Modal Content Scrollable Area */}
<div className="p-6 md:p-8 overflow-y-auto space-y-6 sleek-scrollbar text-slate-800">
{/* Image & Key Attributes Grid */}
<div className="grid grid-cols-1 md:grid-cols-12 gap-6 items-center">
<div className="md:col-span-5 bg-slate-50 border border-slate-200/80 rounded-2xl p-6 flex items-center justify-center aspect-square relative shadow-xs">
<SafeImage
src={product.image}
alt={product.name}
className="w-full h-full"
imgClassName="object-contain max-h-52"
/>
<div className="absolute bottom-3 right-3 bg-white/90 backdrop-blur-sm text-slate-700 text-[11px] font-black px-3 py-1 rounded-lg border border-slate-200/60 shadow-2xs">
وزن/حجم: {product.unit}
</div>
</div>
<div className="md:col-span-7 space-y-4">
<div className="space-y-2">
<span className="text-xs font-black text-slate-400 uppercase tracking-widest block">
شرح بالینی و عملکرد:
</span>
{/<[a-z][\s\S]*>/i.test(product.description || '') ? (
<div
dangerouslySetInnerHTML={{
__html: typeof window !== 'undefined'
? DOMPurify.sanitize(product.description || '')
: product.description || '',
}}
className="text-sm text-slate-600 leading-relaxed font-medium space-y-2 [&>h1]:font-black [&>h2]:font-black [&>h3]:font-black [&>p]:leading-relaxed [&>ul]:list-disc [&>ul]:pr-4 [&>ol]:list-decimal [&>ol]:pr-4 text-justify"
/>
) : (
<p className="text-sm text-slate-600 leading-relaxed font-medium text-justify">
{product.description}
</p>
)}
</div>
{/* Species & Dosage badges */}
<div className="flex flex-wrap gap-2 pt-2">
<div className="bg-slate-100 border border-slate-200 rounded-xl px-3 py-1.5 text-xs font-bold text-slate-700 flex items-center gap-1.5">
<Award className="w-4 h-4 text-canina-blue" />
<span>مناسب: {product.suitableFor}</span>
</div>
<div className="bg-slate-100 border border-slate-200 rounded-xl px-3 py-1.5 text-xs font-bold text-slate-700 flex items-center gap-1.5">
<CheckCircle2 className="w-4 h-4 text-emerald-600" />
<span>گرید دارویی آلمان</span>
</div>
</div>
</div>
</div>
{/* Active Ingredients Section */}
{product.main_ingredients && product.main_ingredients.length > 0 && (
<div className="bg-blue-50/50 border border-blue-100 rounded-2xl p-5 space-y-3">
<div className="flex items-center gap-2 text-canina-blue font-black text-xs">
<Layers className="w-4 h-4" />
<span>ترکیبات فعال و مواد موثره دارویی:</span>
</div>
<div className="flex flex-wrap gap-2">
{product.main_ingredients.map((ingredient, idx) => (
<span
key={idx}
className="bg-white text-slate-800 border border-blue-200 rounded-xl px-3 py-1.5 text-xs font-bold shadow-2xs"
>
{ingredient}
</span>
))}
</div>
</div>
)}
{/* Clinical Dosage Section */}
{product.dosage_logic && (
<div className="bg-amber-50/80 border border-amber-200/80 rounded-2xl p-5 space-y-2">
<div className="flex items-center gap-2 text-amber-900 font-black text-xs">
<ShieldCheck className="w-4.5 h-4.5 text-amber-600" />
<span>دستور مصرف بالینی و دوز توصیه شده:</span>
</div>
<p className="text-xs md:text-sm text-amber-900 leading-relaxed font-bold">
{product.dosage_logic}
</p>
</div>
)}
{/* Specialist Note */}
{product.specialist && (
<div className="bg-slate-50 border border-slate-200 rounded-2xl p-5 flex items-start gap-4">
<SafeImage
src={product.specialist.image}
alt={product.specialist.name}
className="w-12 h-12 rounded-full border-2 border-white shadow-xs shrink-0"
imgClassName="object-cover"
/>
<div className="space-y-1">
<div className="flex items-center gap-2">
<Stethoscope className="w-4 h-4 text-canina-blue" />
<span className="text-xs font-black text-slate-900">{product.specialist.name}</span>
<span className="text-[11px] text-slate-500 font-medium">({product.specialist.title})</span>
</div>
<p className="text-xs text-slate-600 italic leading-relaxed">
«{product.specialist.message}»
</p>
</div>
</div>
)}
</div>
{/* Modal Footer */}
<div className="p-4 bg-slate-50 border-t border-slate-200 flex items-center justify-between">
<div className="flex items-center gap-2 text-xs text-slate-500 font-bold">
<Info className="w-4 h-4 text-slate-400" />
<span>راهنمای کاتالوگ رسمی دارویی Canina Pharma Germany</span>
</div>
<button
onClick={onClose}
className="px-6 py-2.5 bg-slate-900 text-white rounded-xl text-xs font-black hover:bg-slate-800 transition-colors cursor-pointer"
>
بستن جزئیات
</button>
</div>
</div>
</div>
);
}