feat(footer): add expandable read-more and read-less with gradient fade for SEO brand text
Some checks failed
Deploy Canina / deploy (push) Successful in 2m17s
E2E Playwright Tests / Run Full E2E & Security Suites (push) Failing after 0s

This commit is contained in:
parsa aghaei 2026-09-06 11:36:40 +03:30
parent 1ea9920914
commit 81b16e4c62
3 changed files with 674 additions and 639 deletions

View File

@ -1,7 +1,7 @@
"use client";
import React, { useState, useEffect } from "react";
import Image from "next/image";
import { Phone, Mail, MapPin, Instagram, ShieldCheck, Globe, ArrowUp, Download } from "lucide-react";
import { Phone, Mail, MapPin, Instagram, ShieldCheck, Globe, ArrowUp, Download, ChevronDown, ChevronUp } from "lucide-react";
import { useSettingsStore } from "../lib/store/settingsStore";
import BrandLogo from "./BrandLogo";
import Link from "next/link";
@ -19,6 +19,7 @@ export default function Footer({
const isB2BEnabled = useSettingsStore((s) => s.getBoolean('b2bRegistrationOpen', true) && s.getBoolean('b2b_enabled', true));
const [showScroll, setShowScroll] = useState(false);
const [footerCol1, setFooterCol1] = useState<Array<{ id?: string; label: string; href: string }>>([]);
const [isDescExpanded, setIsDescExpanded] = useState(false);
useEffect(() => {
fetch(`${process.env.NEXT_PUBLIC_API_URL || '/api'}/menu/type/FOOTER_COL1`)
@ -47,6 +48,9 @@ export default function Footer({
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const brandDesc = getText('footer_brand_desc', "تدارک هوشمندانه سلامت برای همراهان وفادار شما. واردکننده انحصاری مکمل‌های درمانی با گرید دارویی اختصاصی از آلمان با سابقه ۴۰ سال نوآوری.");
const isLongDesc = brandDesc.length > 120;
return (
<footer className="bg-medical-gray-900 text-white pt-10 sm:pt-24 pb-28 sm:pb-12 font-shabnam relative" dir="rtl">
{/* Floating Back-to-Top Button */}
@ -65,7 +69,7 @@ export default function Footer({
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 sm:gap-16 mb-8 sm:mb-20">
{/* Brand Presence */}
<div className="space-y-4 sm:space-y-8">
<div className="space-y-4 sm:space-y-6">
<div className="flex items-center justify-between">
<BrandLogo isDarkBackground size="lg" />
<div className="flex gap-2.5 sm:hidden">
@ -81,10 +85,41 @@ export default function Footer({
)}
</div>
</div>
<p className="text-xs sm:text-sm text-slate-300 leading-relaxed font-medium">
{getText('footer_brand_desc', "تدارک هوشمندانه سلامت برای همراهان وفادار شما. واردکننده انحصاری مکمل‌های درمانی با گرید دارویی اختصاصی از آلمان با سابقه ۴۰ سال نوآوری.")}
</p>
<div className="hidden sm:flex gap-4">
{/* Expandable SEO-friendly Brand Description */}
<div className="relative">
<div
className={`text-xs sm:text-sm text-slate-300 leading-relaxed font-medium transition-all duration-500 overflow-hidden ${
!isDescExpanded && isLongDesc
? "max-h-[5rem] sm:max-h-[5.5rem] [mask-image:linear-gradient(to_bottom,black_50%,transparent_100%)]"
: "max-h-[1000px]"
}`}
>
<p className="whitespace-pre-line">{brandDesc}</p>
</div>
{isLongDesc && (
<button
type="button"
onClick={() => setIsDescExpanded(!isDescExpanded)}
className="mt-1.5 inline-flex items-center gap-1 text-[11px] sm:text-xs font-bold text-canina-teal hover:text-white transition-colors cursor-pointer"
>
{isDescExpanded ? (
<>
<span>بستن توضیحات</span>
<ChevronUp className="w-3.5 h-3.5" />
</>
) : (
<>
<span>مشاهده بیشتر</span>
<ChevronDown className="w-3.5 h-3.5" />
</>
)}
</button>
)}
</div>
<div className="hidden sm:flex gap-4 pt-1">
{getText('contact_instagram', '') && (
<a href={getText('contact_instagram', '#')} target="_blank" rel="noopener noreferrer" aria-label="صفحه اینستاگرام رسمی کنینا ایران" className="w-10 h-10 bg-white/10 rounded-xl flex items-center justify-center hover:bg-canina-blue hover:text-white transition-all text-slate-300">
<Instagram className="w-5 h-5" />

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff