@@ -4,18 +4,11 @@ import { Dashboard } from './Dashboard';
44import { Settings } from './Settings' ;
55import { Sidebar } from './components/Sidebar' ;
66import { Footer } from './components/Footer' ;
7- import './index.css' ;
8-
9- const INITIAL_REPOS : Repo [ ] = [
10- { id : '1' , path : 'C:\\Dev\\production-backend' , name : 'production-backend' , autoPull : true , status : 'clean' , lastCheck : '12:00:00' } ,
11- { id : '2' , path : 'C:\\Dev\\frontend-client' , name : 'frontend-client' , autoPull : false , status : 'behind' , commitsBehind : 3 , lastCheck : '11:55:00' } ,
12- ] ;
137
148const App = ( ) => {
159 const [ activeTab , setActiveTab ] = useState < 'dashboard' | 'settings' > ( 'dashboard' ) ;
16- const [ repos , setRepos ] = useState < Repo [ ] > ( INITIAL_REPOS ) ;
10+ const [ repos , setRepos ] = useState < Repo [ ] > ( [ ] ) ;
1711 const [ logs , setLogs ] = useState < LogEntry [ ] > ( [ ] ) ;
18- const [ isSimulating , setIsSimulating ] = useState ( true ) ;
1912
2013 const logsEndRef = useRef < HTMLDivElement > ( null ) ;
2114
@@ -33,19 +26,15 @@ const App = () => {
3326 logsEndRef . current ?. scrollIntoView ( { behavior : 'smooth' } ) ;
3427 } , [ logs ] ) ;
3528
36- // --- Real Data & Events ---
3729 useEffect ( ( ) => {
3830 if ( window . electronAPI ) {
39- // 1. Load persisted repos
4031 window . electronAPI . getRepos ( ) . then ( ( savedRepos : Repo [ ] ) => {
41- if ( savedRepos && savedRepos . length > 0 ) {
32+ if ( savedRepos ) {
4233 setRepos ( savedRepos ) ;
43- setIsSimulating ( false ) ; // Stop simulation if we have real data
4434 addLog ( 'Loaded repositories from storage' , 'info' ) ;
4535 }
4636 } ) ;
4737
48- // 2. Listen for backend updates
4938 const cleanup = window . electronAPI . onRepoUpdate ( ( data ) => {
5039 updateRepoStatus ( data . id , data . status as any , data . commits ) ;
5140 if ( data . status === 'behind' ) {
@@ -58,51 +47,6 @@ const App = () => {
5847 }
5948 } , [ ] ) ;
6049
61- // --- Simulation Logic ---
62- useEffect ( ( ) => {
63- if ( ! isSimulating ) return ;
64-
65- const interval = setInterval ( ( ) => {
66- if ( repos . length === 0 ) return ;
67- const repoIdx = Math . floor ( Math . random ( ) * repos . length ) ;
68- const repo = repos [ repoIdx ] ;
69-
70- if ( repo . status === 'pulling' || repo . status === 'checking' ) return ;
71-
72- updateRepoStatus ( repo . id , 'checking' ) ;
73- addLog ( `[${ repo . name } ] Checking for updates...` , 'info' ) ;
74-
75- setTimeout ( ( ) => {
76- const rand = Math . random ( ) ;
77-
78- if ( rand > 0.7 ) {
79- const behindCount = Math . floor ( Math . random ( ) * 5 ) + 1 ;
80- addLog ( `[${ repo . name } ] Found ${ behindCount } new commits.` , 'warn' ) ;
81-
82- if ( repo . autoPull ) {
83- updateRepoStatus ( repo . id , 'pulling' ) ;
84- addLog ( `[${ repo . name } ] Auto-pulling changes...` , 'info' ) ;
85-
86- setTimeout ( ( ) => {
87- updateRepoStatus ( repo . id , 'clean' , 0 ) ;
88- addLog ( `[${ repo . name } ] Successfully pulled updates.` , 'success' ) ;
89- } , 2000 ) ;
90- } else {
91- updateRepoStatus ( repo . id , 'behind' , behindCount ) ;
92- }
93- } else if ( rand > 0.95 ) {
94- updateRepoStatus ( repo . id , 'error' ) ;
95- addLog ( `[${ repo . name } ] Error: Network timeout.` , 'error' ) ;
96- } else {
97- updateRepoStatus ( repo . id , 'clean' ) ;
98- }
99- } , 1500 ) ;
100-
101- } , 4000 ) ;
102-
103- return ( ) => clearInterval ( interval ) ;
104- } , [ repos , isSimulating ] ) ;
105-
10650 const updateRepoStatus = ( id : string , status : Repo [ 'status' ] , commitsBehind ?: number ) => {
10751 setRepos ( prev => prev . map ( r => r . id === id ? {
10852 ...r ,
@@ -161,30 +105,17 @@ const App = () => {
161105 } ;
162106
163107 const handleAddRepo = async ( ) => {
164- // If not in Electron, use fake logic
165108 if ( ! window . electronAPI ) {
166- const name = `new-project-${ Math . floor ( Math . random ( ) * 1000 ) } ` ;
167- const newRepo : Repo = {
168- id : Date . now ( ) . toString ( ) ,
169- path : `C:\\Projects\\${ name } ` ,
170- name : name ,
171- autoPull : true ,
172- status : 'checking' ,
173- lastCheck : 'Now'
174- } ;
175- setRepos ( [ ...repos , newRepo ] ) ;
176- addLog ( `Added new repository: ${ name } ` , 'info' ) ;
109+ addLog ( 'Cannot add repository outside of Electron environment.' , 'error' ) ;
177110 return ;
178111 }
179112
180- // Native Dialog Flow
181113 try {
182114 const result = await window . electronAPI . selectFolder ( ) ;
183- if ( ! result ) return ; // Cancelled
115+ if ( ! result ) return ;
184116
185117 if ( ! result . isRepo ) {
186118 addLog ( `Error: Folder '${ result . name } ' is not a valid Git repository` , 'error' ) ;
187- // You might want to show a toast or alert here
188119 return ;
189120 }
190121
@@ -201,34 +132,31 @@ const App = () => {
201132 setRepos ( prev => [ ...prev , newRepo ] ) ;
202133 addLog ( `Repository added: ${ result . name } ` , 'success' ) ;
203134
204- // Stop simulation to avoid confusion
205- setIsSimulating ( false ) ;
206135 } catch ( e ) {
207136 console . error ( e ) ;
208137 addLog ( 'Failed to add repository' , 'error' ) ;
209138 }
210139 } ;
211140
212141 return (
213- < div className = "app-container " >
142+ < div className = "flex flex-col h-screen bg-background text-foreground " >
214143 { /* Custom Title Bar */ }
215- < div className = "title-bar " >
216- < div className = "title- drag-region" >
217- < div className = "app-icon" > 🔄 </ div >
218- < span className = "app-title " > Git Watcher Pro</ span >
144+ < div className = "flex items-center justify-between h-10 border-b border-border flex-shrink-0 " >
145+ < div className = "flex items-center px-3 gap-2 drag-region h-full flex-grow " >
146+ < svg xmlns = "http://www.w3.org/2000/svg" width = "24" height = "24" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" strokeWidth = "2" strokeLinecap = "round" strokeLinejoin = "round" className = "w-5 h-5" > < path d = "M21 12a9 9 0 1 1-6.219-8.56" /> </ svg >
147+ < span className = "font-semibold text-sm " > Git Watcher Pro</ span >
219148 </ div >
220- < div className = "window-controls " >
221- < div className = "control minimize " onClick = { ( ) => window . electronAPI ?. minimize ( ) } > ─</ div >
222- < div className = "control maximize " onClick = { ( ) => window . electronAPI ?. maximize ( ) } > □</ div >
223- < div className = "control close " onClick = { ( ) => window . electronAPI ?. close ( ) } > ✕</ div >
149+ < div className = "flex items-center h-full no-drag-region " >
150+ < div className = "w-12 h-full flex items-center justify-center text-lg hover:bg-accent transition-colors " onClick = { ( ) => window . electronAPI ?. minimize ( ) } > ─</ div >
151+ < div className = "w-12 h-full flex items-center justify-center text-lg hover:bg-accent transition-colors " onClick = { ( ) => window . electronAPI ?. maximize ( ) } > □</ div >
152+ < div className = "w-12 h-full flex items-center justify-center text-lg hover:bg-destructive transition-colors " onClick = { ( ) => window . electronAPI ?. close ( ) } > ✕</ div >
224153 </ div >
225154 </ div >
226155
227- < div className = "main-layout " >
156+ < div className = "flex flex-grow overflow-hidden " >
228157 < Sidebar activeTab = { activeTab } setActiveTab = { setActiveTab } />
229-
230- < div className = "content-area" >
231- { activeTab === 'dashboard' && (
158+ < main className = "flex-grow p-6 overflow-auto" >
159+ { activeTab === 'dashboard' && (
232160 < Dashboard
233161 repos = { repos }
234162 logs = { logs }
@@ -241,9 +169,10 @@ const App = () => {
241169 onAddRepo = { handleAddRepo }
242170 />
243171 ) }
244- { activeTab === 'settings' && < Settings /> }
245- </ div >
172+ { activeTab === 'settings' && < Settings /> }
173+ </ main >
246174 </ div >
175+
247176 < Footer />
248177 </ div >
249178 ) ;
0 commit comments