feat(core): initialize project skeleton with Electron + React + TypeScript
Set up the complete project foundation for ClawX, a graphical AI assistant: - Electron main process with IPC handlers, menu, tray, and gateway management - React renderer with routing, layout components, and page scaffolding - Zustand state management for gateway, settings, channels, skills, chat, and cron - shadcn/ui components with Tailwind CSS and CSS variable theming - Build tooling with Vite, electron-builder, and TypeScript configuration - Testing setup with Vitest and Playwright - Development configurations (ESLint, Prettier, gitignore, env example)
This commit is contained in:
86
src/App.tsx
Normal file
86
src/App.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Root Application Component
|
||||
* Handles routing and global providers
|
||||
*/
|
||||
import { Routes, Route, useNavigate } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import { Toaster } from 'sonner';
|
||||
import { MainLayout } from './components/layout/MainLayout';
|
||||
import { Dashboard } from './pages/Dashboard';
|
||||
import { Chat } from './pages/Chat';
|
||||
import { Channels } from './pages/Channels';
|
||||
import { Skills } from './pages/Skills';
|
||||
import { Cron } from './pages/Cron';
|
||||
import { Settings } from './pages/Settings';
|
||||
import { Setup } from './pages/Setup';
|
||||
import { useSettingsStore } from './stores/settings';
|
||||
import { useGatewayStore } from './stores/gateway';
|
||||
|
||||
function App() {
|
||||
const navigate = useNavigate();
|
||||
const theme = useSettingsStore((state) => state.theme);
|
||||
const initGateway = useGatewayStore((state) => state.init);
|
||||
|
||||
// Initialize Gateway connection on mount
|
||||
useEffect(() => {
|
||||
initGateway();
|
||||
}, [initGateway]);
|
||||
|
||||
// Listen for navigation events from main process
|
||||
useEffect(() => {
|
||||
const handleNavigate = (path: string) => {
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
const unsubscribe = window.electron.ipcRenderer.on('navigate', handleNavigate);
|
||||
|
||||
return () => {
|
||||
if (typeof unsubscribe === 'function') {
|
||||
unsubscribe();
|
||||
}
|
||||
};
|
||||
}, [navigate]);
|
||||
|
||||
// Apply theme
|
||||
useEffect(() => {
|
||||
const root = window.document.documentElement;
|
||||
root.classList.remove('light', 'dark');
|
||||
|
||||
if (theme === 'system') {
|
||||
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? 'dark'
|
||||
: 'light';
|
||||
root.classList.add(systemTheme);
|
||||
} else {
|
||||
root.classList.add(theme);
|
||||
}
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Routes>
|
||||
{/* Setup wizard (shown on first launch) */}
|
||||
<Route path="/setup/*" element={<Setup />} />
|
||||
|
||||
{/* Main application routes */}
|
||||
<Route element={<MainLayout />}>
|
||||
<Route path="/" element={<Dashboard />} />
|
||||
<Route path="/chat" element={<Chat />} />
|
||||
<Route path="/channels" element={<Channels />} />
|
||||
<Route path="/skills" element={<Skills />} />
|
||||
<Route path="/cron" element={<Cron />} />
|
||||
<Route path="/settings/*" element={<Settings />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
|
||||
{/* Global toast notifications */}
|
||||
<Toaster
|
||||
position="bottom-right"
|
||||
richColors
|
||||
closeButton
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user