diff options
| author | codetorso <[email protected]> | 2024-06-08 06:25:25 +0530 |
|---|---|---|
| committer | codetorso <[email protected]> | 2024-06-08 06:25:25 +0530 |
| commit | 004c952dc323ef481ae0b1532bab78b244841dbc (patch) | |
| tree | 07973184e11daeae0d3fd0663fd01cdbf499a8ce /apps/web | |
| parent | added top bar nav (diff) | |
| download | supermemory-004c952dc323ef481ae0b1532bab78b244841dbc.tar.xz supermemory-004c952dc323ef481ae0b1532bab78b244841dbc.zip | |
Add Dynamic Island
Diffstat (limited to 'apps/web')
| -rw-r--r-- | apps/web/app/(dash)/dynamicisland.tsx | 194 | ||||
| -rw-r--r-- | apps/web/app/(dash)/header.tsx | 40 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/page.tsx | 2 | ||||
| -rw-r--r-- | apps/web/app/(dash)/home/queryinput.tsx | 2 | ||||
| -rw-r--r-- | apps/web/app/(dash)/menu.tsx | 2 |
5 files changed, 205 insertions, 35 deletions
diff --git a/apps/web/app/(dash)/dynamicisland.tsx b/apps/web/app/(dash)/dynamicisland.tsx new file mode 100644 index 00000000..a30ec8cf --- /dev/null +++ b/apps/web/app/(dash)/dynamicisland.tsx @@ -0,0 +1,194 @@ +"use client"; + +import { AddIcon } from "@repo/ui/icons"; +import Image from "next/image"; + +import { AnimatePresence, useMotionValueEvent, useScroll } from "framer-motion"; +import { useState } from "react"; +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"; + +export function DynamicIsland() { + const { scrollYProgress } = useScroll(); + const [visible, setVisible] = useState(true); + + useMotionValueEvent(scrollYProgress, "change", (current) => { + // Check if current is not undefined and is a number + if (typeof current === "number") { + let direction = current! - scrollYProgress.getPrevious()!; + + if (direction < 0 || direction === 1) { + setVisible(true); + } else { + setVisible(false); + } + } + }); + + return ( + <div className="fixed z-40 left-1/2 -translate-x-1/2 top-12"> + <AnimatePresence mode="wait"> + <motion.div + initial={{ + opacity: 1, + y: -150, + }} + animate={{ + y: visible ? 0 : -150, + opacity: visible ? 1 : 0, + }} + transition={{ + duration: 0.2, + }} + className="flex flex-col items-center" + > + <DynamicIslandContent /> + </motion.div> + </AnimatePresence> + </div> + ); +} + +export default DynamicIsland; + +function DynamicIslandContent() { + const [show, setshow] = useState(true); + function cancelfn(){ + setshow(true); + } + return ( + <> + {show ? ( + <div + onClick={() => setshow(!show)} + className="bg-[#1F2428] p-2 rounded-3xl" + > + <Image src={AddIcon} alt="Add icon" /> + </div> + ) : ( + <div> + <ToolBar cancelfn={cancelfn} /> + </div> + )} + </> + ); +} + +const fakeitems = ["spaces", "page", "note"]; + +function ToolBar({cancelfn}: {cancelfn: ()=> void}) { + const [index, setIndex] = useState(0); + return ( + <div className="flex flex-col items-center"> + <div className="bg-[#1F2428] py-[.35rem] px-[.6rem] rounded-2xl"> + <HoverEffect + items={fakeitems} + index={index} + indexFn={(i) => setIndex(i)} + /> + </div> + { index === 0 ? + <SpaceForm cancelfn={cancelfn} /> : + index === 1 ? + <PageForm cancelfn={cancelfn} /> : + <NoteForm cancelfn={cancelfn} /> + } + </div> + ); +} + +export const HoverEffect = ({ + items, + index, + indexFn, +}: { + items: string[]; + index: number; + indexFn: (i: number) => void; +}) => { + return ( + <div className={"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}> + {items.map((item, idx) => ( + <button + key={idx} + className="relative block h-full w-full px-2 py-1" + onClick={() => indexFn(idx)} + > + <AnimatePresence> + {index === idx && ( + <motion.span + className="absolute inset-0 block h-full w-full rounded-xl bg-[#2B3237]" + layoutId="hoverBackground" + initial={{ opacity: 0 }} + animate={{ + opacity: 1, + transition: { duration: 0.15 }, + }} + exit={{ + opacity: 0, + transition: { duration: 0.15, delay: 0.2 }, + }} + /> + )} + </AnimatePresence> + <h3 className="text-[#858B92] z-50 relative">{item}</h3> + </button> + ))} + </div> + ); +}; + +function SpaceForm({cancelfn}: {cancelfn: ()=> void}) { + return ( + <div className="bg-[#1F2428] px-4 py-3 rounded-2xl mt-2 flex flex-col gap-3"> + <div > + <Label className="text-[#858B92]" htmlFor="name">Name</Label> + <Input className="bg-[#2B3237] outline-none border-none focus:border-none focus:outline-none" id="name"/> + </div> + <div className="flex justify-between"> + <a className="text-blue-500" href=""> + pull from store + </a> + <div onClick={cancelfn} className="bg-[#2B3237] px-2 py-1 rounded-xl cursor-pointer">cancel</div> + </div> + </div> + ); +} + +function PageForm({cancelfn}: {cancelfn: ()=> void}) { + return ( + <div className="bg-[#1F2428] 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] outline-none border-none focus:border-none focus:outline-none" id="name"/> + </div> + <div > + <Label className="text-[#858B92]" htmlFor="name">Page Url</Label> + <Input className="bg-[#2B3237] outline-none border-none focus:border-none focus:outline-none" id="name"/> + </div> + <div className="flex justify-end"> + <div onClick={cancelfn} className="bg-[#2B3237] px-2 py-1 rounded-xl cursor-pointer">cancel</div> + </div> + </div> + ); +} + +function NoteForm({cancelfn}: {cancelfn: ()=> void}) { + return ( + <div className="bg-[#1F2428] 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] outline-none border-none focus:border-none focus:outline-none" id="name"/> + </div> + <div > + <Label className="text-[#858B92]" htmlFor="name">Note</Label> + <Textarea cols={4} className="bg-[#2B3237] outline-none border-none resize-none" id="name"/> + </div> + <div className="flex justify-end"> + <div onClick={cancelfn} className="bg-[#2B3237] px-2 py-1 rounded-xl cursor-pointer">cancel</div> + </div> + </div> + ); +}
\ No newline at end of file diff --git a/apps/web/app/(dash)/header.tsx b/apps/web/app/(dash)/header.tsx index 104c63bc..c5aeca3b 100644 --- a/apps/web/app/(dash)/header.tsx +++ b/apps/web/app/(dash)/header.tsx @@ -2,49 +2,25 @@ 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 { Tabs, TabsContent, TabsList, TabsTrigger } from "@repo/ui/shadcn/tabs"; +import { ChatIcon } from "@repo/ui/icons"; + +import DynamicIsland from "./dynamicisland"; function Header() { return ( <div> - <div className="flex items-center justify-between relative z-10"> - <Link href="/"> + <div className="absolute left-0 w-full flex items-center justify-between z-10"> + <Link className="px-5" href="/home"> <Image src={Logo} alt="SuperMemory logo" - className="hover:brightness-125 duration-200" + className="hover:brightness-75 brightness-50 duration-200" /> </Link> - <Tabs - className="absolute flex flex-col justify-center items-center w-full -z-10 group top-0 transition-transform duration-1000 ease-out" - defaultValue="account" - > - <div className="bg-secondary all-center h-11 rounded-full p-2 min-w-14"> - <button className="p-2 group-hover:hidden transition duration-500 ease-in-out"> - <Image src={AddIcon} alt="Add icon" /> - </button> - - <div className="hidden group-hover:flex inset-0 transition-opacity duration-500 ease-in-out"> - <TabsList className="p-2"> - <TabsTrigger value="account">Account</TabsTrigger> - <TabsTrigger value="password">Password</TabsTrigger> - </TabsList> - </div> - </div> - - <div className="bg-secondary all-center rounded-full p-2 mt-4 min-w-14 hidden group-hover:block"> - <TabsContent value="account"> - Make changes to your account here. - </TabsContent> - <TabsContent value="password"> - Change your password here. - </TabsContent> - </div> - </Tabs> + <DynamicIsland /> - <button className="flex shrink-0 duration-200 items-center gap-2 px-2 py-1.5 rounded-xl hover:bg-secondary"> + <button className="flex shrink-0 duration-200 items-center gap-2 px-5 py-1.5 rounded-xl hover:bg-secondary"> <Image src={ChatIcon} alt="Chat icon" /> Start new chat </button> diff --git a/apps/web/app/(dash)/home/page.tsx b/apps/web/app/(dash)/home/page.tsx index 7a6bb94f..0c75e457 100644 --- a/apps/web/app/(dash)/home/page.tsx +++ b/apps/web/app/(dash)/home/page.tsx @@ -16,7 +16,7 @@ async function Page({ const spaces = await getSpaces(); return ( - <div className="max-w-3xl flex mx-auto w-full flex-col"> + <div className="max-w-3xl h-full justify-center flex mx-auto w-full flex-col"> {/* all content goes here */} {/* <div className="">hi {firstTime ? 'first time' : ''}</div> */} diff --git a/apps/web/app/(dash)/home/queryinput.tsx b/apps/web/app/(dash)/home/queryinput.tsx index d098fda8..4cb1fdb2 100644 --- a/apps/web/app/(dash)/home/queryinput.tsx +++ b/apps/web/app/(dash)/home/queryinput.tsx @@ -48,7 +48,7 @@ function QueryInput({ return ( <div> - <div className="bg-secondary rounded-t-[24px] w-full mt-40"> + <div className="bg-secondary rounded-t-[24px]"> {/* input and action button */} <form action={async () => push(parseQ())} className="flex gap-4 p-3"> <textarea diff --git a/apps/web/app/(dash)/menu.tsx b/apps/web/app/(dash)/menu.tsx index 1177bca6..fad4a036 100644 --- a/apps/web/app/(dash)/menu.tsx +++ b/apps/web/app/(dash)/menu.tsx @@ -24,7 +24,7 @@ function Menu() { return ( <div className="absolute h-full p-4 flex items-center top-0 left-0"> <div className=""> - <div className="hover:rounded-2x group inline-flex w-14 text-foreground-menu text-[15px] font-medium flex-col items-start gap-6 overflow-hidden rounded-[28px] bg-secondary px-3 py-4 duration-200 hover:w-40"> + <div className="group inline-flex w-14 text-foreground-menu text-[15px] font-medium flex-col items-start gap-6 overflow-hidden rounded-[28px] bg-secondary px-3 py-4 duration-200 hover:w-40"> {menuItems.map((item) => ( <div key={item.url} |