From fab884c6fabf8deb548b3bd2adb2a4947f2db790 Mon Sep 17 00:00:00 2001 From: Fuwn Date: Tue, 3 Feb 2026 22:58:11 -0800 Subject: feat(web): Add memory dashboard --- packages/web/package.json | 1 + packages/web/src/app/_components/post.tsx | 19 ++-- packages/web/src/app/auth/sign-in/page.tsx | 50 +++++---- packages/web/src/app/auth/sign-up/page.tsx | 65 ++++++----- .../web/src/app/dashboard/dashboard-content.tsx | 122 +++++++++++++++++++++ packages/web/src/app/dashboard/page.tsx | 13 +++ packages/web/src/app/layout.tsx | 14 +-- packages/web/src/app/page.tsx | 88 +++++---------- packages/web/src/server/api/root.ts | 2 + packages/web/src/server/api/routers/memory.ts | 80 ++++++++++++++ packages/web/src/styles/globals.css | 35 ++++++ 11 files changed, 368 insertions(+), 121 deletions(-) create mode 100644 packages/web/src/app/dashboard/dashboard-content.tsx create mode 100644 packages/web/src/app/dashboard/page.tsx create mode 100644 packages/web/src/server/api/routers/memory.ts (limited to 'packages') diff --git a/packages/web/package.json b/packages/web/package.json index b140111..293ee85 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -18,6 +18,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@imemio/sdk": "workspace:*", "@supabase/ssr": "^0.8.0", "@supabase/supabase-js": "^2.94.0", "@t3-oss/env-nextjs": "^0.12.0", diff --git a/packages/web/src/app/_components/post.tsx b/packages/web/src/app/_components/post.tsx index 9a1251f..5fb8ba8 100644 --- a/packages/web/src/app/_components/post.tsx +++ b/packages/web/src/app/_components/post.tsx @@ -15,34 +15,37 @@ export function LatestPost() { }); return ( -
+
{latestPost ? ( -

Your most recent post: {latestPost.name}

+

+ your most recent post:{" "} + {latestPost.name} +

) : ( -

You have no posts yet.

+

you have no posts yet.

)}
{ formSubmitEvent.preventDefault(); createPost.mutate({ name }); }} > setName(inputChangeEvent.target.value) } - placeholder="Title" + placeholder="title" type="text" value={name} />
diff --git a/packages/web/src/app/auth/sign-in/page.tsx b/packages/web/src/app/auth/sign-in/page.tsx index 3c4c10a..2bf6767 100644 --- a/packages/web/src/app/auth/sign-in/page.tsx +++ b/packages/web/src/app/auth/sign-in/page.tsx @@ -1,5 +1,6 @@ "use client"; +import Link from "next/link"; import { useState } from "react"; import { createClient } from "~/lib/supabase/client"; @@ -32,57 +33,64 @@ export default function SignInPage() { } return ( -
-
-

Sign In

+
+
+

+ > sign in +

-
-
-
+
); } diff --git a/packages/web/src/app/auth/sign-up/page.tsx b/packages/web/src/app/auth/sign-up/page.tsx index 94a501c..981692e 100644 --- a/packages/web/src/app/auth/sign-up/page.tsx +++ b/packages/web/src/app/auth/sign-up/page.tsx @@ -1,5 +1,6 @@ "use client"; +import Link from "next/link"; import { useState } from "react"; import { createClient } from "~/lib/supabase/client"; @@ -37,68 +38,80 @@ export default function SignUpPage() { if (success) { return ( -
-
-

Check your email

-

We've sent you a confirmation link to {email}

+
+
+

+ > check your email +

+

+ we've sent a confirmation link to{" "} + {email} +

-
+ ); } return ( -
-
-

Sign Up

+
+
+

+ > sign up +

-
-
-
+
); } diff --git a/packages/web/src/app/dashboard/dashboard-content.tsx b/packages/web/src/app/dashboard/dashboard-content.tsx new file mode 100644 index 0000000..da681b8 --- /dev/null +++ b/packages/web/src/app/dashboard/dashboard-content.tsx @@ -0,0 +1,122 @@ +"use client"; + +import Link from "next/link"; +import { useState } from "react"; +import { api } from "~/trpc/react"; + +function MemoryList() { + const [memories] = api.memory.list.useSuspenseQuery(); + const trpcUtilities = api.useUtils(); + const deleteMemory = api.memory.delete.useMutation({ + onSuccess: async () => { + await trpcUtilities.memory.invalidate(); + }, + }); + + if (memories.length === 0) { + return ( +
+

+ no memories yet. create your first one below. +

+
+ ); + } + + return ( +
+ {memories.map((memory) => ( +
+
+

{memory.content}

+

+ {new Date(memory.createdAt).toLocaleString()} +

+
+ +
+ ))} +
+ ); +} + +function CreateMemoryForm() { + const [content, setContent] = useState(""); + const trpcUtilities = api.useUtils(); + const createMemory = api.memory.create.useMutation({ + onSuccess: async () => { + await trpcUtilities.memory.invalidate(); + setContent(""); + }, + }); + + return ( +
{ + formSubmitEvent.preventDefault(); + + if (content.trim()) { + createMemory.mutate({ content }); + } + }} + > +