mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-02 21:19:12 +00:00
Merge branch 'features/fit-and-finish-new-ux' of github.com:khoj-ai/khoj into features/fit-and-finish-new-ux
This commit is contained in:
@@ -447,7 +447,7 @@ function SharedAutomationCard(props: SharedAutomationCardProps) {
|
||||
<DialogTrigger>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogTitle>
|
||||
<DialogTitle className='py-0'>
|
||||
<Plus className='h-4 w-4 mr-2' />
|
||||
Create Automation
|
||||
</DialogTitle>
|
||||
@@ -946,8 +946,8 @@ export default function Automations() {
|
||||
</div>
|
||||
<div className={`${styles.pageLayout} w-full`}>
|
||||
<div className='py-4 sm:flex sm:justify-between grid gap-1'>
|
||||
<h1 className="text-3xl pt-4">Automations</h1>
|
||||
<div className='flex flex-wrap gap-2 items-center md:justify-start justify-end'>
|
||||
<h1 className="text-3xl">Automations</h1>
|
||||
<div className='flex flex-wrap gap-2 items-center justify-start'>
|
||||
{
|
||||
authenticatedData ? (
|
||||
<span className='rounded-lg text-sm border-secondary border p-1 flex items-center shadow-sm' ><Envelope className='h-4 w-4 mr-2 inline text-orange-500' shadow-s />{authenticatedData.email}</span>
|
||||
@@ -1035,7 +1035,7 @@ export default function Automations() {
|
||||
</Suspense>
|
||||
{
|
||||
((!personalAutomations || personalAutomations.length === 0) && (allNewAutomations.length == 0) && !isLoading) && (
|
||||
<div>
|
||||
<div className="px-4">
|
||||
So empty! Create your own automation to get started.
|
||||
<div className='mt-4'>
|
||||
{
|
||||
|
||||
@@ -71,9 +71,9 @@ export interface UserConfig {
|
||||
|
||||
export function useUserConfig(detailed: boolean = false) {
|
||||
const url = `/api/settings?detailed=${detailed}`;
|
||||
const { data, error } = useSWR<UserConfig>(url, fetcher, { revalidateOnFocus: false });
|
||||
const { data: userConfig, error, isLoading: isLoadingUserConfig } = useSWR<UserConfig>(url, fetcher, { revalidateOnFocus: false });
|
||||
|
||||
if (error || !data || data.detail === 'Forbidden') return null;
|
||||
if (error || !userConfig || userConfig?.detail === 'Forbidden') return {userConfig: null, isLoadingUserConfig};
|
||||
|
||||
return data;
|
||||
return {userConfig, isLoadingUserConfig};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export function KhojLogoType() {
|
||||
return (
|
||||
<svg width="52" height="auto" viewBox="0 0 442 198" className="fill-zinc-950 dark:fill-zinc-300" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="64" height="auto" viewBox="0 0 442 198" className="fill-zinc-950 dark:fill-zinc-300" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_45_75)">
|
||||
<path d="M57.9394 93.0404L67.5396 49.1063C68.7987 49.5268 71.7365 51.9442 74.7267 51.9442C78.5039 51.9442 79.2383 47.4246 86.1631 45.7955C91.6715 44.4817 96.3404 45.4276 99.0684 47.6349C99.0684 47.6349 99.6979 53.6259 101.167 55.4127C102.531 57.0418 104.629 56.4637 104.629 56.4637C107.672 70.8106 114.072 100.661 115.279 105.233C116.8 110.961 110.924 114.114 108.669 119.369C106.413 124.625 94.242 126.884 87.0549 127.62C79.8679 128.356 59.723 119.632 57.9394 117.215C56.1557 114.797 55.3688 109.857 55.1065 105.18C54.8442 101.449 56.8902 95.5104 57.9394 93.0404Z" fill="#FAE80B" />
|
||||
<path d="M57.9394 92.9879L62.2936 74.8046C63.5526 75.2251 66.9626 73.4383 71.4742 69.0764C74.1497 66.4488 79.8678 58.8812 86.0582 55.3601C90.5698 52.785 94.924 54.204 97.5995 56.4112C97.5995 56.4112 100.013 57.6199 102.846 57.6199C104.944 57.6199 104.629 56.4112 104.629 56.4112C107.672 70.7581 114.072 100.608 115.279 105.18C116.8 110.908 110.924 114.062 108.669 119.317C106.413 124.572 94.242 126.832 87.0549 127.568C79.8679 128.303 59.723 119.58 57.9394 117.162C56.1557 114.745 55.3688 109.805 55.1065 105.128C54.8442 101.449 56.8902 95.5104 57.9394 92.9879Z" fill="#FFCC09" />
|
||||
|
||||
@@ -81,30 +81,26 @@ export default function NavMenu() {
|
||||
<DropdownMenuTrigger>
|
||||
{
|
||||
userData ?
|
||||
<Avatar className="h-8 w-8">
|
||||
<Avatar className={`h-8 w-8 border-2 ${userData.is_active ? "border-yellow-500" : "border-stone-700 dark:border-stone-300"}`}>
|
||||
<AvatarImage src={userData?.photo} alt="user profile" />
|
||||
<AvatarFallback>
|
||||
{userData?.username[0]}
|
||||
<AvatarFallback className="bg-transparent hover:bg-muted">
|
||||
{userData?.username[0].toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
:
|
||||
<UserCircle className="w-6 h-6" />
|
||||
<UserCircle className="h-6 w-6" />
|
||||
}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className='gap-2'>
|
||||
<DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => setDarkMode(!darkMode)} className='w-full cursor-pointer'>
|
||||
<div
|
||||
onClick={() => {
|
||||
setDarkMode(!darkMode)
|
||||
}
|
||||
}
|
||||
className="flex flex-rows">
|
||||
{darkMode ? <Sun className="w-6 h-6" /> : <Moon className="w-6 h-6" />}
|
||||
<p className="ml-3 font-semibold">{darkMode ? 'Light Mode' : 'Dark Mode'}</p>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link href="/agents" className="no-underline">
|
||||
<Link href="/agents" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<User className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Agents</p>
|
||||
@@ -112,7 +108,7 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link href="/automations" className="no-underline">
|
||||
<Link href="/automations" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<Robot className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Automations</p>
|
||||
@@ -120,7 +116,7 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link href="/search" className="no-underline">
|
||||
<Link href="/search" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<MagnifyingGlass className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Search</p>
|
||||
@@ -131,7 +127,7 @@ export default function NavMenu() {
|
||||
<DropdownMenuSeparator />
|
||||
{userData &&
|
||||
<DropdownMenuItem>
|
||||
<Link href="/settings" className="no-underline">
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
@@ -140,7 +136,7 @@ export default function NavMenu() {
|
||||
</DropdownMenuItem>
|
||||
}
|
||||
<DropdownMenuItem>
|
||||
<Link href="https://docs.khoj.dev" className="no-underline">
|
||||
<Link href="https://docs.khoj.dev" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<Question className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Help</p>
|
||||
@@ -150,7 +146,7 @@ export default function NavMenu() {
|
||||
{
|
||||
userData ?
|
||||
<DropdownMenuItem>
|
||||
<Link href="/auth/logout" className="no-underline">
|
||||
<Link href="/auth/logout" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<ArrowRight className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Logout</p>
|
||||
@@ -159,7 +155,7 @@ export default function NavMenu() {
|
||||
</DropdownMenuItem>
|
||||
:
|
||||
<DropdownMenuItem>
|
||||
<Link href="/auth/login" className="no-underline">
|
||||
<Link href="/auth/login" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<ArrowRight className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Login</p>
|
||||
@@ -171,15 +167,15 @@ export default function NavMenu() {
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
:
|
||||
<Menubar className='border-none hover:bg-stone-100 dark:hover:bg-neutral-900 bg-none'>
|
||||
<Menubar className='border-none'>
|
||||
<MenubarMenu>
|
||||
<MenubarTrigger>
|
||||
{
|
||||
userData ?
|
||||
<Avatar className="h-8 w-8">
|
||||
<Avatar className={`h-8 w-8 border-2 ${userData.is_active ? "border-yellow-500" : "border-stone-700 dark:border-stone-300"}`}>
|
||||
<AvatarImage src={userData?.photo} alt="user profile" />
|
||||
<AvatarFallback>
|
||||
{userData?.username[0]}
|
||||
<AvatarFallback className="bg-transparent hover:bg-muted">
|
||||
{userData?.username[0].toUpperCase()}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
:
|
||||
@@ -187,19 +183,15 @@ export default function NavMenu() {
|
||||
}
|
||||
</MenubarTrigger>
|
||||
<MenubarContent align="end" className="rounded-xl gap-2">
|
||||
<MenubarItem>
|
||||
<MenubarItem onClick={() => setDarkMode(!darkMode)} className="w-full hover:cursor-pointer">
|
||||
<div
|
||||
onClick={() => {
|
||||
setDarkMode(!darkMode)
|
||||
}
|
||||
}
|
||||
className="flex flex-rows">
|
||||
{darkMode ? <Sun className="w-6 h-6" /> : <Moon className="w-6 h-6" />}
|
||||
<p className="ml-3 font-semibold">{darkMode ? 'Light Mode' : 'Dark Mode'}</p>
|
||||
</div>
|
||||
</MenubarItem>
|
||||
<MenubarItem>
|
||||
<Link href="/agents" className="no-underline">
|
||||
<Link href="/agents" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<User className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Agents</p>
|
||||
@@ -207,7 +199,7 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
<MenubarItem>
|
||||
<Link href="/automations" className="no-underline">
|
||||
<Link href="/automations" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<Robot className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Automations</p>
|
||||
@@ -215,7 +207,7 @@ export default function NavMenu() {
|
||||
</Link>
|
||||
</MenubarItem>
|
||||
<MenubarItem>
|
||||
<Link href="/search" className="no-underline">
|
||||
<Link href="/search" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<MagnifyingGlass className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Search</p>
|
||||
@@ -225,7 +217,7 @@ export default function NavMenu() {
|
||||
<>
|
||||
<MenubarSeparator className="dark:bg-white height-[2px] bg-black" />
|
||||
<MenubarItem>
|
||||
<Link href="https://docs.khoj.dev" className="no-underline">
|
||||
<Link href="https://docs.khoj.dev" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<Question className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Help</p>
|
||||
@@ -235,7 +227,7 @@ export default function NavMenu() {
|
||||
{
|
||||
userData &&
|
||||
<MenubarItem>
|
||||
<Link href="/settings" className="no-underline">
|
||||
<Link href="/settings" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<GearFine className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Settings</p>
|
||||
@@ -246,7 +238,7 @@ export default function NavMenu() {
|
||||
{
|
||||
userData ?
|
||||
<MenubarItem>
|
||||
<Link href="/auth/logout" className="no-underline">
|
||||
<Link href="/auth/logout" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<ArrowRight className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Logout</p>
|
||||
@@ -255,7 +247,7 @@ export default function NavMenu() {
|
||||
</MenubarItem>
|
||||
:
|
||||
<MenubarItem>
|
||||
<Link href="/auth/login" className="no-underline">
|
||||
<Link href="/auth/login" className="no-underline w-full">
|
||||
<div className="flex flex-rows">
|
||||
<ArrowRight className="w-6 h-6" />
|
||||
<p className="ml-3 font-semibold">Login</p>
|
||||
|
||||
@@ -696,19 +696,19 @@ export default function SidePanel(props: SidePanelProps) {
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
:
|
||||
<div className={`flex justify-between flex-row ${enabled ? 'w-full' : 'w-fit'}`}>
|
||||
<div className={`grid grid-flow-col gap-4 w-fit`}>
|
||||
<Link href='/' className="content-center">
|
||||
<KhojLogoType />
|
||||
</Link>
|
||||
<div className={`${enabled ? 'flex items-center flex-row gap-2' : 'flex items-center'}`}>
|
||||
<Link className={`ml-4 mr-4`} href="/">
|
||||
<div className='grid grid-flow-col gap-2 items-center'>
|
||||
<Link className='mx-4' href="/">
|
||||
{enabled ? <NotePencil className="h-6 w-6" /> : <NotePencil className="h-6 w-6" color="gray" />}
|
||||
</Link>
|
||||
<button className={styles.button} onClick={() => setEnabled(!enabled)}>
|
||||
{enabled ? <Sidebar className="h-6 w-6" /> : <Sidebar className="h-6 w-6" color="gray" />}
|
||||
</button>
|
||||
</div>
|
||||
<div className="fixed right-0 w-fit h-fit">
|
||||
<div className="fixed right-0 top-[0.9rem] w-fit h-fit">
|
||||
<NavMenu />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -143,7 +143,8 @@ div.modalSessionsList div.session {
|
||||
|
||||
div.session.compressed {
|
||||
max-width: 100%;
|
||||
grid-template-columns: minmax(auto, 300px) 1fr;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
div.session {
|
||||
|
||||
@@ -38,7 +38,7 @@ interface SuggestionCardProps {
|
||||
|
||||
export default function SuggestionCard(data: SuggestionCardProps) {
|
||||
const bgColors = converColorToBgGradient(data.color);
|
||||
const cardClassName = `${styles.card} ${bgColors} md:w-full md:h-fit sm:w-full sm:h-fit lg:w-[200px] lg:h-[200px]`;
|
||||
const cardClassName = `${styles.card} ${bgColors} md:w-full md:h-fit sm:w-full sm:h-fit lg:w-[200px] lg:h-[200px] cursor-pointer`;
|
||||
const titleClassName = `${styles.title} pt-2 dark:text-white dark:font-bold`;
|
||||
const descriptionClassName = `${styles.text} dark:text-white`;
|
||||
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
'use client'
|
||||
import './globals.css';
|
||||
|
||||
import styles from './page.module.css';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import SuggestionCard from './components/suggestions/suggestionCard';
|
||||
import SidePanel from './components/sidePanel/chatHistorySidePanel';
|
||||
import Loading from './components/loading/loading';
|
||||
import useSWR from 'swr';
|
||||
import Image from 'next/image';
|
||||
|
||||
import 'katex/dist/katex.min.css';
|
||||
|
||||
import ChatInputArea, { ChatOptions } from './components/chatInputArea/chatInputArea';
|
||||
import { useAuthenticatedData } from './common/auth';
|
||||
import { Card, CardTitle } from '@/components/ui/card';
|
||||
import { convertColorToBorderClass } from './common/colorUtils';
|
||||
import { getIconFromIconName } from './common/iconUtils';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import Image from 'next/image';
|
||||
import { ClockCounterClockwise } from '@phosphor-icons/react';
|
||||
import { AgentData } from './agents/page';
|
||||
|
||||
import { Suggestion, suggestionsData } from './components/suggestions/suggestionsData';
|
||||
import LoginPrompt from './components/loginPrompt/loginPrompt';
|
||||
import { Card, CardTitle } from '@/components/ui/card';
|
||||
import SuggestionCard from '@/app/components/suggestions/suggestionCard';
|
||||
import SidePanel from '@/app/components/sidePanel/chatHistorySidePanel';
|
||||
import Loading from '@/app/components/loading/loading';
|
||||
import ChatInputArea, { ChatOptions } from '@/app/components/chatInputArea/chatInputArea';
|
||||
import { Suggestion, suggestionsData } from '@/app/components/suggestions/suggestionsData';
|
||||
import LoginPrompt from '@/app/components/loginPrompt/loginPrompt';
|
||||
|
||||
//get today's day
|
||||
const today = new Date();
|
||||
const day = today.getDay();
|
||||
const greetings = [
|
||||
`Good ${today.getHours() < 12 ? 'morning' : today.getHours() < 15 ? 'afternoon' : 'evening'}! What would you like to do today?`,
|
||||
'How can I help you today?',
|
||||
`Good ${today.getHours() < 12 ? 'morning' : today.getHours() < 15 ? 'afternoon' : 'evening'}! What's on your mind?`,
|
||||
`Ready to breeze through your ${['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day]}?`,
|
||||
`Want to navigate your ${['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day]} workload?`
|
||||
];
|
||||
const greeting = greetings[~~(Math.random() * greetings.length)];
|
||||
import { useAuthenticatedData, UserConfig, useUserConfig } from '@/app/common/auth';
|
||||
import { convertColorToBorderClass } from '@/app/common/colorUtils';
|
||||
import { getIconFromIconName } from '@/app/common/iconUtils';
|
||||
import { AgentData } from '@/app/agents/page';
|
||||
|
||||
|
||||
interface ChatBodyDataProps {
|
||||
@@ -42,19 +28,17 @@ interface ChatBodyDataProps {
|
||||
setUploadedFiles: (files: string[]) => void;
|
||||
isMobileWidth?: boolean;
|
||||
isLoggedIn: boolean;
|
||||
userConfig: UserConfig | null;
|
||||
isLoadingUserConfig: boolean;
|
||||
}
|
||||
|
||||
async function createNewConvo(slug: string) {
|
||||
try {
|
||||
const response = await fetch(`/api/chat/sessions?client=web&agent_slug=${slug}`, { method: "POST" });
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
if (!response.ok) throw new Error(`Failed to fetch chat sessions with status: ${response.status}`);
|
||||
const data = await response.json();
|
||||
const conversationID = data.conversation_id;
|
||||
if (!conversationID) {
|
||||
throw new Error("Conversation ID not found in response");
|
||||
}
|
||||
if (!conversationID) throw new Error("Conversation ID not found in response");
|
||||
return conversationID;
|
||||
} catch (error) {
|
||||
console.error("Error creating new conversation:", error);
|
||||
@@ -65,6 +49,7 @@ async function createNewConvo(slug: string) {
|
||||
function ChatBodyData(props: ChatBodyDataProps) {
|
||||
const [message, setMessage] = useState('');
|
||||
const [processingMessage, setProcessingMessage] = useState(false);
|
||||
const [greeting, setGreeting] = useState('');
|
||||
const [shuffledOptions, setShuffledOptions] = useState<Suggestion[]>([]);
|
||||
const [selectedAgent, setSelectedAgent] = useState<string | null>("khoj");
|
||||
const [agentIcons, setAgentIcons] = useState<JSX.Element[]>([]);
|
||||
@@ -79,6 +64,29 @@ function ChatBodyData(props: ChatBodyDataProps) {
|
||||
setShuffledOptions(shuffled.slice(0, 3));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(`Loading user config: ${props.isLoadingUserConfig}`);
|
||||
if (props.isLoadingUserConfig) return;
|
||||
|
||||
// Set user config
|
||||
console.log(`Logged In: ${props.isLoggedIn}\nUserConfig: ${props.userConfig}`);
|
||||
|
||||
// Get today's day
|
||||
const today = new Date();
|
||||
const day = today.getDay();
|
||||
const timeOfDay = today.getHours() > 4 && today.getHours() < 12 ? 'morning' : today.getHours() < 17 ? 'afternoon' : 'evening';
|
||||
const nameSuffix = props.userConfig?.given_name ? `, ${props.userConfig?.given_name}` : "";
|
||||
const greetings = [
|
||||
`What would you like to get done${nameSuffix}?`,
|
||||
`Hey${nameSuffix}! How can I help?`,
|
||||
`Good ${timeOfDay}${nameSuffix}! What's on your mind?`,
|
||||
`Ready to breeze through your ${['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day]}?`,
|
||||
`Want help navigating your ${['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][day]} workload?`
|
||||
];
|
||||
const greeting = greetings[Math.floor(Math.random() * greetings.length)];
|
||||
setGreeting(greeting);
|
||||
}, [props.isLoadingUserConfig, props.userConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.chatOptionsData) {
|
||||
shuffleAndSetOptions();
|
||||
@@ -87,9 +95,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
|
||||
|
||||
useEffect(() => {
|
||||
const nSlice = props.isMobileWidth ? 3 : 4;
|
||||
|
||||
const shuffledAgents = agentsData ? [...agentsData].sort(() => 0.5 - Math.random()) : [];
|
||||
|
||||
const agents = agentsData ? [agentsData[0]] : []; // Always add the first/default agent.
|
||||
|
||||
shuffledAgents.slice(0, nSlice - 1).forEach(agent => {
|
||||
@@ -168,7 +174,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
|
||||
}
|
||||
<div className={`w-full text-center justify-end content-end`}>
|
||||
<div className="items-center">
|
||||
<h1 className="text-center pb-6 px-4 w-fit ml-auto mr-auto">{greeting}</h1>
|
||||
<h1 className="text-center w-fit pb-6 px-4 mx-auto">{greeting}</h1>
|
||||
</div>
|
||||
{
|
||||
!props.isMobileWidth &&
|
||||
@@ -280,12 +286,19 @@ export default function Home() {
|
||||
const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
|
||||
const [isMobileWidth, setIsMobileWidth] = useState(false);
|
||||
|
||||
const {userConfig: initialUserConfig, isLoadingUserConfig} = useUserConfig(true);
|
||||
const [userConfig, setUserConfig] = useState<UserConfig | null>(null);
|
||||
|
||||
const authenticatedData = useAuthenticatedData();
|
||||
|
||||
const handleConversationIdChange = (newConversationId: string) => {
|
||||
setConversationID(newConversationId);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setUserConfig(initialUserConfig);
|
||||
}, [initialUserConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/api/chat/options')
|
||||
.then(response => response.json())
|
||||
@@ -332,6 +345,8 @@ export default function Home() {
|
||||
setUploadedFiles={setUploadedFiles}
|
||||
isMobileWidth={isMobileWidth}
|
||||
onConversationIdChange={handleConversationIdChange}
|
||||
userConfig={userConfig}
|
||||
isLoadingUserConfig={isLoadingUserConfig}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -159,13 +159,7 @@ export default function Search() {
|
||||
}, [isMobileWidth]);
|
||||
|
||||
function search() {
|
||||
if (searchResultsLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!searchQuery.trim()) {
|
||||
return;
|
||||
}
|
||||
if (searchResultsLoading || !searchQuery.trim()) return;
|
||||
|
||||
const apiUrl = `/api/search?q=${encodeURIComponent(searchQuery)}&client=web`;
|
||||
fetch(apiUrl, {
|
||||
@@ -246,7 +240,7 @@ export default function Search() {
|
||||
}
|
||||
{
|
||||
!focusSearchResult && searchResults && searchResults.length > 0 &&
|
||||
<div className='mt-4'>
|
||||
<div className='mt-4 max-w-[92vw] break-all'>
|
||||
<ScrollArea className="h-[80vh]">
|
||||
{
|
||||
searchResults.map((result, index) => {
|
||||
|
||||
@@ -348,7 +348,7 @@ export default function SettingsView() {
|
||||
const [title, setTitle] = useState("Settings");
|
||||
const [isMobileWidth, setIsMobileWidth] = useState(false);
|
||||
const { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey } = useApiKeys();
|
||||
const initialUserConfig = useUserConfig(true);
|
||||
const {userConfig: initialUserConfig} = useUserConfig(true);
|
||||
const [userConfig, setUserConfig] = useState<UserConfig | null>(null);
|
||||
const [name, setName] = useState<string | undefined>(undefined);
|
||||
const [notionToken, setNotionToken] = useState<string | null>(null);
|
||||
|
||||
@@ -280,7 +280,6 @@ export default function SharedChat() {
|
||||
</div>
|
||||
|
||||
<div className={styles.chatBox}>
|
||||
<NavMenu selected="Chat" title={title} />
|
||||
<div className={styles.chatBoxBody}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<ChatBodyData
|
||||
|
||||
Reference in New Issue
Block a user