aboutsummaryrefslogtreecommitdiff
path: root/apps/web/app/(dash)
diff options
context:
space:
mode:
authorDhravya <[email protected]>2024-06-14 23:35:19 -0500
committerDhravya <[email protected]>2024-06-14 23:35:19 -0500
commit9f0fb14d56fcbd9280aee2bdd83d55e8fabbe7d2 (patch)
tree372de593c837b0a963c081a1db58447ac4e08084 /apps/web/app/(dash)
parentMerge branch 'codetorso' of https://github.com/Dhravya/supermemory into codet... (diff)
downloadsupermemory-9f0fb14d56fcbd9280aee2bdd83d55e8fabbe7d2.tar.xz
supermemory-9f0fb14d56fcbd9280aee2bdd83d55e8fabbe7d2.zip
[MIGRATION REQUIRED]Data fetchers and other server actions, spaces creation and database migrations
Diffstat (limited to 'apps/web/app/(dash)')
-rw-r--r--apps/web/app/(dash)/actions.ts48
-rw-r--r--apps/web/app/(dash)/dynamicisland.tsx109
-rw-r--r--apps/web/app/(dash)/home/page.tsx11
-rw-r--r--apps/web/app/(dash)/home/queryinput.tsx21
-rw-r--r--apps/web/app/(dash)/layout.tsx7
5 files changed, 116 insertions, 80 deletions
diff --git a/apps/web/app/(dash)/actions.ts b/apps/web/app/(dash)/actions.ts
deleted file mode 100644
index 70c2a567..00000000
--- a/apps/web/app/(dash)/actions.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-"use server";
-
-import { cookies, headers } from "next/headers";
-import { db } from "../helpers/server/db";
-import { sessions, users, space } from "../helpers/server/db/schema";
-import { eq } from "drizzle-orm";
-import { redirect } from "next/navigation";
-
-export async function ensureAuth() {
- const token =
- cookies().get("next-auth.session-token")?.value ??
- cookies().get("__Secure-authjs.session-token")?.value ??
- cookies().get("authjs.session-token")?.value ??
- headers().get("Authorization")?.replace("Bearer ", "");
-
- if (!token) {
- return undefined;
- }
-
- const sessionData = await db
- .select()
- .from(sessions)
- .innerJoin(users, eq(users.id, sessions.userId))
- .where(eq(sessions.sessionToken, token));
-
- if (!sessionData || sessionData.length < 0) {
- return undefined;
- }
-
- return {
- user: sessionData[0]!.user,
- session: sessionData[0]!,
- };
-}
-
-export async function getSpaces() {
- const data = await ensureAuth();
- if (!data) {
- redirect("/signin");
- }
-
- const sp = await db
- .select()
- .from(space)
- .where(eq(space.user, data.user.email));
-
- return sp;
-}
diff --git a/apps/web/app/(dash)/dynamicisland.tsx b/apps/web/app/(dash)/dynamicisland.tsx
index b703d55a..31f76fda 100644
--- a/apps/web/app/(dash)/dynamicisland.tsx
+++ b/apps/web/app/(dash)/dynamicisland.tsx
@@ -9,6 +9,17 @@ import { motion } from "framer-motion";
import { Label } from "@repo/ui/shadcn/label";
import { Input } from "@repo/ui/shadcn/input";
import { Textarea } from "@repo/ui/shadcn/textarea";
+import { createSpace } from "../actions/doers";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@repo/ui/shadcn/select";
+import { Space } from "../actions/types";
+import { getSpaces } from "../actions/fetchers";
+import { toast } from "sonner";
export function DynamicIsland() {
const { scrollYProgress } = useScroll();
@@ -80,7 +91,7 @@ function DynamicIslandContent() {
{show ? (
<div
onClick={() => setshow(!show)}
- className="bg-[#1F2428] px-3 w-[2.23rem] overflow-hidden hover:w-[9.2rem] whitespace-nowrap py-2 rounded-3xl transition-[width] cursor-pointer"
+ className="bg-secondary px-3 w-[2.23rem] overflow-hidden hover:w-[9.2rem] whitespace-nowrap py-2 rounded-3xl transition-[width] cursor-pointer"
>
<div className="flex gap-4 items-center">
<Image src={AddIcon} alt="Add icon" />
@@ -99,7 +110,25 @@ function DynamicIslandContent() {
const fakeitems = ["spaces", "page", "note"];
function ToolBar({ cancelfn }: { cancelfn: () => void }) {
+ const [spaces, setSpaces] = useState<Space[]>([]);
+
const [index, setIndex] = useState(0);
+
+ useEffect(() => {
+ (async () => {
+ let spaces = await getSpaces();
+
+ if (!spaces.success || !spaces.data) {
+ toast.warning("Unable to get spaces", {
+ richColors: true,
+ });
+ setSpaces([]);
+ return;
+ }
+ setSpaces(spaces.data);
+ })();
+ }, []);
+
return (
<AnimatePresence mode="wait">
<motion.div
@@ -120,7 +149,7 @@ function ToolBar({ cancelfn }: { cancelfn: () => void }) {
}}
className="flex flex-col items-center"
>
- <div className="bg-[#1F2428] py-[.35rem] px-[.6rem] rounded-2xl">
+ <div className="bg-secondary py-[.35rem] px-[.6rem] rounded-2xl">
<HoverEffect
items={fakeitems}
index={index}
@@ -130,9 +159,9 @@ function ToolBar({ cancelfn }: { cancelfn: () => void }) {
{index === 0 ? (
<SpaceForm cancelfn={cancelfn} />
) : index === 1 ? (
- <PageForm cancelfn={cancelfn} />
+ <PageForm cancelfn={cancelfn} spaces={spaces} />
) : (
- <NoteForm cancelfn={cancelfn} />
+ <NoteForm cancelfn={cancelfn} spaces={spaces} />
)}
</motion.div>
</AnimatePresence>
@@ -182,7 +211,10 @@ export const HoverEffect = ({
function SpaceForm({ cancelfn }: { cancelfn: () => void }) {
return (
- <div className="bg-[#1F2428] px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3">
+ <form
+ action={createSpace}
+ className="bg-secondary border border-muted-foreground px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3"
+ >
<div>
<Label className="text-[#858B92]" htmlFor="name">
Name
@@ -190,34 +222,55 @@ function SpaceForm({ cancelfn }: { cancelfn: () => void }) {
<Input
className="bg-[#2B3237] focus-visible:ring-0 border-none focus-visible:ring-offset-0"
id="name"
+ name="name"
/>
</div>
<div className="flex justify-between">
<a className="text-blue-500" href="">
pull from store
</a>
- <div
+ {/* <div
onClick={cancelfn}
className="bg-[#2B3237] px-2 py-1 rounded-xl cursor-pointer"
>
cancel
- </div>
+ </div> */}
+ <button
+ type="submit"
+ className="bg-[#2B3237] px-2 py-1 rounded-xl cursor-pointer"
+ >
+ Submit
+ </button>
</div>
- </div>
+ </form>
);
}
-function PageForm({ cancelfn }: { cancelfn: () => void }) {
+function PageForm({
+ cancelfn,
+ spaces,
+}: {
+ cancelfn: () => void;
+ spaces: Space[];
+}) {
return (
- <div className="bg-[#1F2428] px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3">
+ <div className="bg-secondary border border-muted-foreground px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3">
<div>
- <Label className="text-[#858B92]" htmlFor="name">
+ <Label className="text-[#858B92]" htmlFor="space">
Space
</Label>
- <Input
- className="bg-[#2B3237] focus-visible:ring-0 border-none focus-visible:ring-offset-0"
- id="name"
- />
+ <Select>
+ <SelectTrigger>
+ <SelectValue placeholder="Space" />
+ </SelectTrigger>
+ <SelectContent className="bg-secondary text-white">
+ {spaces.map((space) => (
+ <SelectItem key={space.id} value={space.id.toString()}>
+ {space.name}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
</div>
<div>
<Label className="text-[#858B92]" htmlFor="name">
@@ -240,17 +293,31 @@ function PageForm({ cancelfn }: { cancelfn: () => void }) {
);
}
-function NoteForm({ cancelfn }: { cancelfn: () => void }) {
+function NoteForm({
+ cancelfn,
+ spaces,
+}: {
+ cancelfn: () => void;
+ spaces: Space[];
+}) {
return (
- <div className="bg-[#1F2428] px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3">
+ <div className="bg-secondary border border-muted-foreground px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3">
<div>
<Label className="text-[#858B92]" htmlFor="name">
Space
</Label>
- <Input
- className="bg-[#2B3237] focus-visible:ring-0 border-none focus-visible:ring-offset-0"
- id="name"
- />
+ <Select>
+ <SelectTrigger>
+ <SelectValue placeholder="Space" />
+ </SelectTrigger>
+ <SelectContent className="bg-secondary text-white">
+ {spaces.map((space) => (
+ <SelectItem key={space.id} value={space.id.toString()}>
+ {space.name}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
</div>
<div>
<Label className="text-[#858B92]" htmlFor="name">
diff --git a/apps/web/app/(dash)/home/page.tsx b/apps/web/app/(dash)/home/page.tsx
index 0c75e457..b4bafb38 100644
--- a/apps/web/app/(dash)/home/page.tsx
+++ b/apps/web/app/(dash)/home/page.tsx
@@ -3,7 +3,7 @@ import Menu from "../menu";
import Header from "../header";
import QueryInput from "./queryinput";
import { homeSearchParamsCache } from "@/app/helpers/lib/searchParams";
-import { getSpaces } from "../actions";
+import { getSpaces } from "@/app/actions/fetchers";
async function Page({
searchParams,
@@ -13,7 +13,12 @@ async function Page({
// TODO: use this to show a welcome page/modal
const { firstTime } = homeSearchParamsCache.parse(searchParams);
- const spaces = await getSpaces();
+ let spaces = await getSpaces();
+
+ if (!spaces.success) {
+ // TODO: handle this error properly.
+ spaces.data = [];
+ }
return (
<div className="max-w-3xl h-full justify-center flex mx-auto w-full flex-col">
@@ -21,7 +26,7 @@ async function Page({
{/* <div className="">hi {firstTime ? 'first time' : ''}</div> */}
<div className="w-full h-96">
- <QueryInput initialSpaces={spaces} />
+ <QueryInput initialSpaces={spaces.data} />
</div>
</div>
);
diff --git a/apps/web/app/(dash)/home/queryinput.tsx b/apps/web/app/(dash)/home/queryinput.tsx
index 4cb1fdb2..d0c27b8d 100644
--- a/apps/web/app/(dash)/home/queryinput.tsx
+++ b/apps/web/app/(dash)/home/queryinput.tsx
@@ -2,10 +2,11 @@
import { ArrowRightIcon } from "@repo/ui/icons";
import Image from "next/image";
-import React, { useState } from "react";
+import React, { useEffect, useMemo, useState } from "react";
import Divider from "@repo/ui/shadcn/divider";
import { MultipleSelector, Option } from "@repo/ui/shadcn/combobox";
import { useRouter } from "next/navigation";
+import { getSpaces } from "@/app/actions/fetchers";
function QueryInput({
initialQuery = "",
@@ -13,7 +14,10 @@ function QueryInput({
disabled = false,
}: {
initialQuery?: string;
- initialSpaces?: { user: string | null; id: number; name: string }[];
+ initialSpaces?: {
+ id: number;
+ name: string;
+ }[];
disabled?: boolean;
}) {
const [q, setQ] = useState(initialQuery);
@@ -41,10 +45,14 @@ function QueryInput({
return newQ;
};
- const options = initialSpaces.map((x) => ({
- label: x.name,
- value: x.id.toString(),
- }));
+ const options = useMemo(
+ () =>
+ initialSpaces.map((x) => ({
+ label: x.name,
+ value: x.id.toString(),
+ })),
+ [initialSpaces],
+ );
return (
<div>
@@ -82,6 +90,7 @@ function QueryInput({
{/* selected sources */}
<div className="flex items-center gap-6 p-2 h-auto bg-secondary rounded-b-[24px]">
<MultipleSelector
+ key={options.length}
disabled={disabled}
defaultOptions={options}
onChange={(e) => setSelectedSpaces(e.map((x) => parseInt(x.value)))}
diff --git a/apps/web/app/(dash)/layout.tsx b/apps/web/app/(dash)/layout.tsx
index 85f8476e..b879a2f5 100644
--- a/apps/web/app/(dash)/layout.tsx
+++ b/apps/web/app/(dash)/layout.tsx
@@ -1,10 +1,11 @@
import Header from "./header";
import Menu from "./menu";
-import { ensureAuth } from "./actions";
import { redirect } from "next/navigation";
+import { auth } from "../helpers/server/auth";
+import { Toaster } from "@repo/ui/shadcn/sonner";
async function Layout({ children }: { children: React.ReactNode }) {
- const info = await ensureAuth();
+ const info = await auth();
if (!info) {
return redirect("/signin");
@@ -17,6 +18,8 @@ async function Layout({ children }: { children: React.ReactNode }) {
<Menu />
{children}
+
+ <Toaster />
</main>
);
}