fixed new chat button showing up on all pages

This commit is contained in:
Dhravya 2024-06-29 02:10:13 -05:00
parent 3754b2c2c8
commit 9272d87e5f
14 changed files with 188 additions and 54 deletions

View file

@ -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;
}

View file

@ -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">

View file

@ -412,7 +412,7 @@ function ChatWindow({
mini
className="w-full shadow-md"
initialQuery={""}
initialSpaces={[]}
initialSpaces={spaces}
handleSubmit={async (q, spaces) => {
setChatHistory((prevChatHistory) => {
return [

View file

@ -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">

View file

@ -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;

View file

@ -74,6 +74,7 @@ function Page({
);
}}
initialSpaces={spaces}
setInitialSpaces={setSpaces}
/>
</div>
</div>

View file

@ -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">

View file

@ -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";

View file

@ -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>
)}

View file

@ -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 (

View file

@ -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 (

13
apps/web/middleware.ts Normal file
View file

@ -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,
},
});
}

View file

@ -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"

View file

@ -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}
/>
));