From d8cf7c17a2b0a437cf4a2f983f5ab48fba775a64 Mon Sep 17 00:00:00 2001
From: MohamedBassem <me@mbassem.com>
Date: Sun, 25 Aug 2024 00:48:37 +0300
Subject: feature(mobile): Allow editing notes from the mobile app

---
 apps/mobile/app/dashboard/add-note.tsx | 82 ++++++++++++++++++++++++++++------
 1 file changed, 69 insertions(+), 13 deletions(-)

(limited to 'apps/mobile/app/dashboard/add-note.tsx')

diff --git a/apps/mobile/app/dashboard/add-note.tsx b/apps/mobile/app/dashboard/add-note.tsx
index 62296fd4..8aa31936 100644
--- a/apps/mobile/app/dashboard/add-note.tsx
+++ b/apps/mobile/app/dashboard/add-note.tsx
@@ -1,28 +1,68 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { Text, View } from "react-native";
-import { useRouter } from "expo-router";
+import { Stack, useLocalSearchParams, useRouter } from "expo-router";
 import { Button } from "@/components/ui/Button";
 import { Input } from "@/components/ui/Input";
 import { api } from "@/lib/trpc";
 
+import {
+  useCreateBookmark,
+  useUpdateBookmarkText,
+} from "@hoarder/shared-react/hooks/bookmarks";
 import { BookmarkTypes } from "@hoarder/shared/types/bookmarks";
 
 export default function AddNote() {
+  const { bookmarkId } = useLocalSearchParams();
+  if (bookmarkId && typeof bookmarkId !== "string") {
+    throw new Error("Unexpected param type");
+  }
+
+  const isEditing = !!bookmarkId;
+
   const [text, setText] = useState("");
   const [error, setError] = useState<string | undefined>();
   const router = useRouter();
-  const invalidateAllBookmarks =
-    api.useUtils().bookmarks.getBookmarks.invalidate;
-
-  const { mutate } = api.bookmarks.createBookmark.useMutation({
-    onSuccess: () => {
-      invalidateAllBookmarks();
-      if (router.canGoBack()) {
-        router.replace("../");
+
+  const { data: bookmark } = api.bookmarks.getBookmark.useQuery(
+    { bookmarkId: bookmarkId! },
+    {
+      enabled: !!bookmarkId,
+    },
+  );
+
+  useEffect(() => {
+    if (bookmark) {
+      if (bookmark.content.type !== BookmarkTypes.TEXT) {
+        throw new Error("Wrong content type rendered");
+      }
+      setText(bookmark.content.text);
+    }
+  }, [bookmark]);
+
+  const onSuccess = () => {
+    if (router.canGoBack()) {
+      router.replace("./");
+    } else {
+      router.replace("dashboard");
+    }
+  };
+
+  const { mutate: createBookmark } = useCreateBookmark({
+    onSuccess,
+    onError: (e) => {
+      let message;
+      if (e.data?.zodError) {
+        const zodError = e.data.zodError;
+        message = JSON.stringify(zodError);
       } else {
-        router.replace("dashboard");
+        message = `Something went wrong: ${e.message}`;
       }
+      setError(message);
     },
+  });
+
+  const { mutate: updateBookmark } = useUpdateBookmarkText({
+    onSuccess,
     onError: (e) => {
       let message;
       if (e.data?.zodError) {
@@ -35,8 +75,24 @@ export default function AddNote() {
     },
   });
 
+  const mutate = (text: string) => {
+    if (isEditing) {
+      updateBookmark({
+        bookmarkId,
+        text,
+      });
+    } else {
+      createBookmark({ type: BookmarkTypes.TEXT, text });
+    }
+  };
+
   return (
     <View className="flex gap-2 p-4">
+      <Stack.Screen
+        options={{
+          title: isEditing ? "Edit Note" : "Add Note",
+        }}
+      />
       {error && (
         <Text className="w-full text-center text-red-500">{error}</Text>
       )}
@@ -50,8 +106,8 @@ export default function AddNote() {
         textAlignVertical="top"
       />
       <Button
-        onPress={() => mutate({ type: BookmarkTypes.TEXT, text })}
-        label="Add Note"
+        onPress={() => mutate(text)}
+        label={isEditing ? "Save" : "Add Note"}
       />
     </View>
   );
-- 
cgit v1.2.3-70-g09d2

