Update nav menu styling to include everything in one header

- Move the nav menu into the chat history side panel component, so that they both show up on one line
- Update all pages to use it with the new formatting
- in mobile, present the sidebar button, home button, and profile button evenly centered in the middle
This commit is contained in:
sabaimran
2024-08-02 17:46:13 +05:30
parent 5a8ea884a9
commit d3c07a098d
13 changed files with 182 additions and 157 deletions

View File

@@ -46,7 +46,7 @@ div.agentList {
} }
@media only screen and (max-width: 700px) { @media only screen and (max-width: 768px) {
div.agentList { div.agentList {
width: 100%; width: 100%;
padding: 0; padding: 0;
@@ -54,4 +54,9 @@ div.agentList {
margin-left: auto; margin-left: auto;
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
div.sidePanel {
position: relative;
height: 100%;
}
} }

View File

@@ -266,9 +266,6 @@ export default function Agents() {
return ( return (
<main className={`${styles.main} w-full mx-auto`}> <main className={`${styles.main} w-full mx-auto`}>
<div className="float-right w-fit h-fit">
<NavMenu selected="Agents" />
</div>
{ {
showLoginPrompt && showLoginPrompt &&
<LoginPrompt <LoginPrompt
@@ -284,7 +281,7 @@ export default function Agents() {
/> />
</div> </div>
<div className={`mx-auto ${isMobileWidth ? "w-11/12" : "w-1/2"} pt-4`}> <div className={`mx-auto ${isMobileWidth ? "w-11/12" : "w-1/2"} pt-4`}>
<div className="pt-8 flex justify-between align-middle w-full"> <div className={`pt-4 md:pt-8 flex justify-between align-middle w-full`}>
<h1 className="text-3xl">Agents</h1> <h1 className="text-3xl">Agents</h1>
<div className="ml-auto float-right border p-2 pt-3 rounded-xl font-bold hover:bg-stone-100 dark:hover:bg-neutral-900"> <div className="ml-auto float-right border p-2 pt-3 rounded-xl font-bold hover:bg-stone-100 dark:hover:bg-neutral-900">
<TooltipProvider> <TooltipProvider>

View File

@@ -28,4 +28,9 @@ div.sidePanel {
div.pageLayout { div.pageLayout {
max-width: 90vw; max-width: 90vw;
} }
div.sidePanel {
position: relative;
height: 100%;
}
} }

View File

@@ -936,9 +936,6 @@ export default function Automations() {
return ( return (
<main className={`${styles.main} w-full ml-auto mr-auto`}> <main className={`${styles.main} w-full ml-auto mr-auto`}>
<div className="float-right w-fit h-fit">
<NavMenu selected="Automations" />
</div>
<div className={`grid w-full ml-auto mr-auto`}> <div className={`grid w-full ml-auto mr-auto`}>
<div className={`${styles.sidePanel} top-0`}> <div className={`${styles.sidePanel} top-0`}>
<SidePanel <SidePanel
@@ -949,7 +946,7 @@ export default function Automations() {
</div> </div>
<div className={`${styles.pageLayout} w-full`}> <div className={`${styles.pageLayout} w-full`}>
<div className='py-4 sm:flex sm:justify-between grid gap-1'> <div className='py-4 sm:flex sm:justify-between grid gap-1'>
<h1 className="text-3xl">Automations</h1> <h1 className="text-3xl pt-4">Automations</h1>
<div className='flex flex-wrap gap-2 items-center md:justify-start justify-end'> <div className='flex flex-wrap gap-2 items-center md:justify-start justify-end'>
{ {
authenticatedData ? ( authenticatedData ? (

View File

@@ -231,6 +231,8 @@ export default function Chat() {
<title> <title>
{title} {title}
</title> </title>
{
!isMobileWidth &&
<div> <div>
<SidePanel <SidePanel
conversationId={conversationId} conversationId={conversationId}
@@ -238,9 +240,25 @@ export default function Chat() {
isMobileWidth={isMobileWidth} isMobileWidth={isMobileWidth}
/> />
</div> </div>
}
<div className={styles.chatBox}> <div className={styles.chatBox}>
<NavMenu selected="Chat" title={title} /> {
isMobileWidth &&
<div>
<SidePanel
conversationId={conversationId}
uploadedFiles={uploadedFiles}
isMobileWidth={isMobileWidth}
/>
</div>
}
<div className={styles.chatBoxBody}> <div className={styles.chatBoxBody}>
{
!isMobileWidth &&
<div className={`text-nowrap text-ellipsis overflow-hidden max-w-screen-md grid items-top font-bold mr-8`}>
{title && <h2 className={`text-lg text-ellipsis whitespace-nowrap overflow-x-hidden pt-4`}>{title}</h2>}
</div>
}
<Suspense fallback={<Loading />}> <Suspense fallback={<Loading />}>
<ChatBodyData <ChatBodyData
isLoggedIn={authenticatedData !== null} isLoggedIn={authenticatedData !== null}

View File

@@ -17,10 +17,6 @@ a.selected {
div.titleBar { div.titleBar {
display: flex; display: flex;
padding-left: 12px;
padding-right: 12px;
padding-top: 16px;
padding-bottom: 16px;
justify-content: space-between; justify-content: space-between;
align-content: space-evenly; align-content: space-evenly;
align-items: start; align-items: start;

View File

@@ -23,35 +23,16 @@ import {
DropdownMenuTrigger, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"; } from "@/components/ui/dropdown-menu";
import { Moon, Sun, UserCircle, User, Robot, MagnifyingGlass, Question, GearFine, ArrowRight } from '@phosphor-icons/react'; import { Moon, Sun, UserCircle, User, Robot, MagnifyingGlass, Question, GearFine, ArrowRight } from '@phosphor-icons/react';
import { KhojLogoType } from '../logo/khogLogo';
export default function NavMenu() {
interface NavMenuProps {
selected: string;
showLogo?: boolean;
title?: string;
}
export default function NavMenu(props: NavMenuProps) {
const userData = useAuthenticatedData(); const userData = useAuthenticatedData();
const [displayTitle, setDisplayTitle] = useState<string | undefined>(props.title);
const [isMobileWidth, setIsMobileWidth] = useState(false); const [isMobileWidth, setIsMobileWidth] = useState(false);
const [darkMode, setDarkMode] = useState(false); const [darkMode, setDarkMode] = useState(false);
const [initialLoadDone, setInitialLoadDone] = useState(false); const [initialLoadDone, setInitialLoadDone] = useState(false);
useEffect(() => { useEffect(() => {
setIsMobileWidth(window.innerWidth < 768); setIsMobileWidth(window.innerWidth < 768);
if (props.title) {
setDisplayTitle(props.title);
} else if (!props.title) {
setDisplayTitle(undefined);
}
}, [props.title]);
useEffect(() => {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
setIsMobileWidth(window.innerWidth < 768); setIsMobileWidth(window.innerWidth < 768);
@@ -94,15 +75,6 @@ export default function NavMenu(props: NavMenuProps) {
return ( return (
<div className={styles.titleBar}> <div className={styles.titleBar}>
<div className={`text-nowrap text-ellipsis overflow-hidden max-w-screen-md grid items-top font-bold mr-8`}>
{displayTitle && <h2 className={`text-lg text-ellipsis whitespace-nowrap overflow-x-hidden`} >{displayTitle}</h2>}
{
!displayTitle && props.showLogo &&
<Link href='/'>
<KhojLogoType />
</Link>
}
</div>
{ {
isMobileWidth ? isMobileWidth ?
<DropdownMenu> <DropdownMenu>

View File

@@ -76,6 +76,7 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
import { modifyFileFilterForConversation } from "@/app/common/chatFunctions"; import { modifyFileFilterForConversation } from "@/app/common/chatFunctions";
import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area"; import { ScrollAreaScrollbar } from "@radix-ui/react-scroll-area";
import { KhojLogo, KhojLogoType } from "@/app/components/logo/khogLogo"; import { KhojLogo, KhojLogoType } from "@/app/components/logo/khogLogo";
import NavMenu from "../navMenu/navMenu";
// Define a fetcher function // Define a fetcher function
const fetcher = (url: string) => fetch(url).then((res) => res.json()); const fetcher = (url: string) => fetch(url).then((res) => res.json());
@@ -660,11 +661,8 @@ export default function SidePanel(props: SidePanelProps) {
}, [chatSessions]); }, [chatSessions]);
return ( return (
<div className={`${styles.panel} ${enabled ? styles.expanded : styles.collapsed} mt-1`}> <div className={`${styles.panel} ${enabled ? styles.expanded : styles.collapsed} ${props.isMobileWidth ? 'mt-0' : 'mt-1'}`}>
<div className={`flex justify-between flex-row`}> <div className={`flex justify-between flex-row`}>
<Link href='/'>
{props.isMobileWidth && <KhojLogo /> || <KhojLogoType />}
</Link>
{ {
authenticatedData && props.isMobileWidth ? authenticatedData && props.isMobileWidth ?
<Drawer open={enabled} onOpenChange={(open) => { <Drawer open={enabled} onOpenChange={(open) => {
@@ -672,7 +670,7 @@ export default function SidePanel(props: SidePanelProps) {
setEnabled(open); setEnabled(open);
} }
}> }>
<DrawerTrigger><Sidebar className="h-4 w-4 mx-2" weight="thin" /></DrawerTrigger> <DrawerTrigger><Sidebar className="h-6 w-6 mx-2" weight="thin" /></DrawerTrigger>
<DrawerContent> <DrawerContent>
<DrawerHeader> <DrawerHeader>
<DrawerTitle>Sessions and Files</DrawerTitle> <DrawerTitle>Sessions and Files</DrawerTitle>
@@ -698,7 +696,11 @@ export default function SidePanel(props: SidePanelProps) {
</DrawerContent> </DrawerContent>
</Drawer> </Drawer>
: :
<div className={`${enabled ? 'flex items-center flex-row gap-2' : 'flex'}`}> <div className={`flex justify-between flex-row`}>
<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="/"> <Link className={`ml-4 mr-4`} href="/">
{enabled ? <NotePencil className="h-6 w-6" /> : <NotePencil className="h-6 w-6" color="gray" />} {enabled ? <NotePencil className="h-6 w-6" /> : <NotePencil className="h-6 w-6" color="gray" />}
</Link> </Link>
@@ -706,6 +708,20 @@ export default function SidePanel(props: SidePanelProps) {
{enabled ? <Sidebar className="h-6 w-6" /> : <Sidebar className="h-6 w-6" color="gray" />} {enabled ? <Sidebar className="h-6 w-6" /> : <Sidebar className="h-6 w-6" color="gray" />}
</button> </button>
</div> </div>
<div className="fixed right-0 w-fit h-fit">
<NavMenu />
</div>
</div>
}
{
props.isMobileWidth &&
<Link href='/' className="content-center">
<KhojLogoType />
</Link>
}
{
props.isMobileWidth &&
<NavMenu />
} }
</div> </div>
{ {

View File

@@ -123,9 +123,9 @@ div.modalSessionsList div.session {
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
div.panel { div.panel {
padding: 0.5rem; padding: 0.25rem;
position: fixed; /* position: fixed; */
width: fit-content; width: 100%;
} }
div.expanded { div.expanded {

View File

@@ -78,7 +78,13 @@ div.chatBoxBody {
display: grid; display: grid;
height: 100%; height: 100%;
margin: auto; margin: auto;
grid-template-rows: auto 1fr; }
div.homeGreetings {
display: grid;
height: 100%;
margin: auto;
grid-template-rows: 1fr 2fr;
} }
@@ -108,6 +114,10 @@ div.sidePanel {
grid-template-rows: auto; grid-template-rows: auto;
} }
div.sidePanel {
position: relative;
}
div.chatBox { div.chatBox {
padding: 0; padding: 0;
} }
@@ -117,4 +127,8 @@ div.sidePanel {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
div.homeGreetings {
grid-template-rows: auto;
}
} }

View File

@@ -6,7 +6,6 @@ import React, { useEffect, useState } from 'react';
import SuggestionCard from './components/suggestions/suggestionCard'; import SuggestionCard from './components/suggestions/suggestionCard';
import SidePanel from './components/sidePanel/chatHistorySidePanel'; import SidePanel from './components/sidePanel/chatHistorySidePanel';
import NavMenu from './components/navMenu/navMenu';
import Loading from './components/loading/loading'; import Loading from './components/loading/loading';
import useSWR from 'swr'; import useSWR from 'swr';
import Image from 'next/image'; import Image from 'next/image';
@@ -157,8 +156,8 @@ function ChatBodyData(props: ChatBodyDataProps) {
} }
return ( return (
<div className={`${styles.chatBoxBody}`}> <div className={`${styles.homeGreetings}`}>
<div className="w-full text-center"> <div className={`w-full text-center justify-end content-end`}>
<div className="items-center"> <div className="items-center">
<h1 className="text-center pb-6 px-4 w-fit ml-auto mr-auto">{greeting}</h1> <h1 className="text-center pb-6 px-4 w-fit ml-auto mr-auto">{greeting}</h1>
</div> </div>
@@ -218,7 +217,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
<button <button
onClick={shuffleSuggestionsCards} onClick={shuffleSuggestionsCards}
className="m-2 p-1.5 rounded-lg dark:hover:bg-[var(--background-color)] hover:bg-stone-100 border border-stone-100 text-sm text-stone-500 dark:text-stone-300 dark:border-neutral-700"> className="m-2 p-1.5 rounded-lg dark:hover:bg-[var(--background-color)] hover:bg-stone-100 border border-stone-100 text-sm text-stone-500 dark:text-stone-300 dark:border-neutral-700">
More Examples <ClockCounterClockwise className='h-4 w-4 inline' /> More Ideas <ClockCounterClockwise className='h-4 w-4 inline' />
</button> </button>
</div> </div>
</div> </div>
@@ -310,7 +309,6 @@ export default function Home() {
/> />
</div> </div>
<div className={`${styles.chatBox}`}> <div className={`${styles.chatBox}`}>
<NavMenu selected="Chat" title={title}></NavMenu>
<div className={`${styles.chatBoxBody}`}> <div className={`${styles.chatBoxBody}`}>
<ChatBodyData <ChatBodyData
isLoggedIn={authenticatedData !== null} isLoggedIn={authenticatedData !== null}

View File

@@ -5,7 +5,6 @@ import { Input } from '@/components/ui/input';
import { useAuthenticatedData } from '../common/auth'; import { useAuthenticatedData } from '../common/auth';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import SidePanel from '../components/sidePanel/chatHistorySidePanel'; import SidePanel from '../components/sidePanel/chatHistorySidePanel';
import NavMenu from '../components/navMenu/navMenu';
import styles from './search.module.css'; import styles from './search.module.css';
import { ScrollArea } from '@/components/ui/scroll-area'; import { ScrollArea } from '@/components/ui/scroll-area';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
@@ -211,20 +210,17 @@ export default function Search() {
console.log('searchResults', searchResults); console.log('searchResults', searchResults);
return ( return (
<div className={`${styles.searchLayout}`}> <div>
<div className='h-full'> <div className={`h-full ${styles.sidePanel}`}>
<SidePanel <SidePanel
conversationId={null} conversationId={null}
uploadedFiles={[]} uploadedFiles={[]}
isMobileWidth={isMobileWidth} isMobileWidth={isMobileWidth}
/> />
</div> </div>
<div className="md:w-3/4 sm:w-full mr-auto ml-auto"> <div className={`${styles.searchLayout}`}>
<NavMenu title={title} selected='Chat' /> <div className="md:w-3/4 sm:w-full mr-auto ml-auto pt-4 md:pt-8">
<div className='p-4 md:w-3/4 sm:w-full mr-auto ml-auto'> <div className='p-4 md:w-3/4 sm:w-full mr-auto ml-auto'>
{
isMobileWidth && <div className='font-bold'>Search</div>
}
<div className='flex justify-between items-center border-2 border-muted p-2 gap-4 rounded-lg'> <div className='flex justify-between items-center border-2 border-muted p-2 gap-4 rounded-lg'>
<MagnifyingGlass className='inline m-2' /> <MagnifyingGlass className='inline m-2' />
<Input <Input
@@ -306,5 +302,6 @@ export default function Search() {
</div> </div>
</div> </div>
</div> </div>
</div>
); );
} }

View File

@@ -1,12 +1,22 @@
div.searchLayout { div.searchLayout {
display: grid; display: grid;
grid-template-columns: auto 1fr; grid-template-columns: 1fr;
gap: 1rem; gap: 1rem;
height: 100vh; height: 100vh;
} }
div.sidePanel {
position: fixed;
height: 100%;
}
@media screen and (max-width: 768px) { @media screen and (max-width: 768px) {
div.searchLayout { div.searchLayout {
gap: 0; gap: 0;
} }
div.sidePanel {
position: relative;
height: 100%;
}
} }