aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/(dash)
diff options
context:
space:
mode:
authorDhravya Shah <[email protected]>2024-07-25 10:00:52 -0500
committerGitHub <[email protected]>2024-07-25 10:00:52 -0500
commita7e46750515cbf33edeff3acacdbfb65db30a6c5 (patch)
tree0c2f5c28b6ca3f85392c396c73861ac8c8cdc0d1 /apps/web/app/(dash)
parenttabs lol (diff)
parentMerge pull request #159 from aryasaatvik/docs (diff)
downloadsupermemory-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.tsx2
-rw-r--r--apps/web/app/(dash)/header/header.tsx32
-rw-r--r--apps/web/app/(dash)/home/history.tsx36
-rw-r--r--apps/web/app/(dash)/home/page.tsx51
-rw-r--r--apps/web/app/(dash)/home/queryinput.tsx31
-rw-r--r--apps/web/app/(dash)/layout.tsx8
-rw-r--r--apps/web/app/(dash)/menu.tsx2
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();