UI updates

This commit is contained in:
Harivansh Rathi 2024-12-08 15:53:58 -05:00
parent 171fe6e04f
commit 7dda2e20d0
7 changed files with 195 additions and 122 deletions

2
.env
View file

@ -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

View file

@ -2,10 +2,12 @@ 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 (
<ThemeProvider>
<AuthProvider>
<BrowserRouter>
<div className="min-h-screen bg-background text-foreground">
@ -13,6 +15,7 @@ const App: React.FC = () => {
</div>
</BrowserRouter>
</AuthProvider>
</ThemeProvider>
);
};

View file

@ -9,8 +9,8 @@ const DashboardLayout = () => {
<Header />
<div className="flex flex-1 overflow-hidden gap-6 p-6 pt-24">
<Sidebar />
<main className="flex-1 overflow-y-auto rounded-2xl bg-background shadow-sm border">
<div className="p-6">
<main className="flex-1 rounded-2xl bg-background shadow-sm border overflow-hidden">
<div className="h-full">
<Outlet />
</div>
</main>

View file

@ -0,0 +1,72 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
interface ThemeContextType {
isDarkMode: boolean;
toggleDarkMode: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(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 (
<ThemeContext.Provider value={{ isDarkMode, toggleDarkMode }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}

View file

@ -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() {
<h1 className="text-3xl font-bold">Settings</h1>
<Tabs defaultValue="chat" className="w-full">
<TabsList className="mb-4 bg-purple-50">
<TabsList className="mb-4 bg-muted">
<TabsTrigger
value="chat"
className="data-[state=active]:bg-gradient-to-r data-[state=active]:from-purple-400 data-[state=active]:to-purple-500 data-[state=active]:text-white"
@ -115,20 +114,8 @@ function Settings() {
<p className="text-sm text-muted-foreground">Enable dark color theme</p>
</div>
<Switch
checked={darkMode}
onCheckedChange={setDarkMode}
className="data-[state=checked]:bg-gradient-to-r data-[state=checked]:from-purple-400 data-[state=checked]:to-purple-500"
/>
</div>
<div className="flex items-center justify-between">
<div>
<Label>Compact View</Label>
<p className="text-sm text-muted-foreground">Reduce spacing in chat interface</p>
</div>
<Switch
checked={compactView}
onCheckedChange={setCompactView}
checked={isDarkMode}
onCheckedChange={toggleDarkMode}
className="data-[state=checked]:bg-gradient-to-r data-[state=checked]:from-purple-400 data-[state=checked]:to-purple-500"
/>
</div>
@ -187,11 +174,6 @@ function Settings() {
</Card>
</TabsContent>
</Tabs>
<div className="flex justify-end space-x-4">
<Button variant="outline" className="hover:bg-purple-50">Reset to Defaults</Button>
<Button className="bg-gradient-to-r from-purple-400 to-purple-500 hover:from-purple-500 hover:to-purple-600 text-white">Save Changes</Button>
</div>
</div>
);
}

View file

@ -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,12 +180,10 @@ export default function AskQuestion() {
}
return (
<div className="h-[calc(100vh-4rem)] flex flex-col">
{/* Main Chat Container */}
<div className="flex-1 flex flex-col relative">
{/* Sticky Subheader */}
<div className="sticky top-0 z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b">
<div className="flex h-14 items-center justify-between px-4">
<div className="flex flex-col h-full">
{/* Header Container */}
<div className="flex-none bg-background rounded-lg m-4">
<div className="flex h-full items-center justify-between px-4">
<div className="flex items-center gap-2">
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10">
<MessageSquarePlus className="h-4 w-4 text-primary" />
@ -238,19 +234,19 @@ export default function AskQuestion() {
</div>
</div>
{/* Error Message */}
{/* Main Chat Container - Added pb-20 to create space at bottom */}
<div className="flex-1 bg-background rounded-lg mx-4 flex flex-col min-h-0 pb-20">
{/* Messages Container */}
<div className="flex-1 overflow-y-auto">
{error && (
<div className="flex-none mx-4 mt-4 flex items-center gap-2 rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
<AlertCircle className="h-4 w-4" />
{error}
</div>
)}
{/* Messages Container */}
<div className="flex-1 overflow-y-auto">
<div className="flex flex-col space-y-6 p-4">
{!isNewChat && !chatId ? (
<div className="h-full flex items-center justify-center min-h-[calc(100vh-12rem)]">
<div className="h-full flex items-center justify-center min-h-[calc(100vh-50rem)]">
<div className="max-w-md w-full space-y-8">
<div className="flex flex-col items-center text-center">
<div className="rounded-full bg-purple-500/20 p-6 mb-8">
@ -371,11 +367,12 @@ export default function AskQuestion() {
)}
</div>
</div>
</div>
{/* Input Box - Fixed at Bottom */}
<div className="sticky bottom-0 left-0 right-0 p-3 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
{/* Input Box - Keep original styling */}
<div className="sticky bottom-0 left-0 right-0 p-4 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<form onSubmit={handleSubmit} className="mx-auto max-w-3xl">
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 h-full">
<input
type="text"
value={question}
@ -409,6 +406,5 @@ export default function AskQuestion() {
</form>
</div>
</div>
</div>
);
}

20
src/types.d.ts vendored Normal file
View file

@ -0,0 +1,20 @@
/// <reference types="@radix-ui/react-label" />
/// <reference types="@radix-ui/react-switch" />
/// <reference types="@radix-ui/react-slider" />
/// <reference types="@radix-ui/react-tabs" />
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'
}