diff --git a/.env b/.env index 87e0f0b..8fec16c 100644 --- a/.env +++ b/.env @@ -2,7 +2,7 @@ VITE_SUPABASE_URL=https://nvatjthzedykhikmttot.supabase.co VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im52YXRqdGh6ZWR5a2hpa210dG90Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzM1OTYxOTMsImV4cCI6MjA0OTE3MjE5M30.u4euR8U-XxxvOdLFmWJD2yrd4E_MPMt_X1yqRrDTF2I # N8N Configuration -VITE_N8N_WEBHOOK_URL=https://harivansh.app.n8n.cloud/webhook/chat-webhook +VITE_N8N_WEBHOOK_URL=https://harivansh.app.n8n.cloud/webhook/chat-webhoo VITE_N8N_UPLOAD_WEBHOOK_URL=https://harivansh.app.n8n.cloud/webhook/upload-webhook # Google Drive Configuration diff --git a/src/App.tsx b/src/App.tsx index 9058e19..9fdf812 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,17 +2,20 @@ import React from 'react'; import { BrowserRouter } from 'react-router-dom'; import { AppRouter } from './routes'; import { AuthProvider } from './contexts/AuthContext'; +import { ThemeProvider } from './contexts/ThemeContext'; import './index.css'; const App: React.FC = () => { return ( - - -
- -
-
-
+ + + +
+ +
+
+
+
); }; diff --git a/src/components/layout/DashboardLayout/index.tsx b/src/components/layout/DashboardLayout/index.tsx index 7650ece..5086407 100644 --- a/src/components/layout/DashboardLayout/index.tsx +++ b/src/components/layout/DashboardLayout/index.tsx @@ -9,8 +9,8 @@ const DashboardLayout = () => {
-
-
+
+
diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx new file mode 100644 index 0000000..612edb9 --- /dev/null +++ b/src/contexts/ThemeContext.tsx @@ -0,0 +1,72 @@ +import React, { createContext, useContext, useEffect, useState } from 'react'; + +interface ThemeContextType { + isDarkMode: boolean; + toggleDarkMode: () => void; +} + +const ThemeContext = createContext(undefined); + +function setThemeClass(isDark: boolean) { + if (isDark) { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } +} + +export function ThemeProvider({ children }: { children: React.ReactNode }) { + const [isDarkMode, setIsDarkMode] = useState(() => { + if (typeof window === 'undefined') return false; + + // Check localStorage first + const stored = localStorage.getItem('darkMode'); + if (stored !== null) { + const isDark = stored === 'true'; + setThemeClass(isDark); + return isDark; + } + + // Then check system preference + const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + setThemeClass(systemPrefersDark); + return systemPrefersDark; + }); + + // Update theme when isDarkMode changes + useEffect(() => { + setThemeClass(isDarkMode); + localStorage.setItem('darkMode', String(isDarkMode)); + }, [isDarkMode]); + + // Listen for system theme changes + useEffect(() => { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + const handleChange = (e: MediaQueryListEvent) => { + if (localStorage.getItem('darkMode') === null) { + setIsDarkMode(e.matches); + } + }; + + mediaQuery.addEventListener('change', handleChange); + return () => mediaQuery.removeEventListener('change', handleChange); + }, []); + + const toggleDarkMode = () => { + setIsDarkMode(prev => !prev); + }; + + return ( + + {children} + + ); +} + +export function useTheme() { + const context = useContext(ThemeContext); + if (context === undefined) { + throw new Error('useTheme must be used within a ThemeProvider'); + } + return context; +} diff --git a/src/pages/dashboard/Settings.tsx b/src/pages/dashboard/Settings.tsx index 58b3a98..52c679b 100644 --- a/src/pages/dashboard/Settings.tsx +++ b/src/pages/dashboard/Settings.tsx @@ -1,10 +1,10 @@ import React, { useState } from 'react'; -import { Button } from '../../components/ui/Button'; import { Card } from '../../components/ui/card'; import { Label } from '../../components/ui/label'; import { Switch } from '../../components/ui/switch'; import { Slider } from '../../components/ui/slider'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../components/ui/tabs'; +import { useTheme } from '../../contexts/ThemeContext'; function Settings() { // Chat & RAG Settings @@ -14,8 +14,7 @@ function Settings() { const [relevanceThreshold, setRelevanceThreshold] = useState(0.8); // UI Settings - const [darkMode, setDarkMode] = useState(false); - const [compactView, setCompactView] = useState(false); + const { isDarkMode, toggleDarkMode } = useTheme(); const [messageGrouping, setMessageGrouping] = useState(true); // Privacy Settings @@ -32,7 +31,7 @@ function Settings() {

Settings

- + Enable dark color theme

-
- -
-
- -

Reduce spacing in chat interface

-
-
@@ -187,11 +174,6 @@ function Settings() { - -
- - -
); } diff --git a/src/pages/dashboard/ask.tsx b/src/pages/dashboard/ask.tsx index bffbc71..c9151b3 100644 --- a/src/pages/dashboard/ask.tsx +++ b/src/pages/dashboard/ask.tsx @@ -108,8 +108,8 @@ export default function AskQuestion() { try { let currentChatId: string; - // If this is a new chat, create it first with the title from the first message - if (isNewChat) { + // If no chat exists or we're on the base ask page, create a new one + if (!chatId || chatId === undefined) { const title = generateChatTitle(question.trim()); const newChat = await chatService.createChatInstance(user.id, title); if (!newChat) { @@ -120,8 +120,6 @@ export default function AskQuestion() { setIsNewChat(false); // Update URL with the real chat ID navigate(`/dashboard/ask/${newChat.id}`, { replace: true }); - } else if (!chatId) { - throw new Error('No chat ID available'); } else { currentChatId = chatId; } @@ -182,75 +180,73 @@ export default function AskQuestion() { } return ( -
- {/* Main Chat Container */} -
- {/* Sticky Subheader */} -
-
-
-
- -
-
-

Ask a Question

- {chat && ( -

- {chat.title} -

- )} -
+
+ {/* Header Container */} +
+
+
+
+
-
+
+

Ask a Question

+ {chat && ( +

+ {chat.title} +

+ )} +
+
+
+ + {chatId && !isNewChat && messages.length > 0 && ( - {chatId && !isNewChat && messages.length > 0 && ( + )} + {hasExistingChats && ( + - )} - {hasExistingChats && ( - - - - )} -
+ + )}
+
- {/* Error Message */} - {error && ( -
- - {error} -
- )} - + {/* Main Chat Container - Added pb-20 to create space at bottom */} +
{/* Messages Container */}
+ {error && ( +
+ + {error} +
+ )}
{!isNewChat && !chatId ? ( -
+
@@ -371,43 +367,43 @@ export default function AskQuestion() { )}
+
- {/* Input Box - Fixed at Bottom */} -
-
-
- setQuestion(e.target.value)} - placeholder="Ask me anything..." - className={cn( - 'flex-1 rounded-full px-4 py-2 text-sm', - 'bg-primary/5 border-primary/10', - 'focus:outline-none focus:ring-2 focus:ring-primary/20', - 'placeholder:text-muted-foreground' - )} - disabled={loading} - /> - -
-
-
+ {/* Input Box - Keep original styling */} +
+
+
+ setQuestion(e.target.value)} + placeholder="Ask me anything..." + className={cn( + 'flex-1 rounded-full px-4 py-2 text-sm', + 'bg-primary/5 border-primary/10', + 'focus:outline-none focus:ring-2 focus:ring-primary/20', + 'placeholder:text-muted-foreground' + )} + disabled={loading} + /> + +
+
); diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..cdee3d3 --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,20 @@ +/// +/// +/// +/// + +declare module '../../components/ui/label' { + export { Label } from '@radix-ui/react-label' +} + +declare module '../../components/ui/switch' { + export { Switch } from '@radix-ui/react-switch' +} + +declare module '../../components/ui/slider' { + export { Slider } from '@radix-ui/react-slider' +} + +declare module '../../components/ui/tabs' { + export { Tabs, TabsContent, TabsList, TabsTrigger } from '@radix-ui/react-tabs' +}