diff options
| author | Yash <[email protected]> | 2024-04-11 04:52:44 +0000 |
|---|---|---|
| committer | Yash <[email protected]> | 2024-04-11 04:52:44 +0000 |
| commit | 6dcc7d18c9be5e3a5e0a3ff60668424ee0158b4e (patch) | |
| tree | 179aa936536510cc707368fc7c330c4c7fbdc3f8 /apps/web/src/components/Sidebar | |
| parent | novel editor (diff) | |
| parent | save user ID with url to ensure that same website can be saved by users (diff) | |
| download | supermemory-6dcc7d18c9be5e3a5e0a3ff60668424ee0158b4e.tar.xz supermemory-6dcc7d18c9be5e3a5e0a3ff60668424ee0158b4e.zip | |
Merge branch 'main' of https://github.com/Dhravya/supermemory into new-uinew-ui
Diffstat (limited to 'apps/web/src/components/Sidebar')
| -rw-r--r-- | apps/web/src/components/Sidebar/CategoryItem.tsx | 138 | ||||
| -rw-r--r-- | apps/web/src/components/Sidebar/FilterCombobox.tsx | 36 | ||||
| -rw-r--r-- | apps/web/src/components/Sidebar/index.tsx | 63 |
3 files changed, 127 insertions, 110 deletions
diff --git a/apps/web/src/components/Sidebar/CategoryItem.tsx b/apps/web/src/components/Sidebar/CategoryItem.tsx index 0cf8a70c..7fb571b5 100644 --- a/apps/web/src/components/Sidebar/CategoryItem.tsx +++ b/apps/web/src/components/Sidebar/CategoryItem.tsx @@ -1,13 +1,13 @@ -'use client'; -import { cleanUrl } from '@/lib/utils'; -import { StoredContent } from '@/server/db/schema'; +"use client"; +import { cleanUrl } from "@/lib/utils"; +import { StoredContent } from "@/server/db/schema"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, -} from '../ui/dropdown-menu'; -import { Label } from '../ui/label'; +} from "../ui/dropdown-menu"; +import { Label } from "../ui/label"; import { ArrowUpRight, MoreHorizontal, @@ -19,8 +19,8 @@ import { ChevronRight, Plus, Minus, -} from 'lucide-react'; -import { useState } from 'react'; +} from "lucide-react"; +import { useState } from "react"; import { Drawer, DrawerContent, @@ -29,106 +29,106 @@ import { DrawerDescription, DrawerFooter, DrawerClose, -} from '../ui/drawer'; -import { Input } from '../ui/input'; -import { Textarea } from '../ui/textarea'; -import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; +} from "../ui/drawer"; +import { Input } from "../ui/input"; +import { Textarea } from "../ui/textarea"; +import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { AnimatePresence, motion, Reorder, useMotionValue, -} from 'framer-motion'; +} from "framer-motion"; const pages: StoredContent[] = [ { id: 1, - content: '', - title: 'Visual Studio Code', - url: 'https://code.visualstudio.com', - description: '', - image: 'https://code.visualstudio.com/favicon.ico', - baseUrl: 'https://code.visualstudio.com', + content: "", + title: "Visual Studio Code", + url: "https://code.visualstudio.com", + description: "", + image: "https://code.visualstudio.com/favicon.ico", + baseUrl: "https://code.visualstudio.com", savedAt: new Date(), }, { id: 2, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 3, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 4, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 5, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 6, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 7, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 8, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, { id: 9, - content: '', + content: "", title: "yxshv/vscode: An unofficial remake of vscode's landing page", - url: 'https://github.com/yxshv/vscode', - description: '', - image: 'https://github.com/favicon.ico', - baseUrl: 'https://github.com', + url: "https://github.com/yxshv/vscode", + description: "", + image: "https://github.com/favicon.ico", + baseUrl: "https://github.com", savedAt: new Date(), }, ]; @@ -153,13 +153,13 @@ export const CategoryItem: React.FC<{ item: StoredContent }> = ({ item }) => { /> <ChevronDown data-down-icon - className={`absolute left-1/2 top-1/2 z-[2] h-4 w-4 min-w-4 -translate-x-1/2 -translate-y-1/2 scale-75 opacity-0 transition-[transform,opacity] duration-150 ${isExpanded ? 'rotate-180' : 'rotate-0'}`} + className={`absolute left-1/2 top-1/2 z-[2] h-4 w-4 min-w-4 -translate-x-1/2 -translate-y-1/2 scale-75 opacity-0 transition-[transform,opacity] duration-150 ${isExpanded ? "rotate-180" : "rotate-0"}`} strokeWidth={1.5} /> </div> <span className="w-full truncate text-nowrap text-left"> - {item.title ?? 'Untitled website'} + {item.title ?? "Untitled website"} </span> </button> <Drawer @@ -178,7 +178,7 @@ export const CategoryItem: React.FC<{ item: StoredContent }> = ({ item }) => { href={item.url} className="text-rgray-11/90 bg-rgray-3 text-md absolute right-0 top-0 flex w-min translate-y-1/2 items-center justify-center gap-1 rounded-full px-5 py-1" > - <img src={item.image ?? '/brain.png'} className="h-4 w-4" /> + <img src={item.image ?? "/brain.png"} className="h-4 w-4" /> {cleanUrl(item.url)} </a> </DrawerHeader> @@ -188,16 +188,16 @@ export const CategoryItem: React.FC<{ item: StoredContent }> = ({ item }) => { <Input className="" required - value={item.title ?? ''} - placeholder={item.title ?? 'Enter the title for the page'} + value={item.title ?? ""} + placeholder={item.title ?? "Enter the title for the page"} /> </div> <div className="mt-5"> <Label>Additional Context</Label> <Textarea className="" - value={item.content ?? ''} - placeholder={'Enter additional context for this page'} + value={item.content ?? ""} + placeholder={"Enter additional context for this page"} /> </div> <DrawerFooter className="flex flex-row-reverse items-center justify-end px-0 pt-5"> @@ -224,7 +224,7 @@ export const CategoryItem: React.FC<{ item: StoredContent }> = ({ item }) => { onReorder={setItems} as="div" initial={{ height: 0 }} - animate={{ height: 'auto' }} + animate={{ height: "auto" }} exit={{ height: 0, transition: {}, @@ -272,8 +272,8 @@ export const CategoryPage: React.FC<{ > <div className="relative h-4 min-w-4"> <img - src={item.image ?? '/brain.png'} - alt={item.title ?? 'Untitiled website'} + src={item.image ?? "/brain.png"} + alt={item.title ?? "Untitiled website"} className="z-1 h-4 w-4 transition-[transform,opacity] delay-150 duration-150" /> <ArrowUpRight @@ -284,7 +284,7 @@ export const CategoryPage: React.FC<{ </div> <span className="w-full truncate text-nowrap"> - {item.title ?? 'Untitled website'} + {item.title ?? "Untitled website"} </span> </a> <button diff --git a/apps/web/src/components/Sidebar/FilterCombobox.tsx b/apps/web/src/components/Sidebar/FilterCombobox.tsx index 76b66db9..a8e3a1e5 100644 --- a/apps/web/src/components/Sidebar/FilterCombobox.tsx +++ b/apps/web/src/components/Sidebar/FilterCombobox.tsx @@ -1,10 +1,10 @@ -'use client'; +"use client"; -import * as React from 'react'; -import { Check, ChevronsUpDown } from 'lucide-react'; +import * as React from "react"; +import { Check, ChevronsUpDown } from "lucide-react"; -import { cn } from '@/lib/utils'; -import { Button } from '@/components/ui/button'; +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, @@ -12,28 +12,30 @@ import { CommandInput, CommandItem, CommandList, -} from '@/components/ui/command'; +} from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, -} from '@/components/ui/popover'; -import { SpaceIcon } from '@/assets/Memories'; -import { AnimatePresence, LayoutGroup, motion } from 'framer-motion'; -import { useMemory } from '@/contexts/MemoryContext'; +} from "@/components/ui/popover"; +import { SpaceIcon } from "@/assets/Memories"; +import { AnimatePresence, LayoutGroup, motion } from "framer-motion"; +import { useMemory } from "@/contexts/MemoryContext"; export interface Props extends React.ButtonHTMLAttributes<HTMLButtonElement> { - side?: 'top' | 'bottom'; - align?: 'end' | 'start' | 'center'; + side?: "top" | "bottom"; + align?: "end" | "start" | "center"; onClose?: () => void; selectedSpaces: number[]; - setSelectedSpaces: (spaces: number[] | ((prev: number[]) => number[])) => void; + setSelectedSpaces: ( + spaces: number[] | ((prev: number[]) => number[]), + ) => void; } export function FilterCombobox({ className, - side = 'bottom', - align = 'center', + side = "bottom", + align = "center", onClose, selectedSpaces, setSelectedSpaces, @@ -65,7 +67,7 @@ export function FilterCombobox({ <button data-state-on={open} className={cn( - 'text-rgray-11/70 on:bg-rgray-3 focus-visible:ring-rgray-8 hover:bg-rgray-3 relative flex items-center justify-center gap-1 rounded-md px-3 py-1.5 ring-2 ring-transparent focus-visible:outline-none', + "text-rgray-11/70 on:bg-rgray-3 focus-visible:ring-rgray-8 hover:bg-rgray-3 relative flex items-center justify-center gap-1 rounded-md px-3 py-1.5 ring-2 ring-transparent focus-visible:outline-none", className, )} {...props} @@ -129,7 +131,7 @@ export function FilterCombobox({ <Check data-state-on={selectedSpaces.includes(space.id)} className={cn( - 'on:opacity-100 ml-auto h-4 w-4 opacity-0', + "on:opacity-100 ml-auto h-4 w-4 opacity-0", )} /> </motion.div> diff --git a/apps/web/src/components/Sidebar/index.tsx b/apps/web/src/components/Sidebar/index.tsx index 830b0f05..568aa3dd 100644 --- a/apps/web/src/components/Sidebar/index.tsx +++ b/apps/web/src/components/Sidebar/index.tsx @@ -1,29 +1,35 @@ -'use client'; -import { MemoryIcon } from '../../assets/Memories'; -import { Trash2, User2 } from 'lucide-react'; -import React, { useEffect, useState } from 'react'; -import { MemoriesBar } from './MemoriesBar'; -import { AnimatePresence, motion } from 'framer-motion'; -import { Bin } from '@/assets/Bin'; -import { Avatar, AvatarFallback, AvatarImage } from '@radix-ui/react-avatar'; -import { useSession } from 'next-auth/react'; +"use client"; +import { MemoryIcon } from "../../assets/Memories"; +import { Trash2, User2 } from "lucide-react"; +import React, { useEffect, useState } from "react"; +import { MemoriesBar } from "./MemoriesBar"; +import { AnimatePresence, motion } from "framer-motion"; +import { Bin } from "@/assets/Bin"; +import { Avatar, AvatarFallback, AvatarImage } from "@radix-ui/react-avatar"; +import { useSession } from "next-auth/react"; +import MessagePoster from "@/app/MessagePoster"; +import Image from "next/image"; +import WordMark from "../WordMark"; export type MenuItem = { icon: React.ReactNode | React.ReactNode[]; label: string; content?: React.ReactNode; + labelDisplay?: React.ReactNode; }; export default function Sidebar({ selectChange, + jwt, }: { selectChange?: (selectedItem: string | null) => void; + jwt: string; }) { const { data: session } = useSession(); const menuItemsTop: Array<MenuItem> = [ { icon: <MemoryIcon className="h-10 w-10" />, - label: 'Memories', + label: "Memories", content: <MemoriesBar />, }, ]; @@ -31,7 +37,7 @@ export default function Sidebar({ const menuItemsBottom: Array<MenuItem> = [ { icon: <Trash2 strokeWidth={1.3} className="h-6 w-6" />, - label: 'Trash', + label: "Trash", }, { icon: ( @@ -47,12 +53,12 @@ export default function Sidebar({ <User2 strokeWidth={1.3} className="h-6 w-6" /> )} <AvatarFallback> - {session?.user?.name?.split(' ').map((n) => n[0])}{' '} + {session?.user?.name?.split(" ").map((n) => n[0])}{" "} </AvatarFallback> </Avatar> </div> ), - label: 'Profile', + label: "Profile", }, ]; @@ -70,22 +76,30 @@ export default function Sidebar({ return ( <> <div className="relative hidden h-screen max-h-screen w-max flex-col items-center text-sm font-light md:flex"> - <div className="bg-rgray-2 border-r-rgray-6 relative z-[50] flex h-full w-full flex-col items-center justify-center border-r px-2 py-5 "> + <div className="bg-rgray-3 border-r-rgray-6 relative z-[50] flex h-full w-full flex-col items-center justify-center border-r px-2 py-5 "> + <Image + className="mb-4 rounded-md" + src="/icons/logo_bw_without_bg.png" + alt="Smort logo" + width={50} + height={50} + /> + + <div className="bg-rgray-6 mb-8 h-[1px] w-full" /> + <MenuItem item={{ - label: 'Memories', + label: "Memories", icon: <MemoryIcon className="h-10 w-10" />, content: <MemoriesBar />, }} selectedItem={selectedItem} setSelectedItem={setSelectedItem} /> - <div className="mt-auto" /> - <MenuItem item={{ - label: 'Trash', + label: "Trash", icon: <Bin id="trash" className="z-[300] h-7 w-7" />, }} selectedItem={selectedItem} @@ -94,7 +108,7 @@ export default function Sidebar({ /> <MenuItem item={{ - label: 'Profile', + label: "Profile", icon: ( <div className="mb-2"> <Avatar> @@ -108,7 +122,7 @@ export default function Sidebar({ <User2 strokeWidth={1.3} className="h-6 w-6" /> )} <AvatarFallback> - {session?.user?.name?.split(' ').map((n) => n[0])}{' '} + {session?.user?.name?.split(" ").map((n) => n[0])}{" "} </AvatarFallback> </Avatar> </div> @@ -117,6 +131,7 @@ export default function Sidebar({ selectedItem={selectedItem} setSelectedItem={setSelectedItem} /> + <MessagePoster jwt={jwt} /> </div> <AnimatePresence> {selectedItem && <SubSidebar>{Subbar}</SubSidebar>} @@ -127,7 +142,7 @@ export default function Sidebar({ } const MenuItem = ({ - item: { icon, label }, + item: { icon, label, labelDisplay }, selectedItem, setSelectedItem, ...props @@ -143,18 +158,18 @@ const MenuItem = ({ {...props} > {icon} - <span className="">{label}</span> + <span className="">{labelDisplay ?? label}</span> </button> ); export function SubSidebar({ children }: { children?: React.ReactNode }) { return ( <motion.div - initial={{ opacity: 0, x: '-100%' }} + initial={{ opacity: 0, x: "-100%" }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, - x: '-100%', + x: "-100%", transition: { delay: 0.2 }, }} transition={{ |