fix(home): fix mobile slider vertical scroll chaining, unify view-all headers, and enhance CTA and navigation cards
This commit is contained in:
parent
49eb1e5ff3
commit
ba9472c938
@ -16,6 +16,7 @@ import api from "../lib/services/api";
|
||||
import Image from "next/image";
|
||||
|
||||
import { Banner, Testimonial, SmartAdvisorRule, HomeApiResponse } from "../lib/types";
|
||||
import { Pill, BookOpen, Sparkles, ArrowLeft, ShieldCheck, Stethoscope } from "lucide-react";
|
||||
|
||||
interface HomeClientProps {
|
||||
initialData?: HomeApiResponse | null;
|
||||
@ -71,41 +72,75 @@ export default function HomeClient({ initialData }: HomeClientProps) {
|
||||
|
||||
|
||||
{/* Navigation to Sections */}
|
||||
<section className="py-6 sm:py-12 bg-medical-gray-50 border-y border-medical-gray-100 font-sans">
|
||||
<div className="max-w-7xl mx-auto px-4 grid md:grid-cols-2 gap-4 sm:gap-8">
|
||||
<section className="py-8 sm:py-14 bg-medical-gray-50 border-y border-medical-gray-100 font-sans">
|
||||
<div className="max-w-7xl mx-auto px-4 grid md:grid-cols-2 gap-5 sm:gap-8">
|
||||
{/* Specialty Shop Card */}
|
||||
<Link
|
||||
href="/shop"
|
||||
className="bg-gradient-to-br from-blue-50/60 to-canina-blue/5 p-6 sm:p-12 rounded-2xl sm:rounded-[2.5rem] border border-blue-100/60 shadow-md hover:shadow-2xl hover:-translate-y-1 transition-all cursor-pointer group block relative overflow-hidden"
|
||||
className="group relative overflow-hidden rounded-3xl sm:rounded-[2.5rem] bg-gradient-to-br from-white via-blue-50/50 to-canina-blue/10 p-6 sm:p-10 border border-blue-200/70 shadow-md hover:shadow-2xl hover:border-canina-blue/50 hover:-translate-y-1 transition-all duration-500 block"
|
||||
>
|
||||
<div className="absolute -top-12 -left-12 w-32 h-32 bg-canina-blue/5 rounded-full blur-2xl group-hover:scale-150 transition-transform duration-700" />
|
||||
<h3 className="text-2xl sm:text-3xl font-black text-medical-gray-900 mb-2 sm:mb-4 group-hover:text-canina-blue transition-colors font-lalezar tracking-wide">
|
||||
{getText('nav_card_shop_title', "فروشگاه تخصصی")}
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-medical-gray-600 mb-4 sm:mb-8 leading-relaxed font-shabnam">
|
||||
{getText('nav_card_shop_desc', "دسترسی به تمامی محصولات بر اساس علائم بالینی و نیازهای پت شما.")}
|
||||
</p>
|
||||
<div className="flex items-center gap-2 text-canina-blue font-black tracking-widest uppercase text-xs font-vazir">
|
||||
{getText('nav_card_shop_cta', "کاتالوگ کامل محصولات")}
|
||||
<span className="text-lg group-hover:-translate-x-1 transition-transform">←</span>
|
||||
{/* Ambient Glows */}
|
||||
<div className="absolute -top-16 -left-16 w-44 h-44 bg-canina-blue/15 rounded-full blur-3xl group-hover:scale-150 transition-transform duration-700 pointer-events-none" />
|
||||
<div className="absolute -bottom-16 -right-16 w-36 h-36 bg-blue-400/10 rounded-full blur-2xl pointer-events-none" />
|
||||
|
||||
<div className="relative z-10 flex flex-col h-full justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between gap-3 mb-4">
|
||||
<div className="w-12 h-12 sm:w-14 sm:h-14 rounded-2xl bg-canina-blue text-white flex items-center justify-center shadow-lg shadow-canina-blue/25 group-hover:scale-110 group-hover:rotate-6 transition-all">
|
||||
<Pill className="w-6 h-6 sm:w-7 sm:h-7" />
|
||||
</div>
|
||||
<span className="px-3 py-1 rounded-full bg-blue-100/80 text-canina-blue text-[11px] font-black tracking-wider uppercase font-vazir border border-blue-200/60 shadow-xs">
|
||||
محصولات دارویی و مکمل
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-2xl sm:text-3xl font-black text-medical-gray-900 mb-2 sm:mb-3 group-hover:text-canina-blue transition-colors font-lalezar tracking-wide">
|
||||
{getText('nav_card_shop_title', "داروخانه تخصصی مکملها")}
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-medical-gray-600 mb-6 sm:mb-8 leading-relaxed font-shabnam">
|
||||
{getText('nav_card_shop_desc', "دسترسی مستقیم به کاملترین مجموعه مکملهای آلمانی اصل بر اساس علائم بالینی و نیازهای پت شما.")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-blue-100/80 flex items-center justify-between text-canina-blue font-black text-xs sm:text-sm font-vazir">
|
||||
<span>{getText('nav_card_shop_cta', "ورود به فروشگاه و کاتالوگ")}</span>
|
||||
<div className="w-8 h-8 rounded-xl bg-canina-blue/10 flex items-center justify-center group-hover:bg-canina-blue group-hover:text-white transition-all">
|
||||
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform rtl:rotate-0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Scientific Wiki Card */}
|
||||
<Link
|
||||
href="/wiki"
|
||||
className="bg-gradient-to-br from-emerald-50/60 to-green-50/20 p-6 sm:p-12 rounded-2xl sm:rounded-[2.5rem] border border-emerald-100/60 shadow-md hover:shadow-2xl hover:-translate-y-1 transition-all cursor-pointer group block relative overflow-hidden"
|
||||
className="group relative overflow-hidden rounded-3xl sm:rounded-[2.5rem] bg-gradient-to-br from-white via-emerald-50/50 to-teal-500/10 p-6 sm:p-10 border border-emerald-200/70 shadow-md hover:shadow-2xl hover:border-emerald-500/50 hover:-translate-y-1 transition-all duration-500 block"
|
||||
>
|
||||
<div className="absolute -top-12 -left-12 w-32 h-32 bg-emerald-500/5 rounded-full blur-2xl group-hover:scale-150 transition-transform duration-700" />
|
||||
<h3 className="text-2xl sm:text-3xl font-black text-medical-gray-900 mb-2 sm:mb-4 group-hover:text-emerald-700 transition-colors font-lalezar tracking-wide">
|
||||
{getText('nav_card_wiki_title', "دانشنامه علمی")}
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-medical-gray-600 mb-4 sm:mb-8 leading-relaxed font-shabnam">
|
||||
{getText('nav_card_wiki_desc', "آشنایی با ترکیبات نایاب و استانداردهای دارویی محصولات آلمانی کنینا.")}
|
||||
</p>
|
||||
<div className="flex items-center gap-2 text-emerald-700 font-black tracking-widest uppercase text-xs font-vazir">
|
||||
{getText('nav_card_wiki_cta', "مطالعه مقالات تخصصی")}
|
||||
<span className="text-lg group-hover:-translate-x-1 transition-transform">←</span>
|
||||
{/* Ambient Glows */}
|
||||
<div className="absolute -top-16 -left-16 w-44 h-44 bg-emerald-500/15 rounded-full blur-3xl group-hover:scale-150 transition-transform duration-700 pointer-events-none" />
|
||||
<div className="absolute -bottom-16 -right-16 w-36 h-36 bg-teal-400/10 rounded-full blur-2xl pointer-events-none" />
|
||||
|
||||
<div className="relative z-10 flex flex-col h-full justify-between">
|
||||
<div>
|
||||
<div className="flex items-center justify-between gap-3 mb-4">
|
||||
<div className="w-12 h-12 sm:w-14 sm:h-14 rounded-2xl bg-emerald-600 text-white flex items-center justify-center shadow-lg shadow-emerald-600/25 group-hover:scale-110 group-hover:-rotate-6 transition-all">
|
||||
<BookOpen className="w-6 h-6 sm:w-7 sm:h-7" />
|
||||
</div>
|
||||
<span className="px-3 py-1 rounded-full bg-emerald-100/80 text-emerald-800 text-[11px] font-black tracking-wider uppercase font-vazir border border-emerald-200/60 shadow-xs">
|
||||
تحقیقات بینالمللی
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="text-2xl sm:text-3xl font-black text-medical-gray-900 mb-2 sm:mb-3 group-hover:text-emerald-700 transition-colors font-lalezar tracking-wide">
|
||||
{getText('nav_card_wiki_title', "دانشنامه علمی و مقالات")}
|
||||
</h3>
|
||||
<p className="text-sm sm:text-base text-medical-gray-600 mb-6 sm:mb-8 leading-relaxed font-shabnam">
|
||||
{getText('nav_card_wiki_desc', "آشنایی تخصصی با ترکیبات دارویی نایاب نظیر صدف لبسبز، هیدروکسیآپاتیت و استانداردهای دارویی آلمان.")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="pt-4 border-t border-emerald-100/80 flex items-center justify-between text-emerald-700 font-black text-xs sm:text-sm font-vazir">
|
||||
<span>{getText('nav_card_wiki_cta', "مطالعه دانشنامه ترکیبات")}</span>
|
||||
<div className="w-8 h-8 rounded-xl bg-emerald-600/10 flex items-center justify-center group-hover:bg-emerald-600 group-hover:text-white transition-all">
|
||||
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform rtl:rotate-0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
@ -170,25 +205,40 @@ export default function HomeClient({ initialData }: HomeClientProps) {
|
||||
{/* Bottom Banner Placement */}
|
||||
<BannerPlacement banners={banners} position="home_bottom" />
|
||||
|
||||
{/* Call to Action */}
|
||||
<section className="bg-canina-blue py-12 relative overflow-hidden font-sans">
|
||||
<div className="absolute inset-0 opacity-10 bg-[radial-gradient(#fff_1px,transparent_1px)] [background-size:24px_24px]" />
|
||||
{/* Call to Action - Elevated with Rich Aesthetics */}
|
||||
<section className="bg-gradient-to-br from-canina-dark via-canina-blue to-[#0b4d8c] py-14 sm:py-20 relative overflow-hidden font-sans shadow-2xl">
|
||||
{/* Background Pattern and Highlights */}
|
||||
<div className="absolute inset-0 opacity-15 bg-[radial-gradient(#ffffff_1.5px,transparent_1.5px)] [background-size:24px_24px] pointer-events-none" />
|
||||
<div className="absolute -top-24 -right-24 w-96 h-96 bg-cyan-400/20 rounded-full blur-3xl pointer-events-none" />
|
||||
<div className="absolute -bottom-24 -left-24 w-96 h-96 bg-amber-400/15 rounded-full blur-3xl pointer-events-none" />
|
||||
|
||||
<div className="max-w-4xl mx-auto px-4 text-center relative z-10">
|
||||
<h2 className="text-3xl lg:text-5xl font-black text-white mb-8 leading-tight font-lalezar tracking-wide">
|
||||
<div className="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-white/10 backdrop-blur-md border border-white/20 text-white text-xs font-bold font-vazir mb-6 shadow-md">
|
||||
<Sparkles className="w-3.5 h-3.5 text-amber-300" />
|
||||
<span>مشاوره و تشخیص هوشمند بالینی</span>
|
||||
</div>
|
||||
|
||||
<h2 className="text-3xl sm:text-4xl lg:text-5xl font-black text-white mb-6 leading-tight font-lalezar tracking-wide drop-shadow-md">
|
||||
{getText('cta_title', "میخواهید بدانید کدام محصول برای پت شما مناسبتر است؟")}
|
||||
</h2>
|
||||
<p className="text-white/80 text-lg mb-10 leading-relaxed font-shabnam">
|
||||
{getText('cta_desc', "تیم متخصص دامپزشکی کنینا ایران آماده پاسخگویی به سوالات شماست.")}
|
||||
<p className="text-blue-100/90 text-base sm:text-lg mb-8 sm:mb-10 leading-relaxed font-shabnam max-w-2xl mx-auto">
|
||||
{getText('cta_desc', "با استفاده از دستیار هوشمند تشخیصی یا تماس با تیم متخصص دامپزشکی کنینا ایران، بهترین رژیم مکمل درمانی را دریافت کنید.")}
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center gap-4">
|
||||
<button className="bg-white text-canina-blue px-12 py-5 rounded-full font-black text-xl hover:scale-105 transition-transform shadow-2xl shadow-black/20 font-shabnam">
|
||||
{getText('cta_btn_primary', "دریافت رژیم مکمل رایگان")}
|
||||
</button>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-3.5 sm:gap-5">
|
||||
<Link
|
||||
href="/shop"
|
||||
className="bg-transparent border-2 border-white text-white px-12 py-5 rounded-full font-black text-xl hover:bg-white hover:text-canina-blue transition-all font-shabnam"
|
||||
href="/smart-advisor"
|
||||
className="w-full sm:w-auto inline-flex items-center justify-center gap-2.5 bg-white text-canina-blue px-8 py-4 sm:px-10 sm:py-4.5 rounded-2xl font-black text-base sm:text-lg hover:scale-105 hover:bg-amber-300 hover:text-slate-950 transition-all shadow-xl shadow-black/20 font-vazir group cursor-pointer"
|
||||
>
|
||||
{getText('cta_btn_secondary', "پروانه دامپزشکی و اصالت کالا")}
|
||||
<Stethoscope className="w-5 h-5 text-canina-blue group-hover:text-slate-950 transition-colors" />
|
||||
<span>{getText('cta_btn_primary', "دریافت رژیم مکمل هوشمند")}</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="/trust-seals"
|
||||
className="w-full sm:w-auto inline-flex items-center justify-center gap-2.5 bg-white/10 hover:bg-white/20 backdrop-blur-md border border-white/30 text-white px-8 py-4 sm:px-10 sm:py-4.5 rounded-2xl font-black text-base sm:text-lg hover:scale-105 transition-all font-vazir shadow-md cursor-pointer"
|
||||
>
|
||||
<ShieldCheck className="w-5 h-5 text-emerald-300" />
|
||||
<span>{getText('cta_btn_secondary', "پروانه دامپزشکی و اصالت کالا")}</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -59,22 +59,22 @@ export default function BlogPreviewSection() {
|
||||
<section className="py-8 sm:py-20 bg-white font-vazir" dir="rtl">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between mb-6 sm:mb-16 gap-4 sm:gap-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-end justify-between mb-6 sm:mb-12 pb-4 sm:pb-6 border-b border-medical-gray-200 gap-3 sm:gap-6">
|
||||
<div className="max-w-2xl">
|
||||
<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-3 sm:mb-4">
|
||||
<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-2 sm:mb-3 font-vazir">
|
||||
<BookOpen className="w-3 h-3" />
|
||||
<span>{getText("blog_preview_badge", "دانشنامه و مقالات علمی")}</span>
|
||||
</div>
|
||||
<h2 className="text-2xl sm:text-4xl md:text-5xl font-black text-medical-gray-900 leading-tight font-lalezar tracking-wide">
|
||||
<h2 className="text-2xl sm:text-3xl md:text-4xl font-black text-medical-gray-900 leading-tight font-lalezar tracking-wide">
|
||||
{getText("blog_preview_title", "تازهترین مقالات")} <span className="text-canina-blue">{getText("blog_preview_title_highlight", "دامپزشکی و سلامت")}</span>
|
||||
</h2>
|
||||
<p className="text-sm sm:text-lg text-medical-gray-500 font-medium mt-2 sm:mt-4">
|
||||
<p className="text-sm sm:text-base text-medical-gray-500 font-medium mt-2 sm:mt-3 leading-relaxed">
|
||||
{getText("blog_preview_desc", "راهنماهای علمی و کاربردی برای نگهداری، تغذیه و پیشگیری از بیماریهای سگ و گربه بر اساس آخرین تحقیقات بینالمللی.")}
|
||||
</p>
|
||||
</div>
|
||||
<Link
|
||||
href="/blog"
|
||||
className="inline-flex items-center gap-1.5 sm:gap-2 text-canina-blue font-bold text-xs sm:text-sm hover:translate-x-1 transition-transform rtl:hover:-translate-x-1"
|
||||
className="inline-flex items-center gap-1.5 sm:gap-2 text-canina-blue font-black text-xs sm:text-sm hover:translate-x-1 transition-all rtl:hover:-translate-x-1 group font-vazir self-start sm:self-auto shrink-0"
|
||||
>
|
||||
<span>{getText("blog_preview_view_all", "مشاهده همه مقالات")}</span>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
@ -83,7 +83,7 @@ export default function BlogPreviewSection() {
|
||||
|
||||
{/* Blog Grid */}
|
||||
{isLoading ? (
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-8 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-8 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none snap-x snap-mandatory md:snap-none overscroll-x-contain">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div
|
||||
key={i}
|
||||
@ -96,7 +96,7 @@ export default function BlogPreviewSection() {
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-8 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-8 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none snap-x snap-mandatory md:snap-none overscroll-x-contain">
|
||||
{blogs.map((blog, idx) => {
|
||||
const image = blog.imageUrl?.startsWith("http")
|
||||
? blog.imageUrl
|
||||
|
||||
@ -191,26 +191,26 @@ export default function FeaturedProducts() {
|
||||
return (
|
||||
<section className="py-8 sm:py-16 bg-medical-gray-50">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="flex items-center justify-between w-full mb-6 sm:mb-12 pb-4 sm:pb-6 border-b border-medical-gray-200 gap-2">
|
||||
<div>
|
||||
<div className="text-canina-blue text-[10px] sm:text-xs font-bold uppercase tracking-[0.2em] mb-1 sm:mb-2 font-vazir">
|
||||
<div className="flex flex-col sm:flex-row sm:items-end justify-between w-full mb-6 sm:mb-12 pb-4 sm:pb-6 border-b border-medical-gray-200 gap-3 sm:gap-6">
|
||||
<div className="max-w-2xl">
|
||||
<div className="text-canina-blue text-[10px] sm:text-xs font-bold uppercase tracking-[0.2em] mb-1.5 sm:mb-2 font-vazir">
|
||||
{getText("featured_badge", "بیشترین انتخاب توسط دامپزشکان")}
|
||||
</div>
|
||||
<h2 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-black text-medical-gray-900 font-lalezar tracking-wide">
|
||||
<h2 className="text-2xl sm:text-3xl md:text-4xl font-black text-medical-gray-900 font-lalezar tracking-wide leading-tight">
|
||||
{getText("featured_title_line1", "محصولات برگزیده و راهکارهای")}{" "}
|
||||
<span className="text-canina-blue">{getText("featured_title_line2", "درمان تخصصی")}</span>
|
||||
</h2>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => router.push("/shop")}
|
||||
className="inline-flex items-center gap-1 sm:gap-2 text-canina-blue font-black text-xs sm:text-sm hover:translate-x-1 transition-all group font-vazir shrink-0"
|
||||
<Link
|
||||
href="/shop"
|
||||
className="inline-flex items-center gap-1.5 sm:gap-2 text-canina-blue font-black text-xs sm:text-sm hover:translate-x-1 transition-all rtl:hover:-translate-x-1 group font-vazir self-start sm:self-auto shrink-0"
|
||||
>
|
||||
<span>{getText("featured_view_all", "مشاهده تمامی محصولات")}</span>
|
||||
<span className="text-sm sm:text-lg group-hover:-translate-x-1 transition-transform">←</span>
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none snap-x snap-mandatory md:snap-none overscroll-x-contain">
|
||||
{isLoading ? (
|
||||
Array.from({ length: 4 }).map((_, i) => (
|
||||
<div key={i} className="w-[68vw] sm:w-[50vw] md:w-auto flex-shrink-0 snap-start">
|
||||
|
||||
@ -98,31 +98,31 @@ export default function VetGallery({ testimonials = [] }: { testimonials?: Testi
|
||||
return (
|
||||
<section className="py-8 sm:py-20 bg-white font-vazir relative overflow-hidden" dir="rtl">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="flex flex-col md:flex-row md:items-end justify-between mb-6 sm:mb-16 gap-4 sm:gap-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-end justify-between mb-6 sm:mb-12 pb-4 sm:pb-6 border-b border-medical-gray-200 gap-3 sm:gap-6">
|
||||
<div className="max-w-2xl">
|
||||
<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-3 sm:mb-4">
|
||||
<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-2 sm:mb-3 font-vazir">
|
||||
<Star className="w-3 h-3" />
|
||||
{getText('videos_badge', "Vet Insights")}
|
||||
</div>
|
||||
<h2 className="text-2xl sm:text-4xl md:text-5xl font-black text-medical-gray-900 leading-tight font-lalezar tracking-wide" suppressHydrationWarning>
|
||||
<h2 className="text-2xl sm:text-3xl md:text-4xl font-black text-medical-gray-900 leading-tight font-lalezar tracking-wide" suppressHydrationWarning>
|
||||
{getText('videos_title', "مشاوره ویدئویی")} <span className="text-canina-blue underline decoration-4 decoration-canina-blue/20 underline-offset-8">{getText('videos_title_highlight', "دوست دامپزشک پت شما")}</span>
|
||||
</h2>
|
||||
<p className="text-sm sm:text-lg text-medical-gray-500 font-medium mt-2 sm:mt-6" suppressHydrationWarning>
|
||||
<p className="text-sm sm:text-base text-medical-gray-500 font-medium mt-2 sm:mt-3 leading-relaxed" suppressHydrationWarning>
|
||||
{getText('videos_desc', "تیم علمی و فرمولهکنندگان کمپانی کنینا در آلمان مستقیماً با شما صحبت میکنند؛ آشنایی با نحوه مصرف، مزایای بالینی و دانش پزشکی پشت هر محصول.")}
|
||||
</p>
|
||||
</div>
|
||||
<Link
|
||||
href="/videos"
|
||||
className="inline-flex items-center gap-2 text-canina-blue font-bold text-xs sm:text-sm hover:translate-x-1 transition-transform rtl:hover:-translate-x-1"
|
||||
className="inline-flex items-center gap-1.5 sm:gap-2 text-canina-blue font-black text-xs sm:text-sm hover:translate-x-1 transition-all rtl:hover:-translate-x-1 group font-vazir self-start sm:self-auto shrink-0"
|
||||
>
|
||||
{getText('videos_view_all', "مشاهده همه ویدئوها")}
|
||||
<Play className="w-4 h-4" />
|
||||
<span>{getText('videos_view_all', "مشاهده همه ویدئوها")}</span>
|
||||
<Play className="w-3.5 h-3.5" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Video Grid or Skeleton */}
|
||||
{isLoading ? (
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none snap-x snap-mandatory md:snap-none overscroll-x-contain">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<div key={i} className="w-[68vw] sm:w-[50vw] md:w-auto flex-shrink-0 snap-start rounded-[2rem] p-2 space-y-3 animate-pulse">
|
||||
<div className="aspect-video bg-medical-gray-100 rounded-[1.5rem] sm:rounded-[2rem]" />
|
||||
@ -132,7 +132,7 @@ export default function VetGallery({ testimonials = [] }: { testimonials?: Testi
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none touch-pan-x snap-x snap-mandatory md:snap-none">
|
||||
<div className="flex md:grid md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6 overflow-x-auto md:overflow-visible pb-4 md:pb-0 micro-hscroll -mx-4 px-4 md:mx-0 md:px-0 select-none snap-x snap-mandatory md:snap-none overscroll-x-contain">
|
||||
{apiVideos.map((video, index) => (
|
||||
<div key={video.id} className="w-[68vw] sm:w-[50vw] md:w-auto flex-shrink-0 snap-start flex">
|
||||
<motion.button
|
||||
|
||||
@ -122,7 +122,7 @@
|
||||
"120": "compilerOptions",
|
||||
"121": "backend/README.md",
|
||||
"122": "AdminController",
|
||||
"123": "RouteErrorBoundary",
|
||||
"123": "ConfirmModal.tsx",
|
||||
"124": "Repository Map",
|
||||
"125": "validate_integrity.js",
|
||||
"126": "admin-panel/package.json",
|
||||
@ -176,7 +176,7 @@
|
||||
"174": "rebuild_honest_ledger.js",
|
||||
"175": "validate_evidence_grade.js",
|
||||
"176": "uploads/[...path]/route.ts",
|
||||
"177": "Reviews.tsx",
|
||||
"177": "app.e2e-spec.js",
|
||||
"178": "نقشه جامع پوشش تستهای سرتاسری (E2E Test Coverage Map) — پروژه Canina",
|
||||
"179": "track/page.tsx",
|
||||
"180": "API Contract Specification",
|
||||
@ -268,7 +268,7 @@
|
||||
"266": "@types/express",
|
||||
"267": "@types/jest",
|
||||
"268": "@types/multer",
|
||||
"269": "bcrypt",
|
||||
"269": "@nestjs/swagger",
|
||||
"270": "app-audit-verification.e2e-spec.d.ts",
|
||||
"271": "app.e2e-spec.d.ts",
|
||||
"272": "Canina Pharma GmbH",
|
||||
@ -294,7 +294,7 @@
|
||||
"292": "Production Docker Compose",
|
||||
"293": "Staging Docker Compose",
|
||||
"294": "ZibalService",
|
||||
"295": "eslint",
|
||||
"295": "@eslint/eslintrc",
|
||||
"296": "@nestjs/throttler",
|
||||
"297": "ZibalEBankService",
|
||||
"298": ".initiateOrderPayment",
|
||||
@ -305,8 +305,9 @@
|
||||
"303": "@nestjs/schematics",
|
||||
"304": "reflect-metadata",
|
||||
"305": "swagger-ui-express",
|
||||
"306": "globals",
|
||||
"306": "eslint-plugin-react-hooks",
|
||||
"307": "eslint-config-prettier",
|
||||
"308": "tailwindcss",
|
||||
"309": "axios",
|
||||
"310": "tailwindcss",
|
||||
"311": "jest",
|
||||
@ -329,6 +330,5 @@
|
||||
"328": "orders.service.ts",
|
||||
"329": "videos.controller.ts",
|
||||
"330": "WikiService",
|
||||
"331": "eslint-plugin-prettier",
|
||||
"332": "eslint-config-next"
|
||||
"331": "eslint-plugin-prettier"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -13,14 +13,14 @@
|
||||
"11": "UsersService",
|
||||
"12": "index.ts",
|
||||
"13": "app-audit-verification.e2e-spec.js",
|
||||
"14": "toPersian",
|
||||
"14": "CheckoutPage.tsx",
|
||||
"15": "src/services/api.ts",
|
||||
"16": "DoctorQueryDto",
|
||||
"17": "schema.ts",
|
||||
"18": "JwtAuthGuard",
|
||||
"19": "admin.controller.ts",
|
||||
"20": "CreateVideoDto",
|
||||
"21": "useSettingsStore",
|
||||
"21": "HomeClient.tsx",
|
||||
"22": "AdminService",
|
||||
"23": "MenuService",
|
||||
"24": "BE-001",
|
||||
@ -47,7 +47,7 @@
|
||||
"45": "What You Must Do When Invoked",
|
||||
"46": "20260526145407_init/migration.sql",
|
||||
"47": "IngredientsService",
|
||||
"48": "app.e2e-spec.js",
|
||||
"48": "toPersian",
|
||||
"49": "devDependencies",
|
||||
"50": "devDependencies",
|
||||
"51": "BlogsController",
|
||||
@ -89,7 +89,7 @@
|
||||
"87": "dependencies",
|
||||
"88": "CreateEBankCheckoutDto",
|
||||
"89": "seed-products.ts",
|
||||
"90": "SmartAdvisor.tsx",
|
||||
"90": "useSettingsStore",
|
||||
"91": "Reconciled Audit Roles & Assignments",
|
||||
"92": "OrdersService",
|
||||
"93": "auth.service.ts",
|
||||
@ -112,7 +112,7 @@
|
||||
"110": "Operational Rules & Boundaries",
|
||||
"111": "Operational Rules & Boundaries",
|
||||
"112": "Operational Rules & Boundaries",
|
||||
"113": "cartStore.ts",
|
||||
"113": "orderService.ts",
|
||||
"114": "AppService",
|
||||
"115": "Spinner.tsx",
|
||||
"116": "Vazirmatn Changelog",
|
||||
@ -196,7 +196,7 @@
|
||||
"194": "Raw Finding Verification & Disposition Report",
|
||||
"195": "React + TypeScript + Vite",
|
||||
"196": "Select.tsx",
|
||||
"197": "ClientLayout.tsx",
|
||||
"197": "AuthModal.tsx",
|
||||
"198": "app/page.tsx",
|
||||
"199": "prisma",
|
||||
"200": "application/README.md",
|
||||
@ -268,7 +268,7 @@
|
||||
"266": "@types/express",
|
||||
"267": "@types/jest",
|
||||
"268": "@types/multer",
|
||||
"269": "eslint-plugin-react-hooks",
|
||||
"269": "bcrypt",
|
||||
"270": "app-audit-verification.e2e-spec.d.ts",
|
||||
"271": "app.e2e-spec.d.ts",
|
||||
"272": "Canina Pharma GmbH",
|
||||
@ -294,7 +294,7 @@
|
||||
"292": "Production Docker Compose",
|
||||
"293": "Staging Docker Compose",
|
||||
"294": "ZibalService",
|
||||
"295": "@nestjs/swagger",
|
||||
"295": "eslint",
|
||||
"296": "@nestjs/throttler",
|
||||
"297": "ZibalEBankService",
|
||||
"298": ".initiateOrderPayment",
|
||||
@ -305,9 +305,8 @@
|
||||
"303": "@nestjs/schematics",
|
||||
"304": "reflect-metadata",
|
||||
"305": "swagger-ui-express",
|
||||
"306": "components/Skeleton.tsx",
|
||||
"306": "globals",
|
||||
"307": "eslint-config-prettier",
|
||||
"308": "@eslint/eslintrc",
|
||||
"309": "axios",
|
||||
"310": "tailwindcss",
|
||||
"311": "jest",
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
# Graph Report - canina (2026-09-06)
|
||||
|
||||
## Corpus Check
|
||||
- 604 files · ~1,120,105 words
|
||||
- 604 files · ~1,120,712 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 4258 nodes · 7827 edges · 333 communities (219 shown, 114 thin omitted)
|
||||
- 4258 nodes · 7827 edges · 332 communities (218 shown, 114 thin omitted)
|
||||
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 298 edges (avg confidence: 0.79)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `1c98f1bf`
|
||||
- Built from commit: `81b16e4c`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@ -29,14 +29,14 @@
|
||||
- UsersService
|
||||
- index.ts
|
||||
- app-audit-verification.e2e-spec.js
|
||||
- toPersian
|
||||
- CheckoutPage.tsx
|
||||
- src/services/api.ts
|
||||
- DoctorQueryDto
|
||||
- schema.ts
|
||||
- JwtAuthGuard
|
||||
- admin.controller.ts
|
||||
- CreateVideoDto
|
||||
- useSettingsStore
|
||||
- HomeClient.tsx
|
||||
- AdminService
|
||||
- MenuService
|
||||
- BE-001
|
||||
@ -63,7 +63,7 @@
|
||||
- What You Must Do When Invoked
|
||||
- 20260526145407_init/migration.sql
|
||||
- IngredientsService
|
||||
- app.e2e-spec.js
|
||||
- toPersian
|
||||
- devDependencies
|
||||
- devDependencies
|
||||
- BlogsController
|
||||
@ -105,7 +105,7 @@
|
||||
- dependencies
|
||||
- CreateEBankCheckoutDto
|
||||
- seed-products.ts
|
||||
- SmartAdvisor.tsx
|
||||
- useSettingsStore
|
||||
- Reconciled Audit Roles & Assignments
|
||||
- OrdersService
|
||||
- auth.service.ts
|
||||
@ -128,7 +128,7 @@
|
||||
- Operational Rules & Boundaries
|
||||
- Operational Rules & Boundaries
|
||||
- Operational Rules & Boundaries
|
||||
- cartStore.ts
|
||||
- orderService.ts
|
||||
- AppService
|
||||
- Spinner.tsx
|
||||
- Vazirmatn Changelog
|
||||
@ -211,7 +211,7 @@
|
||||
- Raw Finding Verification & Disposition Report
|
||||
- React + TypeScript + Vite
|
||||
- Select.tsx
|
||||
- ClientLayout.tsx
|
||||
- AuthModal.tsx
|
||||
- app/page.tsx
|
||||
- prisma
|
||||
- application/README.md
|
||||
@ -279,7 +279,7 @@
|
||||
- @types/express
|
||||
- @types/jest
|
||||
- @types/multer
|
||||
- eslint-plugin-react-hooks
|
||||
- bcrypt
|
||||
- Canina Pharma GmbH
|
||||
- Pets Table
|
||||
- Canina Iran Project Introduction
|
||||
@ -294,7 +294,7 @@
|
||||
- Production Docker Compose
|
||||
- Staging Docker Compose
|
||||
- ZibalService
|
||||
- @nestjs/swagger
|
||||
- eslint
|
||||
- @nestjs/throttler
|
||||
- ZibalEBankService
|
||||
- .initiateOrderPayment
|
||||
@ -305,9 +305,8 @@
|
||||
- @nestjs/schematics
|
||||
- reflect-metadata
|
||||
- swagger-ui-express
|
||||
- components/Skeleton.tsx
|
||||
- globals
|
||||
- eslint-config-prettier
|
||||
- @eslint/eslintrc
|
||||
- jest
|
||||
- @types/passport-jwt
|
||||
- 20260526160916_add_ui_texts_and_scientific_terms/migration.sql
|
||||
@ -354,19 +353,19 @@
|
||||
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
|
||||
|
||||
## Import Cycles
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
||||
|
||||
## Communities (333 total, 114 thin omitted)
|
||||
## Communities (332 total, 114 thin omitted)
|
||||
|
||||
### Community 0 - "Roles"
|
||||
Cohesion: 0.24
|
||||
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
|
||||
|
||||
### Community 1 - "app.module.ts"
|
||||
Cohesion: 0.07
|
||||
Nodes (38): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+30 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (41): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+33 more)
|
||||
|
||||
### Community 2 - "WikiController"
|
||||
Cohesion: 0.21
|
||||
@ -374,7 +373,7 @@ Nodes (9): ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, Controller
|
||||
|
||||
### Community 3 - "productService.ts"
|
||||
Cohesion: 0.06
|
||||
Nodes (33): dynamic, GET(), revalidate, DEFAULT_CATEGORIES, dynamic, revalidate, dynamic, revalidate (+25 more)
|
||||
Nodes (40): buildTorobProductSpec(), buildTorobProductTitle(), dynamic, GET(), revalidate, dynamic, GET(), revalidate (+32 more)
|
||||
|
||||
### Community 4 - "PetsController"
|
||||
Cohesion: 0.15
|
||||
@ -398,7 +397,7 @@ Nodes (27): SmsEventDefinition, SmsService, Injectable, SmsLogQueryDto, ApiPrope
|
||||
|
||||
### Community 9 - "devDependencies"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
|
||||
Nodes (9): devDependencies, @eslint/eslintrc, @types/bcryptjs, @types/node, typescript, @types/node, typescript, @eslint/eslintrc (+1 more)
|
||||
|
||||
### Community 10 - "CreateReviewDto"
|
||||
Cohesion: 0.07
|
||||
@ -416,9 +415,9 @@ Nodes (24): backend, frontend, playwright.config.ts, @playwright/test, tests/**/
|
||||
Cohesion: 0.06
|
||||
Nodes (28): AppModule, Module, EnvironmentVariables, IsNotEmpty, IsOptional, IsString, validateEnv(), CustomHttpExceptionFilter (+20 more)
|
||||
|
||||
### Community 14 - "toPersian"
|
||||
Cohesion: 0.12
|
||||
Nodes (27): VerifyContent(), AddressFormData, AddressModal(), AddressModalProps, normalizeDigits(), validateAddressForm(), ArchivePage(), B2BPortal() (+19 more)
|
||||
### Community 14 - "CheckoutPage.tsx"
|
||||
Cohesion: 0.17
|
||||
Nodes (19): AddressFormData, AddressModal(), AddressModalProps, normalizeDigits(), validateAddressForm(), BackButton(), BackButtonProps, CheckoutPage() (+11 more)
|
||||
|
||||
### Community 15 - "src/services/api.ts"
|
||||
Cohesion: 0.06
|
||||
@ -444,9 +443,9 @@ Nodes (12): ApplyGlobalMarginsDto, BulkPriceAdjustmentDto, ApiProperty, ApiPrope
|
||||
Cohesion: 0.09
|
||||
Nodes (24): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+16 more)
|
||||
|
||||
### Community 21 - "useSettingsStore"
|
||||
Cohesion: 0.07
|
||||
Nodes (30): HomeClient(), HomeClientProps, BannerPlacement(), BannerPlacementProps, BlogPreviewSection(), BrandLogo(), BrandLogoProps, FAQSection() (+22 more)
|
||||
### Community 21 - "HomeClient.tsx"
|
||||
Cohesion: 0.10
|
||||
Nodes (20): HomeClient(), HomeClientProps, BannerPlacement(), BannerPlacementProps, BlogPreviewSection(), FAQItem, FAQSection(), Hero() (+12 more)
|
||||
|
||||
### Community 23 - "MenuService"
|
||||
Cohesion: 0.12
|
||||
@ -548,13 +547,13 @@ Nodes (14): "coupons", "health_logs", "order_items", "orders", "pet_medical_cond
|
||||
Cohesion: 0.13
|
||||
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||
|
||||
### Community 48 - "app.e2e-spec.js"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): app_module_1, supertest_1, testing_1
|
||||
### Community 48 - "toPersian"
|
||||
Cohesion: 0.14
|
||||
Nodes (24): VerifyContent(), AuthModal(), B2BPortal(), CartDrawer(), Header(), MENU_ICONS, MobileBottomNav(), SOLUTION_ITEMS (+16 more)
|
||||
|
||||
### Community 49 - "devDependencies"
|
||||
Cohesion: 0.11
|
||||
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
|
||||
Nodes (19): autoprefixer, eslint-plugin-react-hooks, devDependencies, autoprefixer, eslint, @eslint/js, eslint-plugin-react-hooks, postcss (+11 more)
|
||||
|
||||
### Community 50 - "devDependencies"
|
||||
Cohesion: 0.12
|
||||
@ -601,8 +600,8 @@ Cohesion: 0.23
|
||||
Nodes (10): CreateUserDto, ApiProperty, ApiPropertyOptional, IsEmail, IsNotEmpty, IsNumber, IsOptional, IsString (+2 more)
|
||||
|
||||
### Community 61 - "ProductPage.tsx"
|
||||
Cohesion: 0.14
|
||||
Nodes (32): ArchiveProductCard(), ArchiveProductListItem(), CATEGORY_MAP, ICON_MAP, FeaturedProducts(), ProductCard(), OrderSuccess(), PetProfile() (+24 more)
|
||||
Cohesion: 0.12
|
||||
Nodes (28): ArchiveProductCard(), ArchiveProductListItem(), CATEGORY_MAP, ICON_MAP, FeaturedProducts(), ProductCard(), ProductImageZoomModalProps, CalculatorState (+20 more)
|
||||
|
||||
### Community 62 - "ReportsController"
|
||||
Cohesion: 0.14
|
||||
@ -610,7 +609,7 @@ Nodes (11): ReportsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, C
|
||||
|
||||
### Community 63 - "dependencies"
|
||||
Cohesion: 0.09
|
||||
Nodes (23): dependencies, bcrypt, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport (+15 more)
|
||||
Nodes (23): dependencies, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport, @nestjs/platform-express (+15 more)
|
||||
|
||||
### Community 64 - "compilerOptions"
|
||||
Cohesion: 0.10
|
||||
@ -629,8 +628,8 @@ Cohesion: 0.13
|
||||
Nodes (15): CreatePetDto, ApiProperty, ApiPropertyOptional, IsArray, IsNotEmpty, IsNumber, IsOptional, IsString (+7 more)
|
||||
|
||||
### Community 68 - "lib/services/api.ts"
|
||||
Cohesion: 0.12
|
||||
Nodes (17): B2BLandingClient(), BlogPost, ContactInfoItem, FAQItem, OrderDetailsModal(), OrderDetailsModalProps, Testimonial, api (+9 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (25): BlogPost, ContactInfoItem, DeleteConfirmModal(), DeleteConfirmModalProps, OrderDetailsModal(), OrderDetailsModalProps, OrderRowSkeleton(), PetProfileSkeleton() (+17 more)
|
||||
|
||||
### Community 69 - "Required Review Group Closures"
|
||||
Cohesion: 0.10
|
||||
@ -716,9 +715,9 @@ Nodes (8): CreateEBankCheckoutDto, ApiProperty, ApiPropertyOptional, IsNotEmpty,
|
||||
Cohesion: 0.17
|
||||
Nodes (12): prisma, main(), prisma, determineSuitableFor(), findOrCreateCategory(), getProductImageUrl(), main(), parseSize() (+4 more)
|
||||
|
||||
### Community 90 - "SmartAdvisor.tsx"
|
||||
Cohesion: 0.17
|
||||
Nodes (11): ClientLayout(), MobileBottomNav, metadata, MobileBottomNav(), SOLUTION_ITEMS, CURRENT_SYMPTOMS, MEDICAL_HISTORIES, SmartAdvisor() (+3 more)
|
||||
### Community 90 - "useSettingsStore"
|
||||
Cohesion: 0.08
|
||||
Nodes (28): B2BPortal, CartDrawer, ClientLayout(), MobileBottomNav, PrescriptionUploadModal, metadata, ArchivePage(), B2BLandingClient() (+20 more)
|
||||
|
||||
### Community 91 - "Reconciled Audit Roles & Assignments"
|
||||
Cohesion: 0.12
|
||||
@ -808,9 +807,9 @@ Nodes (10): 1. Mark Active Task as Complete, 2. Documentation Updates, 3. Dynami
|
||||
Cohesion: 0.18
|
||||
Nodes (10): 1. Pre-Deployment Checklist, 2. Build Verification, 3. Deployment Strategy (Based on Target), 4. Post-Deployment Health Check, 5. Forbidden Actions, Expected JSON Output Schema, Operational Rules & Boundaries, Required Output Artifacts (What files to write/update) (+2 more)
|
||||
|
||||
### Community 113 - "cartStore.ts"
|
||||
Cohesion: 0.11
|
||||
Nodes (13): CartDrawer, CartDrawer(), DeleteConfirmModal(), DeleteConfirmModalProps, mockProduct, ApiErr, Order, OrderItem (+5 more)
|
||||
### Community 113 - "orderService.ts"
|
||||
Cohesion: 0.20
|
||||
Nodes (4): ApiErr, Order, OrderItem, OrderService
|
||||
|
||||
### Community 114 - "AppService"
|
||||
Cohesion: 0.29
|
||||
@ -933,8 +932,8 @@ Cohesion: 0.25
|
||||
Nodes (6): app_module_1, core_1, fs, path, swagger_1, yaml
|
||||
|
||||
### Community 144 - "SafeImage.tsx"
|
||||
Cohesion: 0.09
|
||||
Nodes (26): buildTorobProductSpec(), buildTorobProductTitle(), dynamic, GET(), revalidate, BlogPostClientProps, PLAYBACK_RATES, PodcastInlinePlayer() (+18 more)
|
||||
Cohesion: 0.11
|
||||
Nodes (21): BlogPostClientProps, PLAYBACK_RATES, PodcastInlinePlayer(), PodcastInlinePlayerProps, PLAYBACK_RATES, PodcastPlayerModal(), PodcastPlayerModalProps, VideoModalPlayer (+13 more)
|
||||
|
||||
### Community 145 - "AdminLoginDto"
|
||||
Cohesion: 0.29
|
||||
@ -1104,9 +1103,9 @@ Nodes (3): Expanding the ESLint configuration, React Compiler, React + TypeScrip
|
||||
Cohesion: 0.50
|
||||
Nodes (3): Select, SelectOption, SelectProps
|
||||
|
||||
### Community 197 - "ClientLayout.tsx"
|
||||
Cohesion: 0.06
|
||||
Nodes (34): AuthModal, B2BPortal, LoginModal, PrescriptionUploadModal, AuthModal(), AuthModalProps, extractOtpFromText(), otpCooldownExpiries (+26 more)
|
||||
### Community 197 - "AuthModal.tsx"
|
||||
Cohesion: 0.08
|
||||
Nodes (19): AuthModal, LoginModal, AuthModalProps, extractOtpFromText(), otpCooldownExpiries, IMPORTANT: only depend on isOpen here — NOT subView. If we depend on subView,, extractOtpFromText(), LoginModal() (+11 more)
|
||||
|
||||
### Community 198 - "app/page.tsx"
|
||||
Cohesion: 0.67
|
||||
@ -1136,10 +1135,6 @@ Nodes (4): PaymentService, Injectable, Injectable, ZibalService
|
||||
Cohesion: 0.20
|
||||
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
|
||||
|
||||
### Community 306 - "components/Skeleton.tsx"
|
||||
Cohesion: 0.21
|
||||
Nodes (5): OrderRowSkeleton(), PetProfileSkeleton(), ProductListSkeleton(), Skeleton(), SkeletonProps
|
||||
|
||||
### Community 317 - "revalidate/route.ts"
|
||||
Cohesion: 0.83
|
||||
Nodes (3): GET(), handleRevalidate(), POST()
|
||||
@ -1173,8 +1168,8 @@ _Questions this graph is uniquely positioned to answer:_
|
||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||
_1356 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
- **Should `app.module.ts` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.06516290726817042 - nodes in this community are weakly interconnected._
|
||||
_Cohesion score 0.05901639344262295 - nodes in this community are weakly interconnected._
|
||||
- **Should `productService.ts` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.06497175141242938 - nodes in this community are weakly interconnected._
|
||||
_Cohesion score 0.056189640035118525 - nodes in this community are weakly interconnected._
|
||||
- **Should `CmsController` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.0899854862119013 - nodes in this community are weakly interconnected._
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
# Graph Report - canina (2026-09-06)
|
||||
|
||||
## Corpus Check
|
||||
- 604 files · ~1,120,712 words
|
||||
- 604 files · ~1,121,126 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
@ -10,7 +10,7 @@
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `81b16e4c`
|
||||
- Built from commit: `49eb1e5f`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@ -138,7 +138,7 @@
|
||||
- compilerOptions
|
||||
- backend/README.md
|
||||
- AdminController
|
||||
- RouteErrorBoundary
|
||||
- ConfirmModal.tsx
|
||||
- Repository Map
|
||||
- validate_integrity.js
|
||||
- admin-panel/package.json
|
||||
@ -191,7 +191,7 @@
|
||||
- rebuild_honest_ledger.js
|
||||
- validate_evidence_grade.js
|
||||
- uploads/[...path]/route.ts
|
||||
- Reviews.tsx
|
||||
- app.e2e-spec.js
|
||||
- نقشه جامع پوشش تستهای سرتاسری (E2E Test Coverage Map) — پروژه Canina
|
||||
- track/page.tsx
|
||||
- API Contract Specification
|
||||
@ -279,7 +279,7 @@
|
||||
- @types/express
|
||||
- @types/jest
|
||||
- @types/multer
|
||||
- bcrypt
|
||||
- @nestjs/swagger
|
||||
- Canina Pharma GmbH
|
||||
- Pets Table
|
||||
- Canina Iran Project Introduction
|
||||
@ -294,7 +294,7 @@
|
||||
- Production Docker Compose
|
||||
- Staging Docker Compose
|
||||
- ZibalService
|
||||
- eslint
|
||||
- @eslint/eslintrc
|
||||
- @nestjs/throttler
|
||||
- ZibalEBankService
|
||||
- .initiateOrderPayment
|
||||
@ -305,8 +305,9 @@
|
||||
- @nestjs/schematics
|
||||
- reflect-metadata
|
||||
- swagger-ui-express
|
||||
- globals
|
||||
- eslint-plugin-react-hooks
|
||||
- eslint-config-prettier
|
||||
- tailwindcss
|
||||
- jest
|
||||
- @types/passport-jwt
|
||||
- 20260526160916_add_ui_texts_and_scientific_terms/migration.sql
|
||||
@ -326,7 +327,6 @@
|
||||
- videos.controller.ts
|
||||
- WikiService
|
||||
- eslint-plugin-prettier
|
||||
- eslint-config-next
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
1. `Roles()` - 108 edges
|
||||
@ -353,8 +353,8 @@
|
||||
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
|
||||
|
||||
## Import Cycles
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
||||
|
||||
## Communities (332 total, 114 thin omitted)
|
||||
@ -364,8 +364,8 @@ Cohesion: 0.24
|
||||
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
|
||||
|
||||
### Community 1 - "app.module.ts"
|
||||
Cohesion: 0.06
|
||||
Nodes (41): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+33 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (38): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+30 more)
|
||||
|
||||
### Community 2 - "WikiController"
|
||||
Cohesion: 0.21
|
||||
@ -397,7 +397,7 @@ Nodes (27): SmsEventDefinition, SmsService, Injectable, SmsLogQueryDto, ApiPrope
|
||||
|
||||
### Community 9 - "devDependencies"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): devDependencies, @eslint/eslintrc, @types/bcryptjs, @types/node, typescript, @types/node, typescript, @eslint/eslintrc (+1 more)
|
||||
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
|
||||
|
||||
### Community 10 - "CreateReviewDto"
|
||||
Cohesion: 0.07
|
||||
@ -421,7 +421,7 @@ Nodes (19): AddressFormData, AddressModal(), AddressModalProps, normalizeDigits(
|
||||
|
||||
### Community 15 - "src/services/api.ts"
|
||||
Cohesion: 0.06
|
||||
Nodes (36): Layout(), ProtectedRoute(), MenuGroup, Sidebar(), SidebarProps, SubMenuItem, LiveMonitoringSummary, SEARCHABLE_PAGES (+28 more)
|
||||
Nodes (38): Layout(), ProtectedRoute(), MenuGroup, Sidebar(), SidebarProps, SubMenuItem, LiveMonitoringSummary, SEARCHABLE_PAGES (+30 more)
|
||||
|
||||
### Community 16 - "DoctorQueryDto"
|
||||
Cohesion: 0.09
|
||||
@ -485,7 +485,7 @@ Nodes (31): Acceptance Criteria, Affected Application, Affected Files, Alternati
|
||||
|
||||
### Community 32 - "adminRoutes.tsx"
|
||||
Cohesion: 0.07
|
||||
Nodes (21): App(), ContactInfoItem, ContactSubmission, CategoryDist, DashboardData, SslStatus, Ticket, TicketMessage (+13 more)
|
||||
Nodes (16): App(), Props, RouteErrorBoundary, State, HeroBanner, VetTestimonial, SslStatus, AdminRouteConfig (+8 more)
|
||||
|
||||
### Community 33 - "WholesaleApplyDto"
|
||||
Cohesion: 0.10
|
||||
@ -553,11 +553,11 @@ Nodes (24): VerifyContent(), AuthModal(), B2BPortal(), CartDrawer(), Header(), M
|
||||
|
||||
### Community 49 - "devDependencies"
|
||||
Cohesion: 0.11
|
||||
Nodes (19): autoprefixer, eslint-plugin-react-hooks, devDependencies, autoprefixer, eslint, @eslint/js, eslint-plugin-react-hooks, postcss (+11 more)
|
||||
Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, globals, postcss, @types/node (+11 more)
|
||||
|
||||
### Community 50 - "devDependencies"
|
||||
Cohesion: 0.12
|
||||
Nodes (17): devDependencies, eslint, jsdom, tailwindcss, @testing-library/jest-dom, @testing-library/react, @types/node, @types/react (+9 more)
|
||||
Nodes (17): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, @testing-library/jest-dom, @testing-library/react, @types/node (+9 more)
|
||||
|
||||
### Community 51 - "BlogsController"
|
||||
Cohesion: 0.07
|
||||
@ -572,8 +572,8 @@ Cohesion: 0.13
|
||||
Nodes (14): SmartAdvisorController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||
|
||||
### Community 54 - "Button.tsx"
|
||||
Cohesion: 0.10
|
||||
Nodes (16): ButtonProps, ButtonSize, ButtonVariant, ConfirmModal(), ConfirmModalProps, HeroBanner, VetTestimonial, FAQ (+8 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (24): ButtonProps, ButtonSize, ButtonVariant, maxWidthClasses, Modal(), ModalProps, ContactInfoItem, ContactSubmission (+16 more)
|
||||
|
||||
### Community 55 - "UITexts.tsx"
|
||||
Cohesion: 0.08
|
||||
@ -609,7 +609,7 @@ Nodes (11): ReportsController, ApiBearerAuth, ApiOperation, ApiQuery, ApiTags, C
|
||||
|
||||
### Community 63 - "dependencies"
|
||||
Cohesion: 0.09
|
||||
Nodes (23): dependencies, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport, @nestjs/platform-express (+15 more)
|
||||
Nodes (23): dependencies, bcrypt, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport (+15 more)
|
||||
|
||||
### Community 64 - "compilerOptions"
|
||||
Cohesion: 0.10
|
||||
@ -772,8 +772,8 @@ Cohesion: 0.15
|
||||
Nodes (12): 10. `TASK-VERIFY-001`, 1. `TASK-SEC-001`, 2. `TASK-SEC-002`, 3. `TASK-SEC-003`, 4. `TASK-FIN-001`, 5. `TASK-BUILD-001`, 6. `TASK-AUTH-001`, 7. `TASK-FE-001` (+4 more)
|
||||
|
||||
### Community 104 - "Products.tsx"
|
||||
Cohesion: 0.10
|
||||
Nodes (24): Input, InputProps, formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData (+16 more)
|
||||
Cohesion: 0.09
|
||||
Nodes (25): Input, InputProps, formatPriceWithCommas(), PriceInput(), PriceInputProps, toEnglishDigits(), Coupon, CouponFormData (+17 more)
|
||||
|
||||
### Community 105 - "Operational Rules & Boundaries"
|
||||
Cohesion: 0.17
|
||||
@ -816,8 +816,8 @@ Cohesion: 0.29
|
||||
Nodes (5): AppController, Controller, Get, AppService, Injectable
|
||||
|
||||
### Community 115 - "Spinner.tsx"
|
||||
Cohesion: 0.07
|
||||
Nodes (36): ImagePreviewModal(), ImagePreviewModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, maxWidthClasses, Modal() (+28 more)
|
||||
Cohesion: 0.10
|
||||
Nodes (22): ImagePreviewModal(), ImagePreviewModalProps, getFileType(), Media, MediaSelector(), MediaSelectorProps, Spinner(), Doctor (+14 more)
|
||||
|
||||
### Community 116 - "Vazirmatn Changelog"
|
||||
Cohesion: 0.18
|
||||
@ -847,9 +847,9 @@ Nodes (9): Compile and run the project, Deployment, Description, License, Projec
|
||||
Cohesion: 0.17
|
||||
Nodes (12): AdminController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Param (+4 more)
|
||||
|
||||
### Community 123 - "RouteErrorBoundary"
|
||||
Cohesion: 0.22
|
||||
Nodes (3): Props, RouteErrorBoundary, State
|
||||
### Community 123 - "ConfirmModal.tsx"
|
||||
Cohesion: 0.10
|
||||
Nodes (16): ConfirmModal(), ConfirmModalProps, Pagination(), PaginationProps, Category, Pet, DoctorOption, Video (+8 more)
|
||||
|
||||
### Community 124 - "Repository Map"
|
||||
Cohesion: 0.20
|
||||
@ -1051,9 +1051,9 @@ Nodes (4): activeFiles, errors, validationOutput, warnings
|
||||
Cohesion: 0.53
|
||||
Nodes (5): dynamic, GET(), getCandidateUrls(), getMimeType(), HEAD()
|
||||
|
||||
### Community 177 - "Reviews.tsx"
|
||||
Cohesion: 0.40
|
||||
Nodes (5): BlogCommentItem, ProductReview, Reviews(), toPersianDigits(), Reviews
|
||||
### Community 177 - "app.e2e-spec.js"
|
||||
Cohesion: 0.50
|
||||
Nodes (3): app_module_1, supertest_1, testing_1
|
||||
|
||||
### Community 178 - "نقشه جامع پوشش تستهای سرتاسری (E2E Test Coverage Map) — پروژه Canina"
|
||||
Cohesion: 0.33
|
||||
@ -1168,7 +1168,7 @@ _Questions this graph is uniquely positioned to answer:_
|
||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||
_1356 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
- **Should `app.module.ts` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.05901639344262295 - nodes in this community are weakly interconnected._
|
||||
_Cohesion score 0.06516290726817042 - nodes in this community are weakly interconnected._
|
||||
- **Should `productService.ts` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.056189640035118525 - nodes in this community are weakly interconnected._
|
||||
- **Should `CmsController` be split into smaller, more focused modules?**
|
||||
|
||||
2
graphify-out/cache/stat-index.json
vendored
2
graphify-out/cache/stat-index.json
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user