1- import React , { useEffect , useState } from 'react' ;
2- import { X , Scan } from '@phosphor-icons/react' ;
3- import { motion , AnimatePresence } from 'framer-motion' ;
1+ import React from 'react' ;
2+ import { useVisualSettings } from '../context/VisualSettingsContext' ;
3+ import BrutalistImageModal from './BrutalistImageModal' ;
4+ import LuxeImageModal from './LuxeImageModal' ;
45
5- const ImageModal = ( { src , alt , onClose } ) => {
6- const [ dimensions , setDimensions ] = useState ( null ) ;
6+ const ImageModal = ( props ) => {
7+ const { fezcodexTheme } = useVisualSettings ( ) ;
78
8- useEffect ( ( ) => {
9- if ( src ) {
10- document . body . style . overflow = 'hidden' ;
11- } else {
12- document . body . style . overflow = '' ;
13- }
9+ if ( fezcodexTheme === 'luxe' ) {
10+ return < LuxeImageModal { ...props } /> ;
11+ }
1412
15- const handleKeyDown = ( e ) => {
16- if ( e . key === 'Escape' ) {
17- onClose ( ) ;
18- }
19- } ;
20-
21- if ( src ) {
22- window . addEventListener ( 'keydown' , handleKeyDown ) ;
23- }
24-
25- return ( ) => {
26- document . body . style . overflow = '' ;
27- window . removeEventListener ( 'keydown' , handleKeyDown ) ;
28- } ;
29- } , [ src , onClose ] ) ;
30-
31- const handleImageLoad = ( e ) => {
32- setDimensions ( {
33- width : e . target . naturalWidth ,
34- height : e . target . naturalHeight
35- } ) ;
36- } ;
37-
38- const showAlt = alt && ! [ 'Project Detail' , 'Enlarged Content' , 'Intel Imagery' , 'Full size image' ] . includes ( alt ) ;
39-
40- return (
41- < AnimatePresence >
42- { src && (
43- < motion . div
44- className = "fixed inset-0 z-[100] flex items-center justify-center bg-black/90 backdrop-blur-xl p-2 md:p-4"
45- onClick = { onClose }
46- initial = { { opacity : 0 } }
47- animate = { { opacity : 1 } }
48- exit = { { opacity : 0 } }
49- transition = { { duration : 0.2 } }
50- >
51- { /* Grid Background Overlay */ }
52- < div className = "absolute inset-0 pointer-events-none opacity-10"
53- style = { { backgroundImage : 'radial-gradient(circle, #444 1px, transparent 1px)' , backgroundSize : '30px 30px' } }
54- />
55-
56- < motion . div
57- className = "relative w-full h-full max-w-[85vw] max-h-[85vh] flex flex-col"
58- onClick = { ( e ) => e . stopPropagation ( ) }
59- initial = { { scale : 0.98 , opacity : 0 } }
60- animate = { { scale : 1 , opacity : 1 } }
61- exit = { { scale : 0.98 , opacity : 0 } }
62- transition = { { type : "spring" , damping : 30 , stiffness : 300 } }
63- >
64- { /* Header Bar */ }
65- < div className = "flex items-center justify-between bg-black/60 border border-white/10 border-b-0 p-2 md:p-3 backdrop-blur-md rounded-t-sm" >
66- < div className = "flex items-center gap-3" >
67- < Scan className = "text-emerald-500 animate-pulse" size = { 16 } />
68- < span className = "font-mono text-[10px] uppercase tracking-[0.3em] text-gray-400" >
69- SYSTEM.IMG_VIEWER // SECURE_MODE
70- </ span >
71- </ div >
72- < div className = "flex items-center gap-2" >
73- < span className = "hidden md:inline font-mono text-[9px] text-gray-600 uppercase tracking-widest mr-2" > Press ESC to exit</ span >
74- < button
75- onClick = { onClose }
76- className = "group flex items-center gap-2 px-4 py-1.5 bg-white/5 hover:bg-red-500 text-gray-400 hover:text-white border border-white/10 rounded-sm transition-all"
77- >
78- < X size = { 16 } weight = "bold" />
79- </ button >
80- </ div >
81- </ div >
82-
83- { /* Image Container */ }
84- < div className = "relative flex-1 min-h-0 bg-black/40 backdrop-blur-sm rounded-b-sm overflow-hidden flex items-center justify-center" >
85- { /* Corner Accents */ }
86- < div className = "absolute top-0 left-0 w-6 h-6 border-l-2 border-t-2 border-emerald-500/30 z-10" />
87- < div className = "absolute top-0 right-0 w-6 h-6 border-r-2 border-t-2 border-emerald-500/30 z-10" />
88- < div className = "absolute bottom-0 left-0 w-6 h-6 border-l-2 border-b-2 border-emerald-500/30 z-10" />
89- < div className = "absolute bottom-0 right-0 w-6 h-6 border-r-2 border-b-2 border-emerald-500/30 z-10" />
90-
91- < img
92- src = { src }
93- alt = { alt }
94- onLoad = { handleImageLoad }
95- style = { { maxWidth : '100%' , maxHeight : '100%' } }
96- className = "w-auto h-auto object-contain block shadow-[0_0_50px_rgba(0,0,0,0.5)] select-none"
97- />
98- </ div >
99-
100- { /* Footer Metadata */ }
101- < div className = "mt-3 flex justify-between items-center px-2" >
102- < div className = "flex gap-4" >
103- < span className = "font-mono text-sm uppercase tracking-widest text-white font-bold truncate max-w-[50vw]" >
104- { showAlt ? alt : 'RAW_STREAM' }
105- </ span >
106- </ div >
107- < span className = "font-mono text-sm uppercase tracking-widest text-white font-bold text-right" >
108- { dimensions ? `${ dimensions . width } x ${ dimensions . height } PX` : 'CALCULATING...' }
109- </ span >
110- </ div >
111-
112- </ motion . div >
113- </ motion . div >
114- ) }
115- </ AnimatePresence >
116- ) ;
13+ return < BrutalistImageModal { ...props } /> ;
11714} ;
11815
119- export default ImageModal ;
16+ export default ImageModal ;
0 commit comments