feat(product-page): add AI-powered badge and informative subtitle to scientific media section
This commit is contained in:
parent
a00778ffaa
commit
5db23443ed
@ -781,13 +781,21 @@ export default function ProductPage({ productSlug }: { productSlug: string }) {
|
|||||||
{/* Multimedia & Scientific Documentation (Video, Podcast & PDF Catalog) */}
|
{/* Multimedia & Scientific Documentation (Video, Podcast & PDF Catalog) */}
|
||||||
{(product.videoUrl || product.podcastUrl || product.pdfUrl) && (
|
{(product.videoUrl || product.podcastUrl || product.pdfUrl) && (
|
||||||
<section className="bg-white border border-medical-gray-200 rounded-[2.5rem] p-8 md:p-10 shadow-md space-y-8 font-vazir" dir="rtl">
|
<section className="bg-white border border-medical-gray-200 rounded-[2.5rem] p-8 md:p-10 shadow-md space-y-8 font-vazir" dir="rtl">
|
||||||
<div className="flex items-center gap-2.5 sm:gap-4 border-b border-medical-gray-100 pb-4 sm:pb-6">
|
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-medical-gray-100 pb-4 sm:pb-6">
|
||||||
<div className="w-9 h-9 sm:w-12 sm:h-12 bg-canina-blue text-white rounded-xl sm:rounded-2xl flex items-center justify-center shadow-lg shrink-0">
|
<div className="flex items-center gap-2.5 sm:gap-4">
|
||||||
<Sparkles className="w-4 h-4 sm:w-6 sm:h-6" />
|
<div className="w-9 h-9 sm:w-12 sm:h-12 bg-canina-blue text-white rounded-xl sm:rounded-2xl flex items-center justify-center shadow-lg shrink-0">
|
||||||
</div>
|
<Sparkles className="w-4 h-4 sm:w-6 sm:h-6" />
|
||||||
<div>
|
</div>
|
||||||
<h3 className="text-lg sm:text-2xl md:text-3xl font-black text-medical-gray-900 italic">رسانه و مستندات تخصصی محصول</h3>
|
<div>
|
||||||
<p className="text-xs text-medical-gray-400 font-bold mt-0.5 sm:mt-1">ویدیو آموزشی، پادکست تحلیل علمی و دفترچه کاتالوگ کارخانه Canina</p>
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
|
<h3 className="text-lg sm:text-2xl md:text-3xl font-black text-medical-gray-900 italic">رسانه و مستندات تخصصی محصول</h3>
|
||||||
|
<span className="inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-[10px] sm:text-xs font-black bg-purple-100 border border-purple-200 text-purple-700 shadow-2xs">
|
||||||
|
<Sparkles className="w-3 h-3 text-purple-600 animate-pulse" />
|
||||||
|
<span>تحلیل هوشمند (AI-Powered)</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-xs text-medical-gray-400 font-bold mt-0.5 sm:mt-1">ویدیو آموزشی، پادکست تحلیل علمی تولیدشده با هوش مصنوعی و دفترچه کاتالوگ کارخانه Canina</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import React, { useState, useRef, useEffect, useCallback } from "react";
|
import React, { useState, useRef, useEffect, useCallback } from "react";
|
||||||
import { motion, AnimatePresence } from "motion/react";
|
import { motion, AnimatePresence } from "motion/react";
|
||||||
import {
|
import {
|
||||||
Play,
|
Play,
|
||||||
Pause,
|
Pause,
|
||||||
RotateCcw,
|
RotateCcw,
|
||||||
RotateCw,
|
RotateCw,
|
||||||
Volume2,
|
Volume2,
|
||||||
VolumeX,
|
VolumeX,
|
||||||
Maximize,
|
Maximize,
|
||||||
Minimize,
|
Minimize,
|
||||||
Download,
|
Download,
|
||||||
Share2,
|
Share2,
|
||||||
X,
|
X,
|
||||||
Check,
|
Check,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
ChevronUp,
|
ChevronUp,
|
||||||
Sparkles,
|
Sparkles,
|
||||||
Loader2
|
Loader2
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
@ -311,7 +311,7 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{/* Native Video Element */}
|
{/* Native Video Element */}
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 flex items-center justify-center cursor-pointer"
|
className="absolute inset-0 flex items-center justify-center cursor-pointer"
|
||||||
onClick={togglePlay}
|
onClick={togglePlay}
|
||||||
>
|
>
|
||||||
@ -354,9 +354,8 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
|
|||||||
|
|
||||||
{/* Top Header Overlay */}
|
{/* Top Header Overlay */}
|
||||||
<div
|
<div
|
||||||
className={`absolute top-0 left-0 right-0 p-4 sm:p-6 bg-gradient-to-b from-black/80 via-black/40 to-transparent transition-opacity duration-300 z-20 flex items-center justify-between ${
|
className={`absolute top-0 left-0 right-0 p-4 sm:p-6 bg-gradient-to-b from-black/80 via-black/40 to-transparent transition-opacity duration-300 z-20 flex items-center justify-between ${showControls ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
||||||
showControls ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3 text-right">
|
<div className="flex items-center gap-3 text-right">
|
||||||
<div className="w-8 h-8 rounded-full bg-canina-blue/20 text-canina-blue flex items-center justify-center shrink-0">
|
<div className="w-8 h-8 rounded-full bg-canina-blue/20 text-canina-blue flex items-center justify-center shrink-0">
|
||||||
@ -407,193 +406,191 @@ export default function VideoModalPlayer({ isOpen, onClose, video }: VideoModalP
|
|||||||
|
|
||||||
{/* Bottom Custom Controls Bar */}
|
{/* Bottom Custom Controls Bar */}
|
||||||
<div
|
<div
|
||||||
className={`absolute bottom-0 left-0 right-0 p-4 sm:p-6 bg-gradient-to-t from-black/90 via-black/60 to-transparent transition-opacity duration-300 z-20 space-y-3 ${
|
className={`absolute bottom-0 left-0 right-0 p-4 sm:p-6 bg-gradient-to-t from-black/90 via-black/60 to-transparent transition-opacity duration-300 z-20 space-y-3 ${showControls ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
||||||
showControls ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
|
}`}
|
||||||
}`}
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
|
|
||||||
{/* Progress / Seek Bar with filled progress & buffer tracks */}
|
{/* Progress / Seek Bar with filled progress & buffer tracks */}
|
||||||
<div className="flex items-center gap-3 dir-ltr" dir="ltr">
|
<div className="flex items-center gap-3 dir-ltr" dir="ltr">
|
||||||
<span className="text-[11px] font-mono font-bold text-white/70 w-10 text-right">
|
<span className="text-[11px] font-mono font-bold text-white/70 w-10 text-right">
|
||||||
{formatTime(currentTime)}
|
{formatTime(currentTime)}
|
||||||
</span>
|
</span>
|
||||||
<div className="relative flex-1 flex items-center h-4">
|
<div className="relative flex-1 flex items-center h-4">
|
||||||
{/* Background & Buffer & Progress Track */}
|
{/* Background & Buffer & Progress Track */}
|
||||||
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
|
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
|
||||||
{/* Buffered bar */}
|
{/* Buffered bar */}
|
||||||
<div
|
<div
|
||||||
className="h-full bg-white/35 transition-all duration-300"
|
className="h-full bg-white/35 transition-all duration-300"
|
||||||
style={{ width: `${bufferedPercent}%` }}
|
style={{ width: `${bufferedPercent}%` }}
|
||||||
/>
|
|
||||||
{/* Played progress bar */}
|
|
||||||
<div
|
|
||||||
className="h-full bg-canina-blue transition-all -mt-1.5"
|
|
||||||
style={{ width: `${progressPercent}%` }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
min={0}
|
|
||||||
max={duration || 100}
|
|
||||||
step={0.1}
|
|
||||||
value={currentTime}
|
|
||||||
onChange={handleSeek}
|
|
||||||
className="w-full h-4 opacity-0 absolute inset-0 cursor-pointer z-10"
|
|
||||||
/>
|
|
||||||
{/* Visual Scrubber Thumb */}
|
|
||||||
<div
|
|
||||||
className="absolute w-3.5 h-3.5 bg-white rounded-full shadow-md pointer-events-none -translate-x-1/2 transition-transform hover:scale-125"
|
|
||||||
style={{ left: `${progressPercent}%` }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span className="text-[11px] font-mono font-bold text-white/70 w-10 text-left">
|
|
||||||
{formatTime(duration)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Action Buttons Row */}
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
{/* Left Controls (Playback & Jumps with - on Left and + on Right in RTL) */}
|
|
||||||
<div className="flex items-center gap-2 sm:gap-3" dir="rtl">
|
|
||||||
{/* Play/Pause */}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={togglePlay}
|
|
||||||
className="w-10 h-10 rounded-full bg-canina-blue hover:bg-canina-blue/90 text-white flex items-center justify-center transition-transform hover:scale-105 cursor-pointer shadow-lg shadow-canina-blue/30"
|
|
||||||
title={isPlaying ? "توقف" : "پخش"}
|
|
||||||
>
|
|
||||||
{isPlaying ? <Pause className="w-5 h-5 fill-white" /> : <Play className="w-5 h-5 fill-white ml-0.5" />}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* -10s button */}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => skipTime(-10)}
|
|
||||||
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
|
|
||||||
title="۱۰ ثانیه عقب"
|
|
||||||
>
|
|
||||||
<RotateCcw className="w-3.5 h-3.5" />
|
|
||||||
<span>-10s</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* +10s button */}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => skipTime(10)}
|
|
||||||
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
|
|
||||||
title="۱۰ ثانیه جلو"
|
|
||||||
>
|
|
||||||
<RotateCw className="w-3.5 h-3.5" />
|
|
||||||
<span>+10s</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Volume Slider: Increases towards the speaker icon */}
|
|
||||||
<div className="hidden sm:flex items-center gap-2 pr-2" dir="ltr">
|
|
||||||
<div className="relative w-20 flex items-center h-4">
|
|
||||||
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
|
|
||||||
<div
|
|
||||||
className="h-full bg-canina-blue transition-all"
|
|
||||||
style={{ width: `${volumePercent}%` }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
step={0.05}
|
|
||||||
value={isMuted ? 0 : volume}
|
|
||||||
onChange={handleVolumeChange}
|
|
||||||
className="w-full h-4 opacity-0 absolute inset-0 cursor-pointer z-10"
|
|
||||||
/>
|
/>
|
||||||
<div
|
{/* Played progress bar */}
|
||||||
className="absolute w-2.5 h-2.5 bg-white rounded-full shadow pointer-events-none -translate-x-1/2"
|
<div
|
||||||
style={{ left: `${volumePercent}%` }}
|
className="h-full bg-canina-blue transition-all -mt-1.5"
|
||||||
|
style={{ width: `${progressPercent}%` }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<input
|
||||||
type="button"
|
type="range"
|
||||||
onClick={toggleMute}
|
min={0}
|
||||||
className="p-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer"
|
max={duration || 100}
|
||||||
title={isMuted ? "صدا وصل" : "بیصدا"}
|
step={0.1}
|
||||||
>
|
value={currentTime}
|
||||||
{isMuted || volume === 0 ? <VolumeX className="w-4 h-4" /> : <Volume2 className="w-4 h-4" />}
|
onChange={handleSeek}
|
||||||
</button>
|
className="w-full h-4 opacity-0 absolute inset-0 cursor-pointer z-10"
|
||||||
|
/>
|
||||||
|
{/* Visual Scrubber Thumb */}
|
||||||
|
<div
|
||||||
|
className="absolute w-3.5 h-3.5 bg-white rounded-full shadow-md pointer-events-none -translate-x-1/2 transition-transform hover:scale-125"
|
||||||
|
style={{ left: `${progressPercent}%` }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<span className="text-[11px] font-mono font-bold text-white/70 w-10 text-left">
|
||||||
|
{formatTime(duration)}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right Controls (Speed Menu & Fullscreen) */}
|
{/* Action Buttons Row */}
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center justify-between" dir="ltr">
|
||||||
{/* Playback Rate Popup Menu with click-outside */}
|
{/* Left Controls (Playback & Jumps with - on Left and + on Right in RTL) */}
|
||||||
<div className="relative" ref={rateMenuRef}>
|
<div className="flex items-center gap-2 sm:gap-3" dir="ltr">
|
||||||
|
{/* Play/Pause */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowRateMenu(!showRateMenu)}
|
onClick={togglePlay}
|
||||||
className="px-2.5 py-1 rounded-xl bg-white/10 hover:bg-white/20 text-white text-xs font-mono font-bold transition-all cursor-pointer flex items-center gap-1 border border-white/10"
|
className="w-10 h-10 rounded-full bg-canina-blue hover:bg-canina-blue/90 text-white flex items-center justify-center transition-transform hover:scale-105 cursor-pointer shadow-lg shadow-canina-blue/30"
|
||||||
title="سرعت پخش"
|
title={isPlaying ? "توقف" : "پخش"}
|
||||||
>
|
>
|
||||||
<span>{playbackRate}x</span>
|
{isPlaying ? <Pause className="w-5 h-5 fill-white" /> : <Play className="w-5 h-5 fill-white ml-0.5" />}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{showRateMenu && (
|
{/* -10s button */}
|
||||||
<div className="absolute bottom-full left-0 mb-2 bg-neutral-900/95 backdrop-blur-md border border-white/10 rounded-2xl p-1.5 shadow-2xl z-30 flex flex-col gap-1 min-w-[75px]">
|
<button
|
||||||
{PLAYBACK_RATES.map((rate) => (
|
type="button"
|
||||||
<button
|
onClick={() => skipTime(-10)}
|
||||||
key={rate}
|
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
|
||||||
type="button"
|
title="۱۰ ثانیه عقب"
|
||||||
onClick={() => handleRateChange(rate)}
|
>
|
||||||
className={`px-3 py-1.5 text-xs font-mono font-bold rounded-xl text-center transition-colors cursor-pointer ${
|
<RotateCcw className="w-3.5 h-3.5" />
|
||||||
playbackRate === rate
|
<span>-10s</span>
|
||||||
? "bg-canina-blue text-white"
|
</button>
|
||||||
: "text-white/70 hover:bg-white/10 hover:text-white"
|
|
||||||
}`}
|
{/* +10s button */}
|
||||||
>
|
<button
|
||||||
{rate}x
|
type="button"
|
||||||
</button>
|
onClick={() => skipTime(10)}
|
||||||
))}
|
className="px-2.5 py-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer flex items-center gap-1 text-xs font-mono font-bold border border-white/10"
|
||||||
|
title="۱۰ ثانیه جلو"
|
||||||
|
>
|
||||||
|
<RotateCw className="w-3.5 h-3.5" />
|
||||||
|
<span>+10s</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Volume Slider: Increases towards the speaker icon */}
|
||||||
|
<div className="hidden sm:flex items-center gap-2 pr-2" dir="ltr">
|
||||||
|
<div className="relative w-20 flex items-center h-4">
|
||||||
|
<div className="absolute inset-x-0 h-1.5 bg-white/20 rounded-lg overflow-hidden pointer-events-none">
|
||||||
|
<div
|
||||||
|
className="h-full bg-canina-blue transition-all"
|
||||||
|
style={{ width: `${volumePercent}%` }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
step={0.05}
|
||||||
|
value={isMuted ? 0 : volume}
|
||||||
|
onChange={handleVolumeChange}
|
||||||
|
className="w-full h-4 opacity-0 absolute inset-0 cursor-pointer z-10"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="absolute w-2.5 h-2.5 bg-white rounded-full shadow pointer-events-none -translate-x-1/2"
|
||||||
|
style={{ left: `${volumePercent}%` }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={toggleMute}
|
||||||
|
className="p-1.5 text-white/80 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer"
|
||||||
|
title={isMuted ? "صدا وصل" : "بیصدا"}
|
||||||
|
>
|
||||||
|
{isMuted || volume === 0 ? <VolumeX className="w-4 h-4" /> : <Volume2 className="w-4 h-4" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Fullscreen Button */}
|
{/* Right Controls (Speed Menu & Fullscreen) */}
|
||||||
<button
|
<div className="flex items-center gap-2">
|
||||||
type="button"
|
{/* Playback Rate Popup Menu with click-outside */}
|
||||||
onClick={toggleFullscreen}
|
<div className="relative" ref={rateMenuRef}>
|
||||||
className="p-2 text-white/70 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer"
|
<button
|
||||||
title={isFullscreen ? "خروج از تمام صفحه" : "تمام صفحه"}
|
type="button"
|
||||||
>
|
onClick={() => setShowRateMenu(!showRateMenu)}
|
||||||
{isFullscreen ? <Minimize className="w-4 h-4" /> : <Maximize className="w-4 h-4" />}
|
className="px-2.5 py-1 rounded-xl bg-white/10 hover:bg-white/20 text-white text-xs font-mono font-bold transition-all cursor-pointer flex items-center gap-1 border border-white/10"
|
||||||
</button>
|
title="سرعت پخش"
|
||||||
|
>
|
||||||
|
<span>{playbackRate}x</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{showRateMenu && (
|
||||||
|
<div className="absolute bottom-full left-0 mb-2 bg-neutral-900/95 backdrop-blur-md border border-white/10 rounded-2xl p-1.5 shadow-2xl z-30 flex flex-col gap-1 min-w-[75px]">
|
||||||
|
{PLAYBACK_RATES.map((rate) => (
|
||||||
|
<button
|
||||||
|
key={rate}
|
||||||
|
type="button"
|
||||||
|
onClick={() => handleRateChange(rate)}
|
||||||
|
className={`px-3 py-1.5 text-xs font-mono font-bold rounded-xl text-center transition-colors cursor-pointer ${playbackRate === rate
|
||||||
|
? "bg-canina-blue text-white"
|
||||||
|
: "text-white/70 hover:bg-white/10 hover:text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{rate}x
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Fullscreen Button */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={toggleFullscreen}
|
||||||
|
className="p-2 text-white/70 hover:text-white rounded-lg hover:bg-white/10 transition-colors cursor-pointer"
|
||||||
|
title={isFullscreen ? "خروج از تمام صفحه" : "تمام صفحه"}
|
||||||
|
>
|
||||||
|
{isFullscreen ? <Minimize className="w-4 h-4" /> : <Maximize className="w-4 h-4" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
)}
|
||||||
)}
|
</motion.div>
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
{/* Video Description Box (Rendered outside & below the video player for clean viewing) */}
|
{/* Video Description Box (Rendered outside & below the video player for clean viewing) */}
|
||||||
{video.description && (
|
{video.description && (
|
||||||
<div className="bg-neutral-900/90 backdrop-blur-md rounded-2xl p-4 text-white text-xs border border-white/10 shadow-xl space-y-2 text-right">
|
<div className="bg-neutral-900/90 backdrop-blur-md rounded-2xl p-4 text-white text-xs border border-white/10 shadow-xl space-y-2 text-right">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span className="font-black text-canina-blue text-xs">توضیحات و نکات علمی ویدئو:</span>
|
<span className="font-black text-canina-blue text-xs">توضیحات و نکات علمی ویدئو:</span>
|
||||||
{video.description.length > 120 && (
|
{video.description.length > 120 && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setIsExpandedDesc(!isExpandedDesc)}
|
onClick={() => setIsExpandedDesc(!isExpandedDesc)}
|
||||||
className="text-white/60 hover:text-white text-[11px] font-bold inline-flex items-center gap-1 cursor-pointer"
|
className="text-white/60 hover:text-white text-[11px] font-bold inline-flex items-center gap-1 cursor-pointer"
|
||||||
>
|
>
|
||||||
<span>{isExpandedDesc ? "بستن متن" : "مشاهده کامل متن"}</span>
|
<span>{isExpandedDesc ? "بستن متن" : "مشاهده کامل متن"}</span>
|
||||||
{isExpandedDesc ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
|
{isExpandedDesc ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
<p className={`font-medium text-white/80 leading-relaxed ${isExpandedDesc ? "" : "line-clamp-2"}`}>
|
||||||
|
{video.description}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p className={`font-medium text-white/80 leading-relaxed ${isExpandedDesc ? "" : "line-clamp-2"}`}>
|
)}
|
||||||
{video.description}
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</AnimatePresence>
|
||||||
</AnimatePresence>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
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 it is too large
Load Diff
Loading…
Reference in New Issue
Block a user