aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhravya <[email protected]>2024-06-29 02:10:13 -0500
committerDhravya <[email protected]>2024-06-29 02:10:13 -0500
commit9272d87e5f46aeaf1aea0927d47cf3dd69507867 (patch)
tree063812c491ff5a898e6e15d271e11bf61d1d134c
parentfix: Spaces filter not working (diff)
downloadsupermemory-9272d87e5f46aeaf1aea0927d47cf3dd69507867.tar.xz
supermemory-9272d87e5f46aeaf1aea0927d47cf3dd69507867.zip
fixed new chat button showing up on all pages
-rw-r--r--apps/cf-ai-backend/src/index.ts4
-rw-r--r--apps/web/app/(auth)/signin/page.tsx8
-rw-r--r--apps/web/app/(dash)/chat/chatWindow.tsx2
-rw-r--r--apps/web/app/(dash)/header/header.tsx (renamed from apps/web/app/(dash)/header.tsx)12
-rw-r--r--apps/web/app/(dash)/header/newChatButton.tsx27
-rw-r--r--apps/web/app/(dash)/home/page.tsx1
-rw-r--r--apps/web/app/(dash)/home/queryinput.tsx36
-rw-r--r--apps/web/app/(dash)/layout.tsx2
-rw-r--r--apps/web/app/(dash)/menu.tsx113
-rw-r--r--apps/web/app/(landing)/page.tsx5
-rw-r--r--apps/web/app/actions/doers.ts2
-rw-r--r--apps/web/middleware.ts13
-rw-r--r--packages/ui/shadcn/combobox.tsx12
-rw-r--r--packages/ui/shadcn/command.tsx5
14 files changed, 188 insertions, 54 deletions
diff --git a/apps/cf-ai-backend/src/index.ts b/apps/cf-ai-backend/src/index.ts
index dbc0989b..78e1c596 100644
--- a/apps/cf-ai-backend/src/index.ts
+++ b/apps/cf-ai-backend/src/index.ts
@@ -375,10 +375,6 @@ app.post(
// SLICED to 5 to avoid too many queries
for (const space of spaces.slice(0, 5)) {
if (space && space.length >= 1) {
- console.log(
- "this is the key being used",
- `space-${query.user}-${space}`,
- );
// it's possible for space list to be [undefined] so we only add space filter conditionally
filter[`space-${query.user}-${space}`] = 1;
}
diff --git a/apps/web/app/(auth)/signin/page.tsx b/apps/web/app/(auth)/signin/page.tsx
index b117716e..bfb341ff 100644
--- a/apps/web/app/(auth)/signin/page.tsx
+++ b/apps/web/app/(auth)/signin/page.tsx
@@ -1,14 +1,20 @@
import Image from "next/image";
import Link from "next/link";
import Logo from "@/public/logo.svg";
-import { signIn } from "@/server/auth";
+import { auth, signIn } from "@/server/auth";
import { Google } from "@repo/ui/components/icons";
import gradientStyle from "./_components/TextGradient/gradient.module.css";
import { cn } from "@repo/ui/lib/utils";
+import { redirect } from "next/navigation";
export const runtime = "edge";
async function Signin() {
+ const user = await auth();
+
+ if (user) {
+ await redirect("/home");
+ }
return (
<div className="flex relative font-geistSans overflow-hidden items-center justify-between min-h-screen">
<div className="relative w-full lg:w-1/2 flex items-center min-h-screen bg-page-gradient p-8 border-r-[1px] border-white/5">
diff --git a/apps/web/app/(dash)/chat/chatWindow.tsx b/apps/web/app/(dash)/chat/chatWindow.tsx
index 99c997e4..32c45246 100644
--- a/apps/web/app/(dash)/chat/chatWindow.tsx
+++ b/apps/web/app/(dash)/chat/chatWindow.tsx
@@ -412,7 +412,7 @@ function ChatWindow({
mini
className="w-full shadow-md"
initialQuery={""}
- initialSpaces={[]}
+ initialSpaces={spaces}
handleSubmit={async (q, spaces) => {
setChatHistory((prevChatHistory) => {
return [
diff --git a/apps/web/app/(dash)/header.tsx b/apps/web/app/(dash)/header/header.tsx
index 1265fc93..9154ead8 100644
--- a/apps/web/app/(dash)/header.tsx
+++ b/apps/web/app/(dash)/header/header.tsx
@@ -1,11 +1,10 @@
import React from "react";
import Image from "next/image";
import Link from "next/link";
-import Logo from "../../public/logo.svg";
-import { AddIcon, ChatIcon } from "@repo/ui/icons";
+import Logo from "../../../public/logo.svg";
-import { db } from "@/server/db";
-import { getChatHistory } from "../actions/fetchers";
+import { getChatHistory } from "../../actions/fetchers";
+import NewChatButton from "./newChatButton";
async function Header() {
const chatThreads = await getChatHistory();
@@ -26,10 +25,7 @@ async function Header() {
</Link>
<div className="flex items-center gap-2">
- <button className="flex duration-200 items-center text-[#7D8994] hover:bg-[#1F2429] text-[13px] gap-2 px-3 py-2 rounded-xl">
- <Image src={ChatIcon} alt="Chat icon" className="w-5" />
- Start new chat
- </button>
+ <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">
diff --git a/apps/web/app/(dash)/header/newChatButton.tsx b/apps/web/app/(dash)/header/newChatButton.tsx
new file mode 100644
index 00000000..0e9e1c5a
--- /dev/null
+++ b/apps/web/app/(dash)/header/newChatButton.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import { ChatIcon } from "@repo/ui/icons";
+import Image from "next/image";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import React from "react";
+
+function NewChatButton() {
+ const path = usePathname();
+
+ if (path.startsWith("/chat")) {
+ return (
+ <Link
+ href="/home"
+ className="flex duration-200 items-center text-[#7D8994] hover:bg-[#1F2429] text-[13px] gap-2 px-3 py-2 rounded-xl"
+ >
+ <Image src={ChatIcon} alt="Chat icon" className="w-5" />
+ Start new chat
+ </Link>
+ );
+ }
+
+ return null;
+}
+
+export default NewChatButton;
diff --git a/apps/web/app/(dash)/home/page.tsx b/apps/web/app/(dash)/home/page.tsx
index 17d52529..aabb4d80 100644
--- a/apps/web/app/(dash)/home/page.tsx
+++ b/apps/web/app/(dash)/home/page.tsx
@@ -74,6 +74,7 @@ function Page({
);
}}
initialSpaces={spaces}
+ setInitialSpaces={setSpaces}
/>
</div>
</div>
diff --git a/apps/web/app/(dash)/home/queryinput.tsx b/apps/web/app/(dash)/home/queryinput.tsx
index 868f93f9..3c944c05 100644
--- a/apps/web/app/(dash)/home/queryinput.tsx
+++ b/apps/web/app/(dash)/home/queryinput.tsx
@@ -8,6 +8,8 @@ import { useRouter } from "next/navigation";
import { getSpaces } from "@/app/actions/fetchers";
import Combobox from "@repo/ui/shadcn/combobox";
import { MinusIcon } from "lucide-react";
+import { toast } from "sonner";
+import { createSpace } from "@/app/actions/doers";
function QueryInput({
initialQuery = "",
@@ -16,6 +18,7 @@ function QueryInput({
className,
mini = false,
handleSubmit,
+ setInitialSpaces,
}: {
initialQuery?: string;
initialSpaces?: {
@@ -26,6 +29,9 @@ function QueryInput({
className?: string;
mini?: boolean;
handleSubmit: (q: string, spaces: { id: number; name: string }[]) => void;
+ setInitialSpaces?: React.Dispatch<
+ React.SetStateAction<{ id: number; name: string }[]>
+ >;
}) {
const [q, setQ] = useState(initialQuery);
@@ -104,6 +110,7 @@ function QueryInput({
<div className="flex justify-between items-center gap-6 h-auto bg-secondary rounded-b-3xl border-2 border-border">
<Combobox
options={options}
+ className="rounded-bl-3xl bg-[#3C464D] w-44"
onSelect={(v) =>
setSelectedSpaces((prev) => {
if (v === "") {
@@ -112,8 +119,33 @@ function QueryInput({
return [...prev, parseInt(v)];
})
}
- onSubmit={() => {}}
- placeholder="Filter spaces..."
+ onSubmit={async (spaceName) => {
+ const space = options.find((x) => x.label === spaceName);
+ toast.info("Creating space...");
+
+ if (space) {
+ toast.error("A space with that name already exists.");
+ }
+
+ const creationTask = await createSpace(spaceName);
+ if (creationTask.success && creationTask.data) {
+ toast.success("Space created " + creationTask.data);
+ setInitialSpaces?.((prev) => [
+ ...prev,
+ {
+ name: spaceName,
+ id: creationTask.data!,
+ },
+ ]);
+ setSelectedSpaces((prev) => [...prev, creationTask.data!]);
+ } else {
+ toast.error(
+ "Space creation failed: " + creationTask.error ??
+ "Unknown error",
+ );
+ }
+ }}
+ placeholder="Chat with a space..."
/>
<div className="flex flex-row gap-0.5 h-full">
diff --git a/apps/web/app/(dash)/layout.tsx b/apps/web/app/(dash)/layout.tsx
index 3ae4e76d..edac6048 100644
--- a/apps/web/app/(dash)/layout.tsx
+++ b/apps/web/app/(dash)/layout.tsx
@@ -1,4 +1,4 @@
-import Header from "./header";
+import Header from "./header/header";
import Menu from "./menu";
import { redirect } from "next/navigation";
import { auth } from "../../server/auth";
diff --git a/apps/web/app/(dash)/menu.tsx b/apps/web/app/(dash)/menu.tsx
index 29d25574..4b03604f 100644
--- a/apps/web/app/(dash)/menu.tsx
+++ b/apps/web/app/(dash)/menu.tsx
@@ -5,7 +5,7 @@ import Image from "next/image";
import Link from "next/link";
import { MemoriesIcon, ExploreIcon, CanvasIcon, AddIcon } from "@repo/ui/icons";
import { Button } from "@repo/ui/shadcn/button";
-import { PlusCircleIcon } from "lucide-react";
+import { MinusIcon, PlusCircleIcon } from "lucide-react";
import {
Dialog,
DialogContent,
@@ -34,8 +34,9 @@ import {
TooltipTrigger,
} from "@repo/ui/shadcn/tooltip";
import { InformationCircleIcon } from "@heroicons/react/24/outline";
-import { createMemory } from "../actions/doers";
+import { createMemory, createSpace } from "../actions/doers";
import { Input } from "@repo/ui/shadcn/input";
+import ComboboxWithCreate from "@repo/ui/shadcn/combobox";
function Menu() {
const [spaces, setSpaces] = useState<Space[]>([]);
@@ -77,7 +78,7 @@ function Menu() {
];
const [content, setContent] = useState("");
- const [selectedSpace, setSelectedSpace] = useState<string | null>(null);
+ const [selectedSpaces, setSelectedSpaces] = useState<number[]>([]);
const autoDetectedType = useMemo(() => {
if (content.length === 0) {
@@ -97,6 +98,15 @@ function Menu() {
const [dialogOpen, setDialogOpen] = useState(false);
+ const options = useMemo(
+ () =>
+ spaces.map((x) => ({
+ label: x.name,
+ value: x.id.toString(),
+ })),
+ [spaces],
+ );
+
const handleSubmit = async (content?: string, space?: string) => {
setDialogOpen(false);
@@ -212,7 +222,7 @@ function Menu() {
className="text-[#858B92] flex items-center gap-1 duration-200 transform transition-transform"
htmlFor="space"
>
- Space
+ Spaces
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
@@ -227,26 +237,81 @@ function Menu() {
</Tooltip>
</TooltipProvider>
</Label>
- <Select
- onValueChange={(value) => setSelectedSpace(value)}
- value={selectedSpace ?? "none"}
- defaultValue="none"
- name="space"
- >
- <SelectTrigger className="mt-2">
- <SelectValue placeholder="None" />
- </SelectTrigger>
- <SelectContent className="bg-secondary text-white">
- <SelectItem defaultChecked value="none">
- None
- </SelectItem>
- {spaces.map((space) => (
- <SelectItem key={space.id} value={space.id.toString()}>
- {space.name}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
+
+ <ComboboxWithCreate
+ options={spaces.map((x) => ({
+ label: x.name,
+ value: x.id.toString(),
+ }))}
+ onSelect={(v) =>
+ setSelectedSpaces((prev) => {
+ if (v === "") {
+ return [];
+ }
+ return [...prev, parseInt(v)];
+ })
+ }
+ onSubmit={async (spaceName) => {
+ const space = options.find((x) => x.label === spaceName);
+ toast.info("Creating space...");
+
+ if (space) {
+ toast.error("A space with that name already exists.");
+ }
+
+ const creationTask = await createSpace(spaceName);
+ if (creationTask.success && creationTask.data) {
+ toast.success("Space created " + creationTask.data);
+ setSpaces?.((prev) => [
+ ...prev,
+ {
+ name: spaceName,
+ id: creationTask.data!,
+ },
+ ]);
+ setSelectedSpaces((prev) => [
+ ...prev,
+ creationTask.data!,
+ ]);
+ } else {
+ toast.error(
+ "Space creation failed: " + creationTask.error ??
+ "Unknown error",
+ );
+ }
+ }}
+ placeholder="Save or create space by typing."
+ className="bg-[#2B3237] h-min rounded-md mt-2 mb-4"
+ />
+
+ <div>
+ {selectedSpaces.length > 0 && (
+ <div className="flex flex-row flex-wrap gap-0.5 h-min">
+ {selectedSpaces.map((x, idx) => (
+ <button
+ key={x}
+ onClick={() =>
+ setSelectedSpaces((prev) =>
+ prev.filter((y) => y !== x),
+ )
+ }
+ className={`relative group p-2 py-3 bg-[#3C464D] max-w-32 ${
+ idx === selectedSpaces.length - 1
+ ? "rounded-br-xl"
+ : ""
+ }`}
+ >
+ <p className="line-clamp-1">
+ {spaces.find((y) => y.id === x)?.name}
+ </p>
+ <div className="absolute h-full right-0 top-0 p-1 opacity-0 group-hover:opacity-100 items-center">
+ <MinusIcon className="w-6 h-6 rounded-full bg-secondary" />
+ </div>
+ </button>
+ ))}
+ </div>
+ )}
+ </div>
</div>
)}
diff --git a/apps/web/app/(landing)/page.tsx b/apps/web/app/(landing)/page.tsx
index 4e574ad5..2b36df2a 100644
--- a/apps/web/app/(landing)/page.tsx
+++ b/apps/web/app/(landing)/page.tsx
@@ -9,16 +9,15 @@ import { auth } from "@/server/auth";
import Services from "./Features/index";
import { Showcases } from "./Showcase";
import BackgroundPlus from "./GridPatterns/PlusGrid";
+import { redirect } from "next/navigation";
export const runtime = "edge";
export default async function Home() {
const user = await auth();
- console.log(user);
-
if (user) {
- // await redirect("/home")
+ await redirect("/home");
}
return (
diff --git a/apps/web/app/actions/doers.ts b/apps/web/app/actions/doers.ts
index 95b31392..0c4e98db 100644
--- a/apps/web/app/actions/doers.ts
+++ b/apps/web/app/actions/doers.ts
@@ -41,7 +41,7 @@ export const createSpace = async (
.values({ name: input, user: data.user.id });
revalidatePath("/home");
- return { success: true, data: 1 };
+ return { success: true, data: resp.meta.last_row_id };
} catch (e: unknown) {
const error = e as Error;
if (
diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts
new file mode 100644
index 00000000..b6cc4548
--- /dev/null
+++ b/apps/web/middleware.ts
@@ -0,0 +1,13 @@
+// middleware.js
+import { NextRequest, NextResponse } from "next/server";
+
+export function middleware(request: NextRequest) {
+ const requestHeaders = new Headers(request.headers);
+ requestHeaders.set("x-pathname", request.nextUrl.pathname);
+
+ return NextResponse.next({
+ request: {
+ headers: requestHeaders,
+ },
+ });
+}
diff --git a/packages/ui/shadcn/combobox.tsx b/packages/ui/shadcn/combobox.tsx
index 9eb62cf8..9ab54ef1 100644
--- a/packages/ui/shadcn/combobox.tsx
+++ b/packages/ui/shadcn/combobox.tsx
@@ -21,10 +21,11 @@ interface Option {
interface ComboboxWithCreateProps {
options: Option[];
onSelect: (value: string) => void;
- onSubmit: () => void;
+ onSubmit: (newName: string) => void;
placeholder?: string;
emptyMessage?: string;
createNewMessage?: string;
+ className?: string;
}
const ComboboxWithCreate: React.FC<ComboboxWithCreateProps> = ({
@@ -34,9 +35,8 @@ const ComboboxWithCreate: React.FC<ComboboxWithCreateProps> = ({
placeholder = "Select an option",
emptyMessage = "No option found.",
createNewMessage = "Create",
+ className,
}) => {
- const [open, setOpen] = useState(false);
- const [value, setValue] = useState("");
const [options, setOptions] = useState<Option[]>(initialOptions);
const [inputValue, setInputValue] = useState("");
@@ -45,7 +45,7 @@ const ComboboxWithCreate: React.FC<ComboboxWithCreateProps> = ({
}, [initialOptions]);
return (
- <Command className="w-40 group">
+ <Command className={cn("group", className)}>
<CommandInput
onChangeCapture={(e) => setInputValue(e.currentTarget.value)}
placeholder={placeholder}
@@ -53,7 +53,9 @@ const ComboboxWithCreate: React.FC<ComboboxWithCreateProps> = ({
/>
<CommandList className="z-10 translate-y-12 translate-x-5 opacity-0 absolute group-focus-within:opacity-100 bg-secondary p-2 rounded-b-xl max-w-64">
<CommandEmpty>
- {createNewMessage} "{inputValue}"
+ <Button onClick={async () => onSubmit(inputValue)} variant="link">
+ {createNewMessage} "{inputValue}"
+ </Button>
</CommandEmpty>
<CommandGroup
className="hidden group-focus-within:block"
diff --git a/packages/ui/shadcn/command.tsx b/packages/ui/shadcn/command.tsx
index 802dfb11..dfc54283 100644
--- a/packages/ui/shadcn/command.tsx
+++ b/packages/ui/shadcn/command.tsx
@@ -14,10 +14,7 @@ const Command = React.forwardRef<
>(({ className, ...props }, ref) => (
<CommandPrimitive
ref={ref}
- className={cn(
- "flex h-full w-full flex-col overflow-hidden rounded-bl-3xl bg-[#3C464D]",
- className,
- )}
+ className={cn("flex h-full w-full flex-col overflow-hidden", className)}
{...props}
/>
));