diff options
| author | Dhravya <[email protected]> | 2024-06-01 21:21:52 -0500 |
|---|---|---|
| committer | Dhravya <[email protected]> | 2024-06-01 21:21:52 -0500 |
| commit | f105a2fd92c25a75668c3615cd8328fa875050d8 (patch) | |
| tree | db5c8cd657623016029143b4123878ac6b025f2a /apps/web/app | |
| parent | started implmeneting filter (diff) | |
| download | supermemory-f105a2fd92c25a75668c3615cd8328fa875050d8.tar.xz supermemory-f105a2fd92c25a75668c3615cd8328fa875050d8.zip | |
commented the backend code with it's limitations + optimised and removed a bunch of unnecessary queries
Diffstat (limited to 'apps/web/app')
| -rw-r--r-- | apps/web/app/chat/page.tsx | 23 | ||||
| -rw-r--r-- | apps/web/app/globals.css | 48 | ||||
| -rw-r--r-- | apps/web/app/helpers/lib/searchParams.ts | 7 | ||||
| -rw-r--r-- | apps/web/app/home/actions.ts | 6 | ||||
| -rw-r--r-- | apps/web/app/home/page.tsx | 1 | ||||
| -rw-r--r-- | apps/web/app/home/queryinput.tsx | 152 | ||||
| -rw-r--r-- | apps/web/app/layout.tsx | 1 |
7 files changed, 108 insertions, 130 deletions
diff --git a/apps/web/app/chat/page.tsx b/apps/web/app/chat/page.tsx index fce4bfd1..bfe0c362 100644 --- a/apps/web/app/chat/page.tsx +++ b/apps/web/app/chat/page.tsx @@ -1,7 +1,24 @@ -import React from "react"; +import { chatSearchParamsCache } from "../helpers/lib/searchParams"; +import Menu from "../home/menu"; +import Header from "../home/header"; +import ChatWindow from "./chatWindow"; -function Page() { - return <div>Page</div>; +function Page({ + searchParams, +}: { + searchParams: Record<string, string | string[] | undefined>; +}) { + const { firstTime, q, spaces } = chatSearchParamsCache.parse(searchParams); + + return ( + <main className="h-screen flex flex-col p-4 relative"> + <Menu /> + + <Header /> + + <ChatWindow q={q} spaces={spaces ?? []} /> + </main> + ); } export default Page; diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css deleted file mode 100644 index b1902464..00000000 --- a/apps/web/app/globals.css +++ /dev/null @@ -1,48 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* :root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} */ - -@media (prefers-color-scheme: dark) { - :root { - --foreground: rgba(179, 188, 197, 1); - --foreground-menu: rgba(106, 115, 125, 1); - --background: rgba(23, 27, 31, 1); - --secondary: rgba(31, 36, 40, 1); - --primary: rgba(54, 157, 253, 1); - --border: rgba(51, 57, 67, 1); - } -} - -body { - color: var(--foreground); - background: var(--background); - font-size: 14px; -} - -@layer base { - .all-center { - display: flex; - align-items: center; - justify-content: center; - } -} - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} - -.gradient-background { - background: linear-gradient( - 150deg, - rgba(255, 255, 255, 0.1) 0%, - rgba(255, 255, 255, 0) - ); -} diff --git a/apps/web/app/helpers/lib/searchParams.ts b/apps/web/app/helpers/lib/searchParams.ts index a43a28fe..2e02aa3e 100644 --- a/apps/web/app/helpers/lib/searchParams.ts +++ b/apps/web/app/helpers/lib/searchParams.ts @@ -3,8 +3,15 @@ import { parseAsInteger, parseAsString, parseAsBoolean, + parseAsArrayOf, } from "nuqs/server"; export const homeSearchParamsCache = createSearchParamsCache({ firstTime: parseAsBoolean.withDefault(false), }); + +export const chatSearchParamsCache = createSearchParamsCache({ + firstTime: parseAsBoolean.withDefault(false), + q: parseAsString.withDefault(""), + spaces: parseAsArrayOf(parseAsInteger, ","), +}); diff --git a/apps/web/app/home/actions.ts b/apps/web/app/home/actions.ts index 0bb2d051..908fe79e 100644 --- a/apps/web/app/home/actions.ts +++ b/apps/web/app/home/actions.ts @@ -1,7 +1 @@ "use server"; - -import { redirect } from "next/navigation"; - -export async function navigate(q: string) { - redirect(`/chat?q=${q}`); -} diff --git a/apps/web/app/home/page.tsx b/apps/web/app/home/page.tsx index d9025a9d..9908c017 100644 --- a/apps/web/app/home/page.tsx +++ b/apps/web/app/home/page.tsx @@ -9,6 +9,7 @@ function Page({ }: { searchParams: Record<string, string | string[] | undefined>; }) { + // TODO: use this to show a welcome page/modal const { firstTime } = homeSearchParamsCache.parse(searchParams); return ( diff --git a/apps/web/app/home/queryinput.tsx b/apps/web/app/home/queryinput.tsx index c394d9c6..a0e25d83 100644 --- a/apps/web/app/home/queryinput.tsx +++ b/apps/web/app/home/queryinput.tsx @@ -1,88 +1,96 @@ "use client"; -import { ArrowRightIcon, MemoriesIcon, SelectIcon } from "@repo/ui/icons"; +import { ArrowRightIcon } from "@repo/ui/icons"; import Image from "next/image"; -import React from "react"; +import React, { useCallback, useState } from "react"; import Divider from "@repo/ui/shadcn/divider"; -import { redirect } from "next/navigation"; -import { navigate } from "./actions"; -import { FilterSpaces } from "@repo/ui/components/filterSpaces"; +import { MultipleSelector, Option } from "@repo/ui/shadcn/combobox"; +import { AnimatePresence } from "framer-motion"; +import { useRouter } from "next/navigation"; -function QueryInput() { - const [q, setQ] = React.useState(""); +const OPTIONS: Option[] = [ + { label: "nextjs", value: "0" }, + { label: "React", value: "1" }, + { label: "Remix", value: "2" }, + { label: "Vite", value: "3" }, + { label: "Nuxt", value: "4" }, + { label: "Vue", value: "5" }, + { label: "Svelte", value: "6" }, + { label: "Angular", value: "7" }, + { label: "Ember", value: "8" }, + { label: "Gatsby", value: "9" }, +]; - const parseQ = React.useCallback(() => { - const newQ = q.replace(/\n/g, "\\n"); - return newQ; - }, [q]); +function QueryInput({ + initialQuery = "", + initialSpaces = [], + disabled = false, +}: { + initialQuery?: string; + initialSpaces?: number[]; + disabled?: boolean; +}) { + const [q, setQ] = useState(initialQuery); - const [selectedSpaces, setSelectedSpaces] = React.useState<number[]>([]); + const [selectedSpaces, setSelectedSpaces] = useState<number[]>(initialSpaces); - return ( - <div className="bg-secondary rounded-[24px] w-full mt-40"> - {/* input and action button */} - <form action={async () => navigate(parseQ())} className="flex gap-4 p-3"> - <textarea - name="q" - cols={30} - rows={4} - className="bg-transparent pt-2.5 text-base text-[#989EA4] focus:text-foreground duration-200 tracking-[3%] outline-none resize-none w-full p-4" - placeholder="Ask your second brain..." - onKeyDown={(e) => { - if (e.key === "Enter") { - e.preventDefault(); - if (!e.shiftKey) navigate(parseQ()); - } - }} - onChange={(e) => setQ(e.target.value)} - value={q} - /> + const { push } = useRouter(); - <button - type="submit" - className="h-12 w-12 rounded-[14px] bg-[#21303D] all-center shrink-0 hover:brightness-125 duration-200 outline-none focus:outline focus:outline-primary active:scale-90" - > - <Image src={ArrowRightIcon} alt="Right arrow icon" /> - </button> - </form> + const parseQ = () => { + const newQ = + "/chat?q=" + + encodeURI(q) + + (selectedSpaces ? "&spaces=" + selectedSpaces.join(",") : ""); - <Divider /> + return newQ; + }; + return ( + <div> + <div className="bg-secondary rounded-t-[24px] w-full mt-40"> + {/* input and action button */} + <form action={async () => push(parseQ())} className="flex gap-4 p-3"> + <textarea + name="q" + cols={30} + rows={4} + className="bg-transparent pt-2.5 text-base text-[#989EA4] focus:text-foreground duration-200 tracking-[3%] outline-none resize-none w-full p-4" + placeholder="Ask your second brain..." + onKeyDown={(e) => { + if (e.key === "Enter") { + e.preventDefault(); + if (!e.shiftKey) push(parseQ()); + } + }} + onChange={(e) => setQ(e.target.value)} + value={q} + disabled={disabled} + /> + + <button + type="submit" + disabled={disabled} + className="h-12 w-12 rounded-[14px] bg-[#21303D] all-center shrink-0 hover:brightness-125 duration-200 outline-none focus:outline focus:outline-primary active:scale-90" + > + <Image src={ArrowRightIcon} alt="Right arrow icon" /> + </button> + </form> + + <Divider /> + </div> {/* selected sources */} - <div className="flex items-center gap-6 p-2"> - {/* <button className="bg-[#2B3237] h-9 p-2 px-3 flex items-center gap-2 rounded-full"> - <Image src={MemoriesIcon} alt="Memories icon" className="w-5" /> - <span className="pr-3">Filters</span> - <Image src={SelectIcon} alt="Select icon" className="w-4" /> - </button> */} - <FilterSpaces - name="Filters" - selectedSpaces={selectedSpaces} - setSelectedSpaces={setSelectedSpaces} - // side="top" - // align="start" - // className="mr-auto bg-[#252525] md:hidden" - spaces={[ - { - name: "Nvidia", - id: 2, - }, - { - name: "Open-source", - id: 3, - }, - { - name: "Artificial Intelligence", - id: 4, - }, - ]} + <div className="flex items-center gap-6 p-2 h-auto bg-secondary rounded-b-[24px]"> + <MultipleSelector + disabled={disabled} + defaultOptions={OPTIONS} + onChange={(e) => setSelectedSpaces(e.map((x) => parseInt(x.value)))} + placeholder="Focus on specific spaces..." + emptyIndicator={ + <p className="text-center text-lg leading-10 text-gray-600 dark:text-gray-400"> + no results found. + </p> + } /> - - <div className="flex gap-6 brightness-75"> - <p>Nvidia</p> - <p>Open-source</p> - <p>Artificial Intelligence</p> - </div> </div> </div> ); diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 37541f04..8d7cd5ea 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,4 +1,3 @@ -// import "./globals.css"; import "@repo/tailwind-config/globals.css"; import type { Metadata } from "next"; |