@@ -23,114 +23,53 @@ const WIDTH_19_INCH = Math.round(19 * PIXELS_PER_INCH);
2323const WIDTH_10_INCH = Math . round ( 10 * PIXELS_PER_INCH ) ;
2424const RAIL_WIDTH = Math . round ( 0.625 * PIXELS_PER_INCH ) ;
2525
26- // Add window augmentation for Google Analytics
27- declare global {
28- interface Window {
29- dataLayer : any [ ] ;
30- gtag : ( ...args : any [ ] ) => void ;
31- }
32- }
3326
34- export default function RackPlanner ( ) {
35- // --- State ---
36- const [ isDarkMode , setIsDarkMode ] = useState ( ( ) => {
37- if ( typeof window !== 'undefined' ) {
38- const saved = localStorage . getItem ( 'darkMode' ) ;
39- if ( saved !== null ) {
40- return saved === 'true' ;
41- }
42- return window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
43- }
44- return true ;
45- } ) ;
4627
47- const [ areAnimationsEnabled , setAreAnimationsEnabled ] = useState ( ( ) => {
48- if ( typeof window !== 'undefined' ) {
49- const saved = localStorage . getItem ( 'animationsEnabled' ) ;
50- return saved !== null ? saved === 'true' : true ;
51- }
52- return true ;
53- } ) ;
54-
55- const [ isLoading , setIsLoading ] = useState ( true ) ;
56-
57- // Rack Configuration
28+ export default function App ( ) {
5829 const [ rackSettings , setRackSettings ] = useState < RackSettings > ( {
5930 heightU : 10 ,
60- widthStandard : '10inch ' ,
31+ widthStandard : '19inch ' ,
6132 } ) ;
6233 const [ rackSlots , setRackSlots ] = useState < RackSlot [ ] > ( [ ] ) ;
63-
64- // Library State
65- const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
66- const [ libraryTab , setLibraryTab ] = useState < 'catalog' | 'custom' > ( 'catalog' ) ;
6734 const [ customLibrary , setCustomLibrary ] = useState < RackModule [ ] > ( [ ] ) ;
35+ const [ isLoading , setIsLoading ] = useState ( true ) ;
6836
69- // Drag State
70- const [ draggedItem , setDraggedItem ] = useState < {
71- module : RackModule ;
72- originalIndex ?: number ;
73- } | null > ( null ) ;
37+ const [ scale , setScale ] = useState ( 1 ) ;
38+ const containerRef = useRef < HTMLDivElement > ( null ) ;
39+ const fileInputRef = useRef < HTMLInputElement > ( null ) ;
40+ const [ isDarkMode , setIsDarkMode ] = useState ( ( ) => {
41+ if ( typeof window !== 'undefined' ) {
42+ const saved = localStorage . getItem ( 'theme' ) ;
43+ if ( saved ) {
44+ return saved === 'dark' ;
45+ }
46+ return window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
47+ }
48+ return false ;
49+ } ) ;
50+ const [ areAnimationsEnabled , setAreAnimationsEnabled ] = useState ( true ) ;
51+ const [ draggedItem , setDraggedItem ] = useState < { module : RackModule ; originalIndex ?: number } | null > ( null ) ;
7452 const [ dragOverIndex , setDragOverIndex ] = useState < number | null > ( null ) ;
75-
76- // Custom Form State
53+ const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
54+ const [ libraryTab , setLibraryTab ] = useState < 'catalog' | 'custom' > ( 'catalog' ) ;
55+ const [ editingModuleId , setEditingModuleId ] = useState < string | null > ( null ) ;
7756 const [ customName , setCustomName ] = useState ( '' ) ;
7857 const [ customU , setCustomU ] = useState ( 1 ) ;
7958 const [ customType , setCustomType ] = useState < ModuleType > ( 'generic' ) ;
8059 const [ customColor , setCustomColor ] = useState ( COLOR_OPTIONS [ 0 ] . value ) ;
8160 const [ customImage , setCustomImage ] = useState < string | null > ( null ) ;
82- const [ customShowName , setCustomShowName ] = useState ( true ) ; // Added customShowName state
83- const [ editingModuleId , setEditingModuleId ] = useState < string | null > ( null ) ;
61+ const [ customShowName , setCustomShowName ] = useState ( true ) ;
8462
85- const fileInputRef = useRef < HTMLInputElement > ( null ) ;
86- const containerRef = useRef < HTMLElement > ( null ) ;
87- const [ scale , setScale ] = useState ( 1 ) ;
88-
89- // --- Persistence & Initialization ---
90-
91- // Handle Dark Mode
9263 useEffect ( ( ) => {
93- console . log ( 'Dark mode state changed:' , isDarkMode ) ;
94- const root = window . document . documentElement ;
9564 if ( isDarkMode ) {
96- root . classList . add ( 'dark' ) ;
97- console . log ( 'Added dark class to html ') ;
65+ document . documentElement . classList . add ( 'dark' ) ;
66+ localStorage . setItem ( 'theme' , ' dark') ;
9867 } else {
99- root . classList . remove ( 'dark' ) ;
100- console . log ( 'Removed dark class from html ') ;
68+ document . documentElement . classList . remove ( 'dark' ) ;
69+ localStorage . setItem ( 'theme' , 'light ') ;
10170 }
102- localStorage . setItem ( 'darkMode' , String ( isDarkMode ) ) ;
10371 } , [ isDarkMode ] ) ;
10472
105- useEffect ( ( ) => {
106- localStorage . setItem ( 'animationsEnabled' , String ( areAnimationsEnabled ) ) ;
107- } , [ areAnimationsEnabled ] ) ;
108-
109- // Handle Google Analytics
110- useEffect ( ( ) => {
111- const gaId = import . meta. env . VITE_GOOGLE_ANALYTICS_ID ;
112-
113- if ( gaId && typeof window !== 'undefined' ) {
114- // Load the script
115- const script = document . createElement ( 'script' ) ;
116- script . async = true ;
117- script . src = `https://www.googletagmanager.com/gtag/js?id=${ gaId } ` ;
118- document . head . appendChild ( script ) ;
119-
120- // Initialize dataLayer
121- window . dataLayer = window . dataLayer || [ ] ;
122- function gtag ( ...args : any [ ] ) {
123- window . dataLayer . push ( args ) ;
124- }
125- window . gtag = gtag ;
126-
127- gtag ( 'js' , new Date ( ) ) ;
128- gtag ( 'config' , gaId ) ;
129-
130- console . log ( 'Google Analytics initialized with ID:' , gaId ) ;
131- }
132- } , [ ] ) ;
133-
13473 // Handle Responsive Scaling
13574 useEffect ( ( ) => {
13675 const handleResize = ( ) => {
0 commit comments