theo-agent-dashboard

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

App.tsx (3266B)


      1 import { useEffect, useCallback, useState } from "react";
      2 import { useAuthStore } from "./store/auth";
      3 import { useThemeStore } from "./store/theme";
      4 import { Login } from "./components/Login/Login";
      5 import { Setup } from "./components/Setup/Setup";
      6 import { ChatView } from "./components/Chat/ChatView";
      7 import { Sidebar } from "./components/Sidebar/Sidebar";
      8 import { SearchModal } from "./components/Search/SearchModal";
      9 import { ThemeToggle } from "./components/Theme/ThemeToggle";
     10 
     11 export function App() {
     12   const { authenticated, configured, loading, checkStatus } = useAuthStore();
     13   const { theme } = useThemeStore();
     14   const [searchOpen, setSearchOpen] = useState(false);
     15   const [sidebarOpen, setSidebarOpen] = useState(false);
     16 
     17   useEffect(() => {
     18     checkStatus();
     19   }, [checkStatus]);
     20 
     21   const toggleSearch = useCallback(() => {
     22     setSearchOpen((prev) => !prev);
     23   }, []);
     24 
     25   const closeSearch = useCallback(() => {
     26     setSearchOpen(false);
     27   }, []);
     28 
     29   const toggleSidebar = useCallback(() => {
     30     setSidebarOpen((prev) => !prev);
     31   }, []);
     32 
     33   const closeSidebar = useCallback(() => {
     34     setSidebarOpen(false);
     35   }, []);
     36 
     37   const handleSelectSession = useCallback((_sessionId: string) => {
     38     setSidebarOpen(false);
     39   }, []);
     40 
     41   useEffect(() => {
     42     const handleKeyDown = (e: KeyboardEvent) => {
     43       if ((e.ctrlKey || e.metaKey) && e.key === "k") {
     44         e.preventDefault();
     45         toggleSearch();
     46       }
     47     };
     48     document.addEventListener("keydown", handleKeyDown);
     49     return () => document.removeEventListener("keydown", handleKeyDown);
     50   }, [toggleSearch]);
     51 
     52   const bgClass = theme === "dark" ? "bg-gray-950" : "bg-gray-100";
     53   const textClass = theme === "dark" ? "text-gray-100" : "text-gray-900";
     54 
     55   if (loading) {
     56     return (
     57       <div className={`flex h-screen items-center justify-center ${bgClass} ${textClass}`}>
     58         Loading...
     59       </div>
     60     );
     61   }
     62 
     63   if (!configured) {
     64     return <Setup />;
     65   }
     66 
     67   if (!authenticated) {
     68     return <Login />;
     69   }
     70 
     71   return (
     72     <div className={`flex h-screen overflow-hidden ${bgClass} ${textClass}`}>
     73       {/* Mobile hamburger */}
     74       <button
     75         type="button"
     76         onClick={toggleSidebar}
     77         className="fixed left-4 top-4 z-30 rounded-lg bg-gray-800 p-2 text-gray-300 hover:bg-gray-700 md:hidden"
     78         aria-label="Toggle sidebar"
     79       >
     80     81       </button>
     82 
     83       {/* Sidebar */}
     84       <div
     85         className={`fixed inset-y-0 left-0 z-20 w-64 transition-transform duration-200 md:translate-x-0 ${
     86           sidebarOpen ? "translate-x-0" : "-translate-x-full"
     87         }`}
     88       >
     89         <Sidebar onSelectSession={handleSelectSession} />
     90       </div>
     91 
     92       {/* Mobile overlay */}
     93       {sidebarOpen && (
     94         <div
     95           className="fixed inset-0 z-10 bg-black/50 md:hidden"
     96           onClick={closeSidebar}
     97           aria-hidden="true"
     98         />
     99       )}
    100 
    101       {/* Main content */}
    102       <main className="flex min-w-0 min-h-0 flex-1 flex-col md:ml-64">
    103         <div className="flex items-center justify-end p-2">
    104           <ThemeToggle />
    105         </div>
    106         <ChatView />
    107       </main>
    108 
    109       <SearchModal
    110         isOpen={searchOpen}
    111         onClose={closeSearch}
    112         onSelectSession={handleSelectSession}
    113       />
    114     </div>
    115   );
    116 }