aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorCodeTorso <[email protected]>2024-07-13 01:47:26 +0530
committerGitHub <[email protected]>2024-07-13 01:47:26 +0530
commit7576567af82ada84ffa4cbd352048ddbc333ad52 (patch)
tree58e549084fe6692b2bc7fb623a82cb1262618bd7 /apps
parentMerge pull request #114 from GauravBurande/patch-1 (diff)
parentui changes :) (diff)
downloadsupermemory-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.tsx9
-rw-r--r--apps/web/app/(dash)/menu.tsx279
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 */}