1- ' use client' ;
2- import { useState , useRef , useEffect } from ' react' ;
3- import Image from ' next/image' ;
1+ " use client" ;
2+ import { useState , useRef , useEffect , useCallback } from " react" ;
3+ import Image from " next/image" ;
44
55export default function Gallery ( { images } ) {
66 const [ activeImage , setActiveImage ] = useState ( null ) ;
7- const [ imageDimensions , setImageDimensions ] = useState ( { width : 0 , height : 0 } ) ;
7+ const [ imageDimensions , setImageDimensions ] = useState ( {
8+ width : 0 ,
9+ height : 0 ,
10+ } ) ;
811 const imageRef = useRef ( null ) ;
9-
12+
1013 const openModal = ( image ) => {
1114 setActiveImage ( image ) ;
12- document . body . style . overflow = ' hidden' ;
15+ document . body . style . overflow = " hidden" ;
1316 } ;
14-
17+
1518 const closeModal = ( ) => {
1619 setActiveImage ( null ) ;
17- document . body . style . overflow = ' auto' ;
20+ document . body . style . overflow = " auto" ;
1821 } ;
19-
22+
2023 // Esta función calculará las dimensiones reales de la imagen renderizada
21- const updateImageDimensions = ( ) => {
24+ const updateImageDimensions = useCallback ( ( ) => {
2225 if ( imageRef . current && activeImage ) {
2326 const img = imageRef . current ;
2427 const rect = img . getBoundingClientRect ( ) ;
2528 setImageDimensions ( {
2629 width : rect . width ,
2730 height : rect . height ,
2831 top : rect . top ,
29- left : rect . left
32+ left : rect . left ,
3033 } ) ;
3134 }
32- } ;
33-
35+ } , [ activeImage ] ) ;
36+
3437 // Actualizar dimensiones cuando cambia la imagen activa o en resize
3538 useEffect ( ( ) => {
3639 if ( activeImage ) {
37- // Permitir que la imagen se cargue y renderice primero
3840 const timer = setTimeout ( updateImageDimensions , 100 ) ;
39- window . addEventListener ( ' resize' , updateImageDimensions ) ;
40-
41+ window . addEventListener ( " resize" , updateImageDimensions ) ;
42+
4143 return ( ) => {
4244 clearTimeout ( timer ) ;
43- window . removeEventListener ( ' resize' , updateImageDimensions ) ;
45+ window . removeEventListener ( " resize" , updateImageDimensions ) ;
4446 } ;
4547 }
46- } , [ activeImage ] ) ;
47-
48+ } , [ activeImage , updateImageDimensions ] ) ;
49+
4850 return (
4951 < div >
5052 < div className = "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" >
@@ -56,19 +58,19 @@ export default function Gallery({ images }) {
5658 >
5759 < Image
5860 src = { image . src }
59- alt = { image . alt || ' Imagen de PyDay Chile' }
61+ alt = { image . alt || " Imagen de PyDay Chile" }
6062 fill
6163 className = "object-cover transition-transform duration-300 group-hover:scale-110"
6264 />
6365 < div className = "absolute inset-0 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end p-4" >
6466 < span className = "text-white text-sm font-medium" >
65- { image . caption || `PyDay ${ image . year || ' 2024' } ` }
67+ { image . caption || `PyDay ${ image . year || " 2024" } ` }
6668 </ span >
6769 </ div >
6870 </ div >
6971 ) ) }
7072 </ div >
71-
73+
7274 { /* Modal */ }
7375 { activeImage && (
7476 < div
@@ -79,44 +81,59 @@ export default function Gallery({ images }) {
7981 className = "absolute top-4 right-4 text-white p-2 hover:bg-white/10 rounded-full transition z-50"
8082 onClick = { closeModal }
8183 >
82- < svg xmlns = "http://www.w3.org/2000/svg" className = "h-6 w-6" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
83- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M6 18L18 6M6 6l12 12" />
84+ < svg
85+ xmlns = "http://www.w3.org/2000/svg"
86+ className = "h-6 w-6"
87+ fill = "none"
88+ viewBox = "0 0 24 24"
89+ stroke = "currentColor"
90+ >
91+ < path
92+ strokeLinecap = "round"
93+ strokeLinejoin = "round"
94+ strokeWidth = { 2 }
95+ d = "M6 18L18 6M6 6l12 12"
96+ />
8497 </ svg >
8598 </ button >
86-
99+
87100 < div className = "flex flex-col items-center justify-center relative max-w-3xl w-full" >
88101 { /* Contenedor de la imagen */ }
89102 < div className = "relative flex items-center justify-center w-full h-[60vh] md:h-[70vh] lg:h-[80vh]" >
90103 < div className = "relative h-full flex items-center justify-center" >
91104 < Image
92105 ref = { imageRef }
93106 src = { activeImage . src }
94- alt = { activeImage . alt || ' Imagen de PyDay Chile' }
107+ alt = { activeImage . alt || " Imagen de PyDay Chile" }
95108 width = { 1200 }
96109 height = { 900 }
97- style = { {
98- maxHeight : ' 100%' ,
99- width : ' auto' ,
100- maxWidth : ' 100%' ,
101- objectFit : ' contain'
110+ style = { {
111+ maxHeight : " 100%" ,
112+ width : " auto" ,
113+ maxWidth : " 100%" ,
114+ objectFit : " contain" ,
102115 } }
103116 onLoad = { updateImageDimensions }
104117 priority
105118 />
106-
119+
107120 { /* Caption*/ }
108121 { activeImage . caption && imageDimensions . width > 0 && (
109- < div
122+ < div
110123 className = "absolute bg-black/60 p-3 md:p-4 text-center"
111124 style = { {
112125 bottom : 0 ,
113126 width : imageDimensions . width ,
114- maxWidth : ' 100%'
127+ maxWidth : " 100%" ,
115128 } }
116129 >
117- < p className = "text-white text-sm md:text-base" > { activeImage . caption } </ p >
130+ < p className = "text-white text-sm md:text-base" >
131+ { activeImage . caption }
132+ </ p >
118133 { activeImage . location && (
119- < p className = "text-white text-xs md:text-sm opacity-70 mt-1" > { activeImage . location } </ p >
134+ < p className = "text-white text-xs md:text-sm opacity-70 mt-1" >
135+ { activeImage . location }
136+ </ p >
120137 ) }
121138 </ div >
122139 ) }
@@ -127,4 +144,4 @@ export default function Gallery({ images }) {
127144 ) }
128145 </ div >
129146 ) ;
130- }
147+ }
0 commit comments