canina/frontend/application/components/BlogPage.tsx
parsa aghaei 7615aa0e51 fix: resolve seed encoding, search param, and wiki data source issues
- Fix seed-products.ts TS error (implicit any) and BOM handling
- Re-run full seed to restore correct Persian encoding in DB
- Fix productService query→search param mismatch
- Fix IngredientWiki hardcoded port 4000→use settingsStore
- Restore seed-products-data.json from git after accidental corruption
2026-07-11 15:40:49 +03:30

322 lines
18 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { motion } from "motion/react";
import { ChevronRight, Calendar, User, ArrowLeft, Sparkles, BookOpen } from "lucide-react";
import { Product } from "../lib/data/products";
import { productService } from "../lib/services/productService";
export interface BlogPost {
id: string;
slug: string;
title: string;
excerpt: string;
image: string;
date: string;
author: string;
content: string;
}
import { useRouter } from 'next/navigation';
export default function BlogPage({ blogs = [] }: { blogs: BlogPost[] }) {
const router = useRouter();
const [selectedPost, setSelectedPost] = React.useState<BlogPost | null>(null);
const [products, setProducts] = React.useState<Product[]>([]);
React.useEffect(() => {
productService.getProducts().then(data => setProducts(data));
}, []);
if (selectedPost) {
return (
<div className="min-h-screen bg-medical-gray-50 pt-8 pb-20 px-4 font-vazir" dir="rtl">
<div className="max-w-7xl mx-auto">
{/* Breadcrumbs */}
<div className="flex items-center gap-2 text-[10px] font-black text-medical-gray-400 uppercase tracking-widest mb-10">
<span className="cursor-pointer hover:text-canina-blue" onClick={() => router.push('/')}>خانه</span>
<ChevronRight className="w-2.5 h-2.5" />
<span className="cursor-pointer hover:text-canina-blue" onClick={() => setSelectedPost(null)}>مجله سلامت</span>
<ChevronRight className="w-2.5 h-2.5" />
<span className="text-canina-blue">{selectedPost.title}</span>
</div>
<div className="grid lg:grid-cols-12 gap-12">
<div className="lg:col-span-8">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="bg-white rounded-[3.5rem] border border-medical-gray-200 shadow-2xl overflow-hidden"
>
<div className="aspect-video w-full overflow-hidden">
<img src={selectedPost.image} alt={selectedPost.title} className="w-full h-full object-cover" />
</div>
<div className="p-12">
<div className="flex items-center gap-4 text-xs font-bold text-canina-blue mb-8">
<div className="bg-canina-blue/10 px-4 py-1.5 rounded-full uppercase tracking-widest">تحقیق بالینی</div>
<div className="flex items-center gap-1">
<Calendar className="w-4 h-4" />
{selectedPost.date}
</div>
</div>
<h1 className="text-4xl lg:text-5xl font-black text-medical-gray-900 mb-10 leading-tight">
{selectedPost.title}
</h1>
<div className="prose prose-lg max-w-none text-medical-gray-600 leading-[2] text-justify space-y-6">
<p className="font-bold text-medical-gray-900 italic text-xl border-r-4 border-canina-blue pr-6 py-2">
{selectedPost.excerpt}
</p>
<div className="whitespace-pre-line">
{selectedPost.content}
</div>
</div>
<div className="mt-16 pt-10 border-t border-medical-gray-100 flex items-center justify-between">
<div className="flex items-center gap-4">
<div className="w-14 h-14 bg-medical-gray-100 rounded-full flex items-center justify-center text-medical-gray-400 border-2 border-white shadow-lg">
<User className="w-8 h-8" />
</div>
<div>
<div className="font-black text-medical-gray-900 text-lg">{selectedPost.author}</div>
<div className="font-bold text-medical-gray-400">تیم تحقیق و توسعه کانینا آلمان</div>
</div>
</div>
<div className="flex gap-4">
<button className="p-4 bg-medical-gray-100 rounded-2xl hover:bg-canina-blue hover:text-white transition-all text-medical-gray-400">
<Sparkles className="w-6 h-6" />
</button>
</div>
</div>
</div>
</motion.div>
</div>
<div className="lg:col-span-4 space-y-10">
<div className="bg-canina-blue rounded-[3rem] p-10 text-white shadow-2xl relative overflow-hidden">
<div className="absolute top-0 left-0 p-8 opacity-10">
<Sparkles className="w-20 h-20" />
</div>
<h4 className="text-2xl font-black mb-6 italic relative z-10">محصولات پیشنهادی</h4>
<div className="space-y-6 relative z-10">
{products.slice(4, 7).map(p => (
<div
key={p.id}
onClick={() => router.push(`/shop/${p.id}`)}
className="bg-white/10 border border-white/20 p-4 rounded-3xl flex items-center gap-4 cursor-pointer hover:bg-white/20 transition-all group"
>
<div className="w-16 h-16 bg-white rounded-2xl p-2 shrink-0 group-hover:scale-110 transition-transform">
<img src={p.image} alt={p.name} className="w-full h-full object-contain" />
</div>
<div>
<div className="text-[10px] font-black opacity-50 uppercase tracking-widest">{p.category}</div>
<div className="text-sm font-black font-vazir text-white">{p.name}</div>
</div>
</div>
))}
</div>
</div>
<div className="bg-white rounded-[3rem] border border-medical-gray-200 p-10 shadow-xl">
<h4 className="text-xl font-black italic mb-6">محبوبترین مقالات</h4>
<div className="space-y-6">
{blogs.map(p => (
<div
key={p.id}
onClick={() => router.push(`/blog/${p.slug}`)}
className="flex items-center gap-4 cursor-pointer group"
>
<div className="w-16 h-16 rounded-2xl overflow-hidden shrink-0">
<img src={p.image} className="w-full h-full object-cover group-hover:scale-110 transition-transform" />
</div>
<div className="text-sm font-black text-medical-gray-900 group-hover:text-canina-blue transition-colors line-clamp-2">
{p.title}
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
);
}
return (
<div className="min-h-screen bg-medical-gray-50 pt-8 pb-20 px-4 font-vazir" dir="rtl">
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="flex flex-col md:flex-row items-center justify-between mb-16 gap-6">
<div className="text-right">
<div className="inline-flex items-center gap-2 px-3 py-1 bg-canina-blue/10 text-canina-blue rounded-full text-[10px] font-black uppercase tracking-widest mb-4">
<BookOpen className="w-3 h-3" />
Canina Science Blog
</div>
<h1 className="text-4xl lg:text-6xl font-black text-medical-gray-900 italic leading-tight">
مجله تخصصی <span className="text-canina-blue">سلامت پتها</span>
</h1>
<p className="text-lg text-medical-gray-500 font-medium mt-4 max-w-xl">
آخرین یافتههای علمی محققین کانینا آلمان در مورد تغذیه و سلامت پتها.
</p>
</div>
<button
onClick={() => router.push('/')}
className="px-8 py-3 bg-white border border-medical-gray-200 rounded-2xl text-medical-gray-700 shadow-sm flex items-center gap-2 font-black hover:bg-medical-gray-50 transition-all"
>
<ChevronRight className="w-5 h-5" />
بازگشت به خانه
</button>
</div>
{/* Featured Post */}
{blogs.length > 0 && (
<div className="mb-20">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="bg-white rounded-[3.5rem] overflow-hidden border border-medical-gray-200 shadow-2xl flex flex-col lg:flex-row cursor-pointer group"
onClick={() => router.push(`/blog/${blogs[0].slug}`)}
>
<div className="lg:w-1/2 aspect-video lg:aspect-auto">
<img
src={blogs[0].image}
alt={blogs[0].title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
/>
</div>
<div className="lg:w-1/2 p-12 flex flex-col justify-center">
<div className="flex items-center gap-4 text-xs font-bold text-canina-blue mb-6">
<div className="bg-canina-blue/10 px-3 py-1 rounded-full uppercase tracking-widest">تخصصی</div>
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
{blogs[0].date}
</div>
</div>
<h2 className="text-3xl lg:text-4xl font-black text-medical-gray-900 mb-6 leading-tight group-hover:text-canina-blue transition-colors">
{blogs[0].title}
</h2>
<p className="text-lg text-medical-gray-500 mb-8 leading-relaxed italic">
{blogs[0].excerpt}
</p>
<div className="flex items-center justify-between pt-8 border-t border-medical-gray-100">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-medical-gray-100 rounded-full flex items-center justify-center text-medical-gray-400">
<User className="w-6 h-6" />
</div>
<div className="text-sm">
<div className="font-black text-medical-gray-900">{blogs[0].author}</div>
<div className="font-bold text-medical-gray-400">نویسنده کانینا</div>
</div>
</div>
<div className="flex items-center gap-2 text-canina-blue font-black">
ادامه مطلب
<ArrowLeft className="w-5 h-5 group-hover:-translate-x-2 transition-transform" />
</div>
</div>
</div>
</motion.div>
</div>
)}
{/* Post Grid */}
<div className="grid md:grid-cols-2 gap-8">
{blogs.slice(1).map((post, idx) => (
<motion.div
key={post.id}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: idx * 0.1 }}
className="bg-white rounded-[3rem] overflow-hidden border border-medical-gray-200 shadow-xl group hover:shadow-2xl transition-all cursor-pointer"
onClick={() => router.push(`/blog/${post.slug}`)}
>
<div className="aspect-[16/9] overflow-hidden">
<img
src={post.image}
alt={post.title}
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
/>
</div>
<div className="p-8">
<div className="flex items-center gap-4 text-[10px] font-bold text-canina-blue mb-4">
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
{post.date}
</div>
</div>
<h3 className="text-xl font-black text-medical-gray-900 mb-4 group-hover:text-canina-blue transition-colors">
{post.title}
</h3>
<p className="text-sm text-medical-gray-500 mb-8 leading-relaxed line-clamp-2">
{post.excerpt}
</p>
<div className="flex items-center gap-2 text-medical-gray-900 font-bold group">
مطالعه مقاله
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" />
</div>
</div>
</motion.div>
))}
{/* Newsletter / CTA Box */}
<div className="bg-canina-blue rounded-[3rem] p-10 text-white relative overflow-hidden flex flex-col justify-center">
<div className="absolute top-0 right-0 p-8 opacity-20">
<Sparkles className="w-24 h-24" />
</div>
<h3 className="text-3xl font-black mb-4 italic">مشترک خبرنامه علمی شوید</h3>
<p className="text-white/80 mb-8 font-medium leading-relaxed">
ماهانه یک ایمیل حاوی مهمترین نکات سلامت پتها و کدهای تخفیف اختصاصی دریافت کنید.
</p>
<div className="flex gap-2">
<input
type="email"
placeholder="آدرس ایمیل شما"
className="flex-1 bg-white/10 border border-white/20 rounded-xl px-4 py-3 outline-none focus:bg-white/20 placeholder:text-white/40"
/>
<button className="bg-white text-canina-blue px-6 py-3 rounded-xl font-black">
عضویت
</button>
</div>
</div>
</div>
{/* Synergy Products Cross-sell */}
<section className="mt-32 p-12 bg-canina-blue rounded-[4rem] text-white overflow-hidden relative shadow-2xl">
<div className="absolute inset-0 opacity-20 pointer-events-none">
<div className="grid grid-cols-6 h-full w-full">
{Array.from({ length: 36 }).map((_, i) => (
<div key={i} className="border border-white/20" />
))}
</div>
</div>
<div className="relative z-10 flex flex-col lg:flex-row items-center gap-12">
<div className="flex-1">
<h3 className="text-3xl lg:text-4xl font-black italic mb-6">علم آلمانی در خدمت سلامت پت شما</h3>
<p className="text-white/80 mb-8 leading-relaxed max-w-xl">
تمامی مقالات این وبلاگ بر اساس کاتالوگهای رسمی و نتایج آزمایشگاهی کمپانی کانینا آلمان تدوین شده است.
</p>
<button
onClick={() => router.push('/shop')}
className="bg-white text-canina-blue px-8 py-4 rounded-2xl font-black hover:scale-105 transition-transform"
>
مشاهده محصولات تخصصی
</button>
</div>
<div className="grid grid-cols-2 gap-4 flex-shrink-0">
{products.slice(0, 2).map((p) => (
<div
key={p.id}
onClick={() => router.push(`/shop/${p.id}`)}
className="bg-white/10 border border-white/20 p-6 rounded-3xl cursor-pointer hover:bg-white/20 transition-all text-center group"
>
<img src={p.image} alt={p.name} className="w-20 h-20 mx-auto mb-4 object-contain filter brightness-0 invert group-hover:scale-110 transition-transform" />
<h5 className="text-[10px] font-black">{p.name}</h5>
</div>
))}
</div>
</div>
</section>
</div>
</div>
);
}