diff options
| author | Dhravya Shah <[email protected]> | 2024-07-25 10:00:52 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-07-25 10:00:52 -0500 |
| commit | a7e46750515cbf33edeff3acacdbfb65db30a6c5 (patch) | |
| tree | 0c2f5c28b6ca3f85392c396c73861ac8c8cdc0d1 /apps/web/app/(dash) | |
| parent | tabs lol (diff) | |
| parent | Merge pull request #159 from aryasaatvik/docs (diff) | |
| download | supermemory-a7e46750515cbf33edeff3acacdbfb65db30a6c5.tar.xz supermemory-a7e46750515cbf33edeff3acacdbfb65db30a6c5.zip | |
Merge branch 'main' into signout
Diffstat (limited to 'apps/web/app/(dash)')
| -rw-r--r-- | apps/web/app/(dash)/dialogContentContainer.tsx | 2 | ||||
| -rw-r--r-- | apps/web/app/(dash)/header/header.tsx | 32 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/history.tsx | 36 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/page.tsx | 51 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/queryinput.tsx | 31 | ||||
| -rw-r--r-- | apps/web/app/(dash)/layout.tsx | 8 | ||||
| -rw-r--r-- | apps/web/app/(dash)/menu.tsx | 2 |
7 files changed, 79 insertions, 83 deletions
diff --git a/apps/web/app/(dash)/dialogContentContainer.tsx b/apps/web/app/(dash)/dialogContentContainer.tsx index aae71237..4e8d81ef 100644 --- a/apps/web/app/(dash)/dialogContentContainer.tsx +++ b/apps/web/app/(dash)/dialogContentContainer.tsx @@ -100,7 +100,7 @@ export function DialogContentContainer({ }, []); return ( - <DialogContent className="sm:max-w-[475px] text-[#F2F3F5] rounded-2xl bg-background z-[39] backdrop-blur-md"> + <DialogContent className="sm:max-w-[475px] text-[#F2F3F5] rounded-2xl bg-background z-[39]"> <form action={async (e: FormData) => { const content = e.get("content")?.toString(); diff --git a/apps/web/app/(dash)/header/header.tsx b/apps/web/app/(dash)/header/header.tsx index a3fba9b1..595666b0 100644 --- a/apps/web/app/(dash)/header/header.tsx +++ b/apps/web/app/(dash)/header/header.tsx @@ -7,6 +7,8 @@ import { getChatHistory } from "../../actions/fetchers"; import NewChatButton from "./newChatButton"; import AutoBreadCrumbs from "./autoBreadCrumbs"; import SignOutButton from "./signOutButton"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@repo/ui/shadcn/dropdown-menu"; +import { CaretDownIcon } from "@radix-ui/react-icons"; async function Header() { const chatThreads = await getChatHistory(); @@ -33,27 +35,31 @@ async function Header() { <div className="flex items-center gap-2"> <NewChatButton /> - <div className="relative group"> - <button className="flex duration-200 items-center text-[#7D8994] hover:bg-[#1F2429] text-[13px] gap-2 px-3 py-2 rounded-xl"> - History - </button> - - <div className="absolute p-4 hidden group-hover:block right-0 w-full md:w-[400px] max-h-[70vh] overflow-auto"> - <div className="bg-[#1F2429] rounded-xl p-2 flex flex-col shadow-lg"> - {chatThreads.data.map((thread) => ( + <DropdownMenu> + <DropdownMenuTrigger className="inline-flex flex-row flex-nowrap items-center text-muted-foreground hover:text-foreground"> + History + <CaretDownIcon /> + </DropdownMenuTrigger> + <DropdownMenuContent className="p-4 w-full md:w-[400px] max-h-[70vh] overflow-auto border-none"> + {chatThreads.data.map((thread) => ( + <DropdownMenuItem asChild> <Link prefetch={false} href={`/chat/${thread.id}`} key={thread.id} - className="p-2 rounded-md hover:bg-secondary" + className="p-2 rounded-md cursor-pointer focus:bg-secondary focus:text-current" > {thread.firstMessage} </Link> - ))} - </div> - </div> - </div> + </DropdownMenuItem> + ))} + </DropdownMenuContent> + </DropdownMenu> + <SignOutButton /> + </div> + + </div> </div> </div> diff --git a/apps/web/app/(dash)/home/history.tsx b/apps/web/app/(dash)/home/history.tsx index 922734df..307ef4e3 100644 --- a/apps/web/app/(dash)/home/history.tsx +++ b/apps/web/app/(dash)/home/history.tsx @@ -5,26 +5,32 @@ import Link from "next/link"; import { memo, useEffect, useState } from "react"; import { motion } from "framer-motion"; import { chatThreads } from "@/server/db/schema"; +import { getQuerySuggestions } from "@/app/actions/doers"; +import { Button } from "@repo/ui/shadcn/button"; -const History = memo(() => { - const [chatThreads_, setChatThreads] = useState< - (typeof chatThreads.$inferSelect)[] | null - >(null); +const History = memo(({ setQuery }: { setQuery: (q: string) => void }) => { + const [suggestions, setSuggestions] = useState<string[] | null>(null); useEffect(() => { (async () => { - const chatThreads = await getChatHistory(); - if (!chatThreads.success || !chatThreads.data) { - console.error(chatThreads.error); + const suggestions = await getQuerySuggestions(); + if (!suggestions.success || !suggestions.data) { + console.error(suggestions.error); + setSuggestions([]); return; } - setChatThreads(chatThreads.data.reverse().slice(0, 3)); + console.log(suggestions); + if (typeof suggestions.data === "string") { + setSuggestions(JSON.parse(suggestions.data)); + return; + } + setSuggestions(suggestions.data.reverse().slice(0, 3)); })(); }, []); return ( <ul className="text-base list-none space-y-3 text-[#b9b9b9] mt-8"> - {!chatThreads_ && ( + {!suggestions && ( <> <Skeleton key="loader-1" @@ -40,17 +46,15 @@ const History = memo(() => { ></Skeleton> </> )} - {chatThreads_?.map((thread) => ( + {suggestions?.map((suggestion) => ( <motion.li initial={{ opacity: 0, filter: "blur(1px)" }} animate={{ opacity: 1, filter: "blur(0px)" }} - className="flex items-center gap-2 truncate" - key={thread.id} + className="flex items-center gap-2 truncate cursor-pointer" + key={suggestion} + onClick={() => setQuery(suggestion)} > - <ArrowLongRightIcon className="h-5" />{" "} - <Link prefetch={false} href={`/chat/${thread.id}`}> - {thread.firstMessage} - </Link> + <ArrowLongRightIcon className="h-5" /> {suggestion} </motion.li> ))} </ul> diff --git a/apps/web/app/(dash)/home/page.tsx b/apps/web/app/(dash)/home/page.tsx index ebd4d84b..d192d07d 100644 --- a/apps/web/app/(dash)/home/page.tsx +++ b/apps/web/app/(dash)/home/page.tsx @@ -4,12 +4,15 @@ import React, { useEffect, useState } from "react"; import QueryInput from "./queryinput"; import { getSessionAuthToken, getSpaces } from "@/app/actions/fetchers"; import { redirect, useRouter } from "next/navigation"; -import { createChatThread, linkTelegramToUser } from "@/app/actions/doers"; +import { + createChatThread, + getQuerySuggestions, + linkTelegramToUser, +} from "@/app/actions/doers"; import { toast } from "sonner"; import { motion } from "framer-motion"; -import { ChromeIcon, GithubIcon, TwitterIcon } from "lucide-react"; +import { ChromeIcon, GithubIcon, MailIcon, TwitterIcon } from "lucide-react"; import Link from "next/link"; -import { homeSearchParamsCache } from "@/lib/searchParams"; import History from "./history"; const slap = { @@ -26,28 +29,14 @@ const slap = { }; function Page({ searchParams }: { searchParams: Record<string, string> }) { - // TODO: use this to show a welcome page/modal - const firstTime = searchParams.firstTime === "true"; + const telegramUser = searchParams.telegramUser; + const extensionInstalled = searchParams.extension; + const [query, setQuery] = useState(searchParams.q || ""); - const query = searchParams.q || ""; - - if (firstTime) { - redirect("/onboarding"); - } - - const [queryPresent, setQueryPresent] = useState<boolean>(false); - - const [telegramUser, setTelegramUser] = useState<string | undefined>( - searchParams.telegramUser as string, - ); - const [extensionInstalled, setExtensionInstalled] = useState< - string | undefined - >(searchParams.extension as string); + const [spaces, setSpaces] = useState<{ id: number; name: string }[]>([]); const { push } = useRouter(); - const [spaces, setSpaces] = useState<{ id: number; name: string }[]>([]); - useEffect(() => { if (telegramUser) { const linkTelegram = async () => { @@ -63,10 +52,6 @@ function Page({ searchParams }: { searchParams: Record<string, string> }) { linkTelegram(); } - if (extensionInstalled) { - toast.success("Extension installed successfully"); - } - getSpaces().then((res) => { if (res.success && res.data) { setSpaces(res.data); @@ -77,15 +62,15 @@ function Page({ searchParams }: { searchParams: Record<string, string> }) { getSessionAuthToken().then((token) => { if (typeof window === "undefined") return; + if (extensionInstalled) { + toast.success("Extension installed successfully"); + } window.postMessage({ token: token.data }, "*"); }); }, [telegramUser]); return ( <div className="max-w-3xl h-full justify-center flex mx-auto w-full flex-col px-2 md:px-0"> - {/* all content goes here */} - {/* <div className="">hi {firstTime ? 'first time' : ''}</div> */} - <motion.h1 {...{ ...slap, @@ -101,8 +86,8 @@ function Page({ searchParams }: { searchParams: Record<string, string> }) { <div className="w-full pb-20 mt-10"> <QueryInput - initialQuery={query} - setQueryPresent={setQueryPresent} + query={query} + setQuery={setQuery} handleSubmit={async (q, spaces, proMode) => { if (q.length === 0) { toast.error("Query is required"); @@ -123,7 +108,7 @@ function Page({ searchParams }: { searchParams: Record<string, string> }) { initialSpaces={spaces} /> - <History /> + <History setQuery={setQuery} /> </div> <div className="w-full fixed bottom-0 left-0 p-4"> @@ -138,12 +123,12 @@ function Page({ searchParams }: { searchParams: Record<string, string> }) { Install extension </Link> <Link - href="https://github.com/supermemoryai/supermemory/issues/new" + href="mailto:[email protected]" target="_blank" rel="noreferrer" className="flex items-center gap-2 text-muted-foreground hover:text-grey-50 duration-300" > - <GithubIcon className="w-4 h-4" /> + <MailIcon className="w-4 h-4" /> Bug report </Link> <Link diff --git a/apps/web/app/(dash)/home/queryinput.tsx b/apps/web/app/(dash)/home/queryinput.tsx index 9f1e7292..82561438 100644 --- a/apps/web/app/(dash)/home/queryinput.tsx +++ b/apps/web/app/(dash)/home/queryinput.tsx @@ -8,26 +8,24 @@ import { Switch } from "@repo/ui/shadcn/switch"; import { Label } from "@repo/ui/shadcn/label"; function QueryInput({ - setQueryPresent, - initialQuery, initialSpaces, handleSubmit, + query, + setQuery, }: { - setQueryPresent: (t: boolean) => void; initialSpaces?: { id: number; name: string; }[]; - initialQuery?: string; mini?: boolean; handleSubmit: ( q: string, spaces: { id: number; name: string }[], proMode: boolean, ) => void; + query: string; + setQuery: (q: string) => void; }) { - const [q, setQ] = useState(initialQuery || ""); - const [proMode, setProMode] = useState(false); const [selectedSpaces, setSelectedSpaces] = useState< @@ -42,11 +40,11 @@ function QueryInput({ {/* input and action button */} <form action={async () => { - if (q.trim().length === 0) { + if (query.trim().length === 0) { return; } - handleSubmit(q, selectedSpaces, proMode); - setQ(""); + handleSubmit(query, selectedSpaces, proMode); + setQuery(""); }} > <textarea @@ -59,20 +57,15 @@ function QueryInput({ onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); - if (q.trim().length === 0) { + if (query.trim().length === 0) { return; } - handleSubmit(q, selectedSpaces, proMode); - setQ(""); + handleSubmit(query, selectedSpaces, proMode); + setQuery(""); } }} - onChange={(e) => - setQ((prev) => { - setQueryPresent(!!e.target.value.length); - return e.target.value; - }) - } - value={q} + onChange={(e) => setQuery(e.target.value)} + value={query} /> <div className="flex p-2 px-3 w-full items-center justify-between rounded-xl overflow-hidden"> <FilterSpaces diff --git a/apps/web/app/(dash)/layout.tsx b/apps/web/app/(dash)/layout.tsx index b2b27a4f..c6174945 100644 --- a/apps/web/app/(dash)/layout.tsx +++ b/apps/web/app/(dash)/layout.tsx @@ -4,6 +4,7 @@ import { redirect } from "next/navigation"; import { auth } from "../../server/auth"; import { Toaster } from "@repo/ui/shadcn/sonner"; import BackgroundPlus from "../(landing)/GridPatterns/PlusGrid"; +import { getUser } from "../actions/fetchers"; async function Layout({ children }: { children: React.ReactNode }) { const info = await auth(); @@ -12,6 +13,13 @@ async function Layout({ children }: { children: React.ReactNode }) { return redirect("/signin"); } + const user = await getUser(); + const hasOnboarded = user.data?.hasOnboarded; + + if (!hasOnboarded) { + redirect("/onboarding"); + } + return ( <main className="h-screen flex flex-col"> <div className="fixed top-0 left-0 w-full z-40"> diff --git a/apps/web/app/(dash)/menu.tsx b/apps/web/app/(dash)/menu.tsx index 34ef3b2d..c56a3247 100644 --- a/apps/web/app/(dash)/menu.tsx +++ b/apps/web/app/(dash)/menu.tsx @@ -176,7 +176,7 @@ function Menu() { </div> </div> - <DialogContent className="sm:max-w-[475px] text-[#F2F3F5] rounded-2xl bg-background z-[39] backdrop-blur-md"> + <DialogContent className="sm:max-w-[475px] text-[#F2F3F5] rounded-2xl bg-background z-[39]"> <form action={async (e: FormData) => { const content = e.get("content")?.toString(); |