diff options
| -rw-r--r-- | packages/mobile/app/dashboard/(tabs)/index.tsx | 28 | ||||
| -rw-r--r-- | packages/mobile/app/dashboard/_layout.tsx | 14 | ||||
| -rw-r--r-- | packages/mobile/app/dashboard/add-link.tsx | 57 | ||||
| -rw-r--r-- | packages/mobile/app/dashboard/add-note.tsx | 53 | ||||
| -rw-r--r-- | packages/mobile/package.json | 1 |
5 files changed, 152 insertions, 1 deletions
diff --git a/packages/mobile/app/dashboard/(tabs)/index.tsx b/packages/mobile/app/dashboard/(tabs)/index.tsx index 07516f3b..b2349525 100644 --- a/packages/mobile/app/dashboard/(tabs)/index.tsx +++ b/packages/mobile/app/dashboard/(tabs)/index.tsx @@ -1,5 +1,31 @@ +import { Link, Stack } from "expo-router"; +import { SquarePen, Link as LinkIcon } from "lucide-react-native"; +import { View } from "react-native"; + import BookmarkList from "@/components/bookmarks/BookmarkList"; +function HeaderRight() { + return ( + <View className="flex flex-row"> + <Link href="dashboard/add-link" className="mt-2 px-2"> + <LinkIcon /> + </Link> + <Link href="dashboard/add-note" className="mt-2 px-2"> + <SquarePen /> + </Link> + </View> + ); +} + export default function Home() { - return <BookmarkList archived={false} />; + return ( + <> + <Stack.Screen + options={{ + headerRight: () => <HeaderRight />, + }} + /> + <BookmarkList archived={false} /> + </> + ); } diff --git a/packages/mobile/app/dashboard/_layout.tsx b/packages/mobile/app/dashboard/_layout.tsx index 4dd03d95..ff2384d2 100644 --- a/packages/mobile/app/dashboard/_layout.tsx +++ b/packages/mobile/app/dashboard/_layout.tsx @@ -19,6 +19,20 @@ export default function Dashboard() { title: "🗄️ Archive", }} /> + <Stack.Screen + name="add-link" + options={{ + title: "New link", + presentation: "modal", + }} + /> + <Stack.Screen + name="add-note" + options={{ + title: "New Note", + presentation: "modal", + }} + /> </Stack> ); } diff --git a/packages/mobile/app/dashboard/add-link.tsx b/packages/mobile/app/dashboard/add-link.tsx new file mode 100644 index 00000000..69a9c7a2 --- /dev/null +++ b/packages/mobile/app/dashboard/add-link.tsx @@ -0,0 +1,57 @@ +import { useRouter } from "expo-router"; +import { useState } from "react"; +import { View, Text } from "react-native"; + +import { Button } from "@/components/ui/Button"; +import { Input } from "@/components/ui/Input"; +import { api } from "@/lib/trpc"; + +export default function AddNote() { + 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("../"); + } else { + router.replace("dashboard"); + } + }, + onError: (e) => { + let message; + if (e.data?.code === "BAD_REQUEST") { + const error = JSON.parse(e.message)[0]; + message = error.message; + } else { + message = `Something went wrong: ${e.message}`; + } + setError(message); + }, + }); + + return ( + <View className="flex gap-2 p-4"> + {error && ( + <Text className="w-full text-center text-red-500">{error}</Text> + )} + <Input + className="bg-white" + value={text} + onChangeText={setText} + placeholder="Link" + autoCapitalize="none" + inputMode="url" + autoFocus + /> + <Button + onPress={() => mutate({ type: "link", url: text })} + label="Add Link" + /> + </View> + ); +} diff --git a/packages/mobile/app/dashboard/add-note.tsx b/packages/mobile/app/dashboard/add-note.tsx new file mode 100644 index 00000000..cf775a15 --- /dev/null +++ b/packages/mobile/app/dashboard/add-note.tsx @@ -0,0 +1,53 @@ +import { useRouter } from "expo-router"; +import { useState } from "react"; +import { View, Text } from "react-native"; + +import { Button } from "@/components/ui/Button"; +import { Input } from "@/components/ui/Input"; +import { api } from "@/lib/trpc"; + +export default function AddNote() { + 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("../"); + } else { + router.replace("dashboard"); + } + }, + onError: (e) => { + let message; + if (e.data?.code === "BAD_REQUEST") { + const error = JSON.parse(e.message)[0]; + message = error.message; + } else { + message = `Something went wrong: ${e.message}`; + } + setError(message); + }, + }); + + return ( + <View className="flex gap-2 p-4"> + {error && ( + <Text className="w-full text-center text-red-500">{error}</Text> + )} + <Input + className="bg-white" + value={text} + onChangeText={setText} + multiline + placeholder="What's on your mind?" + autoFocus + /> + <Button onPress={() => mutate({ type: "text", text })} label="Add Note" /> + </View> + ); +} diff --git a/packages/mobile/package.json b/packages/mobile/package.json index 252f98e0..37cc5ee4 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -10,6 +10,7 @@ "lint": "eslint ." }, "dependencies": { + "@hoarder/trpc": "0.1.0", "@tanstack/react-query": "^5.24.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", |
