diff options
| author | CodeTorso <[email protected]> | 2024-07-13 01:47:26 +0530 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-07-13 01:47:26 +0530 |
| commit | 7576567af82ada84ffa4cbd352048ddbc333ad52 (patch) | |
| tree | 58e549084fe6692b2bc7fb623a82cb1262618bd7 /apps | |
| parent | Merge pull request #114 from GauravBurande/patch-1 (diff) | |
| parent | ui changes :) (diff) | |
| download | supermemory-7576567af82ada84ffa4cbd352048ddbc333ad52.tar.xz supermemory-7576567af82ada84ffa4cbd352048ddbc333ad52.zip | |
Merge pull request #116 from Dhravya/ui-improvements
ui changes :)
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/web/app/(dash)/(memories)/content.tsx | 9 | ||||
| -rw-r--r-- | apps/web/app/(dash)/menu.tsx | 279 |
2 files changed, 145 insertions, 143 deletions
diff --git a/apps/web/app/(dash)/(memories)/content.tsx b/apps/web/app/(dash)/(memories)/content.tsx index 960ca05f..9f84a6b6 100644 --- a/apps/web/app/(dash)/(memories)/content.tsx +++ b/apps/web/app/(dash)/(memories)/content.tsx @@ -33,6 +33,7 @@ import { Button } from "@repo/ui/shadcn/button"; import { addUserToSpace, deleteItem, moveItem } from "@/app/actions/doers"; import { toast } from "sonner"; import { Input } from "@repo/ui/shadcn/input"; +import { motion } from "framer-motion"; export function MemoriesPage({ memoriesAndSpaces, @@ -269,7 +270,9 @@ function LinkComponent({ id: number; }) { return ( - <div + <motion.div + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} className={`bg-secondary group relative border-2 border-border rounded-xl ${type === "tweet" ? "" : "p-4"} hover:scale-105 transition duration-200`} > <Link @@ -353,7 +356,7 @@ function LinkComponent({ </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> - </div> + </motion.div> ); } @@ -362,7 +365,7 @@ const SpaceFilterMethods = ["All", "Pages", "Notes", "Tweet"]; function Filters({ setFilter, filter, - filterMethods + filterMethods, }: { setFilter: (i: string) => void; filter: string; diff --git a/apps/web/app/(dash)/menu.tsx b/apps/web/app/(dash)/menu.tsx index 6cea35a4..a481ae1f 100644 --- a/apps/web/app/(dash)/menu.tsx +++ b/apps/web/app/(dash)/menu.tsx @@ -40,8 +40,11 @@ import { Input } from "@repo/ui/shadcn/input"; import ComboboxWithCreate from "@repo/ui/shadcn/combobox"; import { StoredSpace } from "@/server/db/schema"; import { revalidatePath } from "next/cache"; +import useMeasure from "react-use-measure"; +import { motion } from "framer-motion"; function Menu() { + const [ref, bounds] = useMeasure(); const [spaces, setSpaces] = useState<StoredSpace[]>([]); useEffect(() => { @@ -183,158 +186,154 @@ function Menu() { </div> </div> - <DialogContent className="sm:max-w-[425px] rounded-2xl bg-background z-[39] backdrop-blur-md"> - <form - action={async (e: FormData) => { - const content = e.get("content")?.toString(); - const space = e.get("space")?.toString(); - - await handleSubmit(content, space); - }} - className="flex flex-col gap-4" + <DialogContent className="sm:max-w-[475px] text-[#F2F3F5] rounded-2xl bg-background z-[39] backdrop-blur-md"> + <motion.div + className="overflow-hidden max-h-[70vh]" + animate={{ height: bounds.height + 10 }} > - <DialogHeader> - <DialogTitle>Add memory</DialogTitle> - <DialogDescription> - A "Memory" is a bookmark, something you want to remember. - </DialogDescription> - </DialogHeader> + <form + ref={ref} + action={async (e: FormData) => { + const content = e.get("content")?.toString(); + const space = e.get("space")?.toString(); - <div> - <Label className="text-[#858B92]" htmlFor="name"> - Resource (URL or content) - </Label> - <Textarea - className="bg-[#2F353C] focus-visible:ring-0 border-none focus-visible:ring-offset-0 mt-2" - id="content" - name="content" - placeholder="Start typing a note or paste a URL here. I'll remember it." - value={content} - onChange={(e) => setContent(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - handleSubmit(content); - } - }} - /> - </div> + await handleSubmit(content, space); + }} + className="flex flex-col gap-4" + > + <DialogHeader> + <DialogTitle>Add memory</DialogTitle> + <DialogDescription className="text-[#F2F3F5]"> + A "Memory" is a bookmark, something you want to remember. + </DialogDescription> + </DialogHeader> - {autoDetectedType != "none" && ( <div> - <Label - className="text-[#858B92] flex items-center gap-1 duration-200 transform transition-transform" - htmlFor="space" - > - Spaces - <TooltipProvider> - <Tooltip> - <TooltipTrigger> - <span> - <InformationCircleIcon className="w-4 h-4" /> - </span> - </TooltipTrigger> - <TooltipContent> - <p> - A space is a collection of memories. You can create a - space and then chat/write/ideate with it. - </p> - </TooltipContent> - </Tooltip> - </TooltipProvider> + <Label htmlFor="name"> + Resource (URL or content) </Label> - - <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!, - createdAt: new Date(), - user: null, - numItems: 0, - }, - ]); - setSelectedSpaces((prev) => [ - ...prev, - creationTask.data!, - ]); - } else { - toast.error( - "Space creation failed: " + creationTask.error ?? - "Unknown error", - ); + <Textarea + className={`bg-[#2F353C] text-[#DBDEE1] max-h-[35vh] overflow-auto focus-visible:ring-0 border-none focus-visible:ring-offset-0 mt-2 ${/^https?:\/\/\S+$/i.test(content) && "text-[#1D9BF0] underline underline-offset-2"}`} + id="content" + name="content" + rows={8} + placeholder="Start typing a note or paste a URL here. I'll remember it." + value={content} + onChange={(e) => setContent(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSubmit(content); } }} - placeholder="Save or create space by typing." - className="bg-[#2F353C] h-min rounded-md mt-2 mb-4" /> + </div> + {autoDetectedType != "none" && ( <div> - {selectedSpaces.length > 0 && ( - <div className="flex flex-row flex-wrap gap-0.5 h-min"> - {selectedSpaces.map((x, idx) => ( - <button - key={x} - type="button" - 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> - )} + <Label + className="space-y-2" + htmlFor="space" + > + <h3 className="font-bold text-lg">Spaces</h3> + <p className="leading-normal"> + A space is a collection of memories. You can create a + space and then chat/write/ideate with it. + </p> + </Label> + + <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!, + createdAt: new Date(), + user: null, + numItems: 0, + }, + ]); + setSelectedSpaces((prev) => [ + ...prev, + creationTask.data!, + ]); + } else { + toast.error( + "Space creation failed: " + creationTask.error ?? + "Unknown error", + ); + } + }} + placeholder="Save or create space by typing." + className="bg-[#2F353C] h-min rounded-md mt-4 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} + type="button" + 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> - </div> - )} + )} - <DialogFooter> - <Button - disabled={autoDetectedType === "none"} - variant={"secondary"} - type="submit" - > - Save {autoDetectedType != "none" && autoDetectedType} - </Button> - </DialogFooter> - </form> + <DialogFooter> + <Button + disabled={autoDetectedType === "none"} + variant={"secondary"} + type="submit" + > + Save {autoDetectedType != "none" && autoDetectedType} + </Button> + </DialogFooter> + </form> + </motion.div> </DialogContent> {/* Mobile Menu */} |