diff options
| author | Dhravya <[email protected]> | 2024-06-14 23:35:19 -0500 |
|---|---|---|
| committer | Dhravya <[email protected]> | 2024-06-14 23:35:19 -0500 |
| commit | 9f0fb14d56fcbd9280aee2bdd83d55e8fabbe7d2 (patch) | |
| tree | 372de593c837b0a963c081a1db58447ac4e08084 /apps/web/app/(dash) | |
| parent | Merge branch 'codetorso' of https://github.com/Dhravya/supermemory into codet... (diff) | |
| download | supermemory-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.ts | 48 | ||||
| -rw-r--r-- | apps/web/app/(dash)/dynamicisland.tsx | 109 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/page.tsx | 11 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/queryinput.tsx | 21 | ||||
| -rw-r--r-- | apps/web/app/(dash)/layout.tsx | 7 |
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> ); } |