From 9272d87e5f46aeaf1aea0927d47cf3dd69507867 Mon Sep 17 00:00:00 2001 From: Dhravya Date: Sat, 29 Jun 2024 02:10:13 -0500 Subject: [PATCH] fixed new chat button showing up on all pages --- apps/cf-ai-backend/src/index.ts | 4 - apps/web/app/(auth)/signin/page.tsx | 8 +- apps/web/app/(dash)/chat/chatWindow.tsx | 2 +- apps/web/app/(dash)/{ => header}/header.tsx | 12 +- apps/web/app/(dash)/header/newChatButton.tsx | 27 +++++ apps/web/app/(dash)/home/page.tsx | 1 + apps/web/app/(dash)/home/queryinput.tsx | 36 +++++- apps/web/app/(dash)/layout.tsx | 2 +- apps/web/app/(dash)/menu.tsx | 113 +++++++++++++++---- apps/web/app/(landing)/page.tsx | 5 +- apps/web/app/actions/doers.ts | 2 +- apps/web/middleware.ts | 13 +++ packages/ui/shadcn/combobox.tsx | 12 +- packages/ui/shadcn/command.tsx | 5 +- 14 files changed, 188 insertions(+), 54 deletions(-) rename apps/web/app/(dash)/{ => header}/header.tsx (78%) create mode 100644 apps/web/app/(dash)/header/newChatButton.tsx create mode 100644 apps/web/middleware.ts 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 (
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 similarity index 78% rename from apps/web/app/(dash)/header.tsx rename to 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() {
- +
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({
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..." />
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([]); @@ -77,7 +78,7 @@ function Menu() { ]; const [content, setContent] = useState(""); - const [selectedSpace, setSelectedSpace] = useState(null); + const [selectedSpaces, setSelectedSpaces] = useState([]); 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 @@ -227,26 +237,81 @@ function Menu() { - + + ({ + 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" + /> + +
+ {selectedSpaces.length > 0 && ( +
+ {selectedSpaces.map((x, idx) => ( + + ))} +
+ )} +
)} 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 = ({ @@ -34,9 +35,8 @@ const ComboboxWithCreate: React.FC = ({ placeholder = "Select an option", emptyMessage = "No option found.", createNewMessage = "Create", + className, }) => { - const [open, setOpen] = useState(false); - const [value, setValue] = useState(""); const [options, setOptions] = useState(initialOptions); const [inputValue, setInputValue] = useState(""); @@ -45,7 +45,7 @@ const ComboboxWithCreate: React.FC = ({ }, [initialOptions]); return ( - + setInputValue(e.currentTarget.value)} placeholder={placeholder} @@ -53,7 +53,9 @@ const ComboboxWithCreate: React.FC = ({ /> - {createNewMessage} "{inputValue}" + (({ className, ...props }, ref) => ( ));