1
+ import React , { useEffect , useRef , useState } from 'react' ;
1
2
import { Link } from 'react-router-dom' ;
2
3
import { RiArrowRightSLine } from 'react-icons/ri' ;
3
4
import ContentLoader from 'react-content-loader' ;
4
- import React from 'react' ;
5
5
6
6
interface SectionProps {
7
7
title : string ;
@@ -11,6 +11,7 @@ interface SectionProps {
11
11
buttonText : string ;
12
12
isImageLoaded : boolean ;
13
13
setIsImageLoaded : ( loaded : boolean ) => void ;
14
+ imgUrl : string ;
14
15
}
15
16
16
17
const Section : React . FC < SectionProps > = ( {
@@ -21,36 +22,73 @@ const Section: React.FC<SectionProps> = ({
21
22
buttonText,
22
23
isImageLoaded,
23
24
setIsImageLoaded,
24
- } ) => (
25
- < div className = "w-full max-w-[800px] bg-slate-100 bg-gradient-to-r from-gray-100 to-gray-200 p-4 text-center" >
26
- < h2 className = "mt-20 text-2xl font-semibold text-orange-500 xs:text-xl" > { title } </ h2 >
27
- < p className = "mt-10 text-3xl font-bold xs:text-2xl" > { subtitle } </ p >
28
- < p className = "mt-10 text-[16px] text-gray-500 xs:text-[16px]" > { description } </ p >
29
- < div className = "flex justify-center" >
30
- < Link
31
- to = { linkTo }
32
- className = "gray-400 mt-4 flex h-12 w-32 items-center justify-center rounded-[20px] bg-white px-4 py-2 font-bold hover:bg-orange-600 hover:text-white xs:h-11 xs:w-28" >
33
- { buttonText } < RiArrowRightSLine size = { 20 } />
34
- </ Link >
25
+ imgUrl,
26
+ } ) => {
27
+ const [ isVisible , setIsVisible ] = useState ( false ) ;
28
+ const sectionRef = useRef < HTMLDivElement > ( null ) ;
29
+
30
+ useEffect ( ( ) => {
31
+ const observer = new IntersectionObserver (
32
+ ( entries ) => {
33
+ entries . forEach ( ( entry ) => {
34
+ if ( entry . isIntersecting ) {
35
+ setIsVisible ( true ) ;
36
+ }
37
+ } ) ;
38
+ } ,
39
+ { threshold : 0.05 } ,
40
+ ) ;
41
+ if ( sectionRef . current ) {
42
+ observer . observe ( sectionRef . current ) ;
43
+ }
44
+ return ( ) => {
45
+ if ( sectionRef . current ) {
46
+ observer . unobserve ( sectionRef . current ) ;
47
+ }
48
+ } ;
49
+ } , [ ] ) ;
50
+
51
+ return (
52
+ < div
53
+ ref = { sectionRef }
54
+ className = "relative w-full max-w-[600px] overflow-hidden bg-slate-100 bg-gradient-to-r from-gray-100 to-gray-200 p-4 text-center" >
55
+ < h2
56
+ className = { `mt-20 text-2xl font-semibold text-orange-500 xs:text-xl ${ isVisible ? 'animate-slideInLeft' : 'opacity-0' } ` } >
57
+ { title }
58
+ </ h2 >
59
+ < p className = { `mt-10 text-3xl font-bold xs:text-2xl ${ isVisible ? 'animate-slideInLeft' : 'opacity-0' } ` } >
60
+ { subtitle }
61
+ </ p >
62
+ < p
63
+ className = { `mt-10 text-[16px] text-gray-500 xs:text-[16px] ${ isVisible ? 'animate-slideInLeft' : 'opacity-0' } ` } >
64
+ { description }
65
+ </ p >
66
+ < div className = { `flex justify-center ${ isVisible ? 'animate-slideInLeft' : 'opacity-0' } ` } >
67
+ < Link
68
+ to = { linkTo }
69
+ className = "gray-400 mt-4 flex h-12 w-32 items-center justify-center rounded-[20px] bg-white px-4 py-2 font-bold hover:bg-orange-600 hover:text-white xs:h-11 xs:w-28" >
70
+ { buttonText } < RiArrowRightSLine size = { 20 } />
71
+ </ Link >
72
+ </ div >
73
+ { ! isImageLoaded && (
74
+ < ContentLoader
75
+ height = { 200 }
76
+ width = { 200 }
77
+ speed = { 2 }
78
+ backgroundColor = "#f3f3f3"
79
+ foregroundColor = "#ecebeb"
80
+ className = "mx-auto mb-20 mt-20" >
81
+ < circle cx = "100" cy = "100" r = "100" />
82
+ </ ContentLoader >
83
+ ) }
84
+ < img
85
+ src = { imgUrl }
86
+ alt = "example"
87
+ className = { `mx-auto mb-5 mt-20 xs:mt-10 ${ isVisible ? 'animate-slideInRight' : 'opacity-0' } ` }
88
+ onLoad = { ( ) => setIsImageLoaded ( true ) }
89
+ />
35
90
</ div >
36
- { ! isImageLoaded && (
37
- < ContentLoader
38
- height = { 200 }
39
- width = { 200 }
40
- speed = { 2 }
41
- backgroundColor = "#f3f3f3"
42
- foregroundColor = "#ecebeb"
43
- className = "mx-auto mb-20 mt-20" >
44
- < circle cx = "100" cy = "100" r = "100" />
45
- </ ContentLoader >
46
- ) }
47
- < img
48
- src = "/images/HomeExample.svg"
49
- alt = "example"
50
- className = { `mx-auto mb-20 mt-20 ${ isImageLoaded ? 'block' : 'hidden' } ` }
51
- onLoad = { ( ) => setIsImageLoaded ( true ) }
52
- />
53
- </ div >
54
- ) ;
91
+ ) ;
92
+ } ;
55
93
56
94
export default Section ;
0 commit comments