aboutsummaryrefslogtreecommitdiffstats
path: root/apps/mobile/app/dashboard
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-11-23 20:59:34 +0000
committerGitHub <noreply@github.com>2024-11-23 20:59:34 +0000
commit5522e20104da6afe2e4667cf45dbbbbc0e838865 (patch)
tree72f416fa83c97a8533eea431e25bd63bda1e7d81 /apps/mobile/app/dashboard
parent4bb74872fd518008afea16a136292037baf5b024 (diff)
downloadkarakeep-5522e20104da6afe2e4667cf45dbbbbc0e838865.tar.zst
ui(mobile): Replace bottom sheet with native screens (#690)
* Remove bottom sheet from bookmark info page * Remove bottom sheet from manage lists page * Remove bottom sheet from new list page * Remove bottom sheet from new bookmark page * Drop bottom-sheets * Improve the look of the modals * Make the search page fade from bottom
Diffstat (limited to 'apps/mobile/app/dashboard')
-rw-r--r--apps/mobile/app/dashboard/(tabs)/index.tsx10
-rw-r--r--apps/mobile/app/dashboard/(tabs)/lists.tsx10
-rw-r--r--apps/mobile/app/dashboard/_layout.tsx45
-rw-r--r--apps/mobile/app/dashboard/add-link.tsx64
-rw-r--r--apps/mobile/app/dashboard/bookmarks/[slug]/index.tsx (renamed from apps/mobile/app/dashboard/bookmarks/[slug].tsx)33
-rw-r--r--apps/mobile/app/dashboard/bookmarks/[slug]/info.tsx115
-rw-r--r--apps/mobile/app/dashboard/bookmarks/[slug]/manage_lists.tsx105
-rw-r--r--apps/mobile/app/dashboard/bookmarks/new.tsx76
-rw-r--r--apps/mobile/app/dashboard/lists/new.tsx56
9 files changed, 409 insertions, 105 deletions
diff --git a/apps/mobile/app/dashboard/(tabs)/index.tsx b/apps/mobile/app/dashboard/(tabs)/index.tsx
index b9ab7d11..f70474a9 100644
--- a/apps/mobile/app/dashboard/(tabs)/index.tsx
+++ b/apps/mobile/app/dashboard/(tabs)/index.tsx
@@ -1,9 +1,7 @@
-import { useRef } from "react";
import { Platform, Pressable, Text, View } from "react-native";
import * as Haptics from "expo-haptics";
import * as ImagePicker from "expo-image-picker";
import { router } from "expo-router";
-import NoteEditorModal from "@/components/bookmarks/NewBookmarkModal";
import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList";
import { TailwindResolver } from "@/components/TailwindResolver";
import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
@@ -11,7 +9,6 @@ import PageTitle from "@/components/ui/PageTitle";
import { useToast } from "@/components/ui/Toast";
import useAppSettings from "@/lib/settings";
import { useUploadAsset } from "@/lib/upload";
-import { BottomSheetModal } from "@gorhom/bottom-sheet";
import { MenuView } from "@react-native-menu/menu";
import { Plus, Search } from "lucide-react-native";
@@ -77,11 +74,8 @@ function HeaderRight({
}
export default function Home() {
- const newBookmarkModal = useRef<BottomSheetModal>(null);
-
return (
<CustomSafeAreaView>
- <NoteEditorModal ref={newBookmarkModal} snapPoints={["90%", "60%"]} />
<UpdatingBookmarkList
query={{ archived: false }}
header={
@@ -89,7 +83,9 @@ export default function Home() {
<View className="flex flex-row justify-between">
<PageTitle title="Home" className="pb-2" />
<HeaderRight
- openNewBookmarkModal={() => newBookmarkModal.current?.present()}
+ openNewBookmarkModal={() =>
+ router.push("/dashboard/bookmarks/new")
+ }
/>
</View>
<Pressable
diff --git a/apps/mobile/app/dashboard/(tabs)/lists.tsx b/apps/mobile/app/dashboard/(tabs)/lists.tsx
index fa97f67a..9cc49cd4 100644
--- a/apps/mobile/app/dashboard/(tabs)/lists.tsx
+++ b/apps/mobile/app/dashboard/(tabs)/lists.tsx
@@ -1,15 +1,13 @@
-import { useEffect, useRef, useState } from "react";
+import { useEffect, useState } from "react";
import { FlatList, Pressable, Text, View } from "react-native";
import * as Haptics from "expo-haptics";
-import { Link } from "expo-router";
+import { Link, router } from "expo-router";
import FullPageError from "@/components/FullPageError";
-import NewListModal from "@/components/lists/NewListModal";
import { TailwindResolver } from "@/components/TailwindResolver";
import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
import FullPageSpinner from "@/components/ui/FullPageSpinner";
import PageTitle from "@/components/ui/PageTitle";
import { api } from "@/lib/trpc";
-import { BottomSheetModal } from "@gorhom/bottom-sheet";
import { ChevronRight, Plus } from "lucide-react-native";
import { useBookmarkLists } from "@hoarder/shared-react/hooks/lists";
@@ -72,7 +70,6 @@ export default function Lists() {
{},
);
const apiUtils = api.useUtils();
- const newListModal = useRef<BottomSheetModal>(null);
useEffect(() => {
setRefreshing(isPending);
@@ -117,14 +114,13 @@ export default function Lists() {
return (
<CustomSafeAreaView>
- <NewListModal ref={newListModal} snapPoints={["90%"]} />
<FlatList
className="h-full"
ListHeaderComponent={
<View className="flex flex-row justify-between">
<PageTitle title="Lists" />
<HeaderRight
- openNewListModal={() => newListModal.current?.present()}
+ openNewListModal={() => router.push("/dashboard/lists/new")}
/>
</View>
}
diff --git a/apps/mobile/app/dashboard/_layout.tsx b/apps/mobile/app/dashboard/_layout.tsx
index 609f06f5..bc743c7a 100644
--- a/apps/mobile/app/dashboard/_layout.tsx
+++ b/apps/mobile/app/dashboard/_layout.tsx
@@ -50,6 +50,49 @@ export default function Dashboard() {
}}
/>
<Stack.Screen
+ name="bookmarks/[slug]/index"
+ options={{
+ headerTitle: "",
+ headerBackTitle: "Back",
+ headerTransparent: true,
+ }}
+ />
+ <Stack.Screen
+ name="bookmarks/new"
+ options={{
+ headerTitle: "New Bookmark",
+ headerBackTitle: "Back",
+ headerTransparent: true,
+ presentation: "modal",
+ }}
+ />
+ <Stack.Screen
+ name="bookmarks/[slug]/manage_lists"
+ options={{
+ headerTitle: "Manage Lists",
+ headerBackTitle: "Back",
+ headerTransparent: true,
+ presentation: "modal",
+ }}
+ />
+ <Stack.Screen
+ name="bookmarks/[slug]/info"
+ options={{
+ headerBackTitle: "Back",
+ headerTransparent: true,
+ presentation: "modal",
+ }}
+ />
+ <Stack.Screen
+ name="lists/new"
+ options={{
+ headerTitle: "New List",
+ headerBackTitle: "Back",
+ headerTransparent: true,
+ presentation: "modal",
+ }}
+ />
+ <Stack.Screen
name="archive"
options={{
headerTitle: "",
@@ -64,6 +107,8 @@ export default function Dashboard() {
headerBackTitle: "",
headerTransparent: true,
headerShown: false,
+ animation: "fade_from_bottom",
+ animationDuration: 100,
}}
/>
<Stack.Screen
diff --git a/apps/mobile/app/dashboard/add-link.tsx b/apps/mobile/app/dashboard/add-link.tsx
deleted file mode 100644
index d9773fb4..00000000
--- a/apps/mobile/app/dashboard/add-link.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { useState } from "react";
-import { Text, View } from "react-native";
-import { useRouter } from "expo-router";
-import { Button } from "@/components/ui/Button";
-import { Input } from "@/components/ui/Input";
-import { useToast } from "@/components/ui/Toast";
-import { api } from "@/lib/trpc";
-
-import { BookmarkTypes } from "@hoarder/shared/types/bookmarks";
-
-export default function AddNote() {
- const [text, setText] = useState("");
- const [error, setError] = useState<string | undefined>();
- const { toast } = useToast();
- const router = useRouter();
- const invalidateAllBookmarks =
- api.useUtils().bookmarks.getBookmarks.invalidate;
-
- const { mutate } = api.bookmarks.createBookmark.useMutation({
- onSuccess: (resp) => {
- if (resp.alreadyExists) {
- toast({
- message: "Bookmark already exists",
- });
- }
- invalidateAllBookmarks();
- if (router.canGoBack()) {
- router.replace("../");
- } else {
- router.replace("dashboard");
- }
- },
- onError: (e) => {
- let message;
- if (e.data?.zodError) {
- const zodError = e.data.zodError;
- message = JSON.stringify(zodError);
- } 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
- value={text}
- onChangeText={setText}
- placeholder="Link"
- autoCapitalize="none"
- inputMode="url"
- autoFocus
- />
- <Button
- onPress={() => mutate({ type: BookmarkTypes.LINK, url: text })}
- label="Add Link"
- />
- </View>
- );
-}
diff --git a/apps/mobile/app/dashboard/bookmarks/[slug].tsx b/apps/mobile/app/dashboard/bookmarks/[slug]/index.tsx
index 9459488a..87330a88 100644
--- a/apps/mobile/app/dashboard/bookmarks/[slug].tsx
+++ b/apps/mobile/app/dashboard/bookmarks/[slug]/index.tsx
@@ -1,4 +1,4 @@
-import React, { useRef, useState } from "react";
+import React, { useState } from "react";
import {
Alert,
Keyboard,
@@ -12,8 +12,6 @@ import WebView from "react-native-webview";
import { Stack, useLocalSearchParams, useRouter } from "expo-router";
import BookmarkAssetImage from "@/components/bookmarks/BookmarkAssetImage";
import BookmarkTextMarkdown from "@/components/bookmarks/BookmarkTextMarkdown";
-import ListPickerModal from "@/components/bookmarks/ListPickerModal";
-import ViewBookmarkModal from "@/components/bookmarks/ViewBookmarkModal";
import FullPageError from "@/components/FullPageError";
import { TailwindResolver } from "@/components/TailwindResolver";
import { Button } from "@/components/ui/Button";
@@ -23,13 +21,7 @@ import { Input } from "@/components/ui/Input";
import { useToast } from "@/components/ui/Toast";
import { useAssetUrl } from "@/lib/hooks";
import { api } from "@/lib/trpc";
-import { BottomSheetModal } from "@gorhom/bottom-sheet";
-import {
- ArrowUpFromLine,
- ClipboardList,
- Globe,
- Trash2,
-} from "lucide-react-native";
+import { ClipboardList, Globe, Info, Trash2 } from "lucide-react-native";
import {
useDeleteBookmark,
@@ -40,8 +32,6 @@ import { BookmarkTypes, ZBookmark } from "@hoarder/shared/types/bookmarks";
function BottomActions({ bookmark }: { bookmark: ZBookmark }) {
const { toast } = useToast();
const router = useRouter();
- const viewBookmarkModal = useRef<BottomSheetModal>(null);
- const manageListsSheetRef = useRef<BottomSheetModal>(null);
const { mutate: deleteBookmark, isPending: isDeletionPending } =
useDeleteBookmark({
onSuccess: () => {
@@ -84,7 +74,8 @@ function BottomActions({ bookmark }: { bookmark: ZBookmark }) {
/>
),
shouldRender: true,
- onClick: () => manageListsSheetRef.current?.present(),
+ onClick: () =>
+ router.push(`/dashboard/bookmarks/${bookmark.id}/manage_lists`),
disabled: false,
},
{
@@ -92,13 +83,11 @@ function BottomActions({ bookmark }: { bookmark: ZBookmark }) {
icon: (
<TailwindResolver
className="text-foreground"
- comp={(styles) => (
- <ArrowUpFromLine color={styles?.color?.toString()} />
- )}
+ comp={(styles) => <Info color={styles?.color?.toString()} />}
/>
),
shouldRender: true,
- onClick: () => viewBookmarkModal.current?.present(),
+ onClick: () => router.push(`/dashboard/bookmarks/${bookmark.id}/info`),
disabled: false,
},
{
@@ -130,16 +119,6 @@ function BottomActions({ bookmark }: { bookmark: ZBookmark }) {
];
return (
<View>
- <ViewBookmarkModal
- bookmark={bookmark}
- ref={viewBookmarkModal}
- snapPoints={["95%"]}
- />
- <ListPickerModal
- ref={manageListsSheetRef}
- snapPoints={["50%", "90%"]}
- bookmarkId={bookmark.id}
- />
<View className="flex flex-row items-center justify-between px-10 pb-2 pt-4">
{actions.map(
(a) =>
diff --git a/apps/mobile/app/dashboard/bookmarks/[slug]/info.tsx b/apps/mobile/app/dashboard/bookmarks/[slug]/info.tsx
new file mode 100644
index 00000000..5d15ab6b
--- /dev/null
+++ b/apps/mobile/app/dashboard/bookmarks/[slug]/info.tsx
@@ -0,0 +1,115 @@
+import React from "react";
+import { Text, View } from "react-native";
+import { Stack, useLocalSearchParams } from "expo-router";
+import TagPill from "@/components/bookmarks/TagPill";
+import FullPageError from "@/components/FullPageError";
+import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
+import FullPageSpinner from "@/components/ui/FullPageSpinner";
+import { Input } from "@/components/ui/Input";
+import { Skeleton } from "@/components/ui/Skeleton";
+import { api } from "@/lib/trpc";
+
+import { useUpdateBookmark } from "@hoarder/shared-react/hooks/bookmarks";
+import { isBookmarkStillTagging } from "@hoarder/shared-react/utils/bookmarkUtils";
+import { BookmarkTypes, ZBookmark } from "@hoarder/shared/types/bookmarks";
+
+function TagList({ bookmark }: { bookmark: ZBookmark }) {
+ return (
+ <View className="flex flex-row items-center gap-4">
+ <Text className="text-foreground">Tags</Text>
+ {isBookmarkStillTagging(bookmark) ? (
+ <>
+ <Skeleton className="h-4 w-full" />
+ <Skeleton className="h-4 w-full" />
+ </>
+ ) : bookmark.tags.length > 0 ? (
+ <View className="flex flex-row flex-wrap gap-2">
+ {bookmark.tags.map((t) => (
+ <TagPill key={t.id} tag={t} />
+ ))}
+ </View>
+ ) : (
+ <Text className="text-foreground">No tags</Text>
+ )}
+ </View>
+ );
+}
+
+function NotesEditor({ bookmark }: { bookmark: ZBookmark }) {
+ const { mutate, isPending } = useUpdateBookmark();
+ return (
+ <View className="flex flex-row items-center gap-4">
+ <Text className="text-foreground">Notes</Text>
+
+ <Input
+ className="flex-1"
+ editable={!isPending}
+ multiline={true}
+ numberOfLines={3}
+ loading={isPending}
+ placeholder="Notes"
+ textAlignVertical="top"
+ onEndEditing={(ev) =>
+ mutate({
+ bookmarkId: bookmark.id,
+ note: ev.nativeEvent.text,
+ })
+ }
+ defaultValue={bookmark.note ?? ""}
+ />
+ </View>
+ );
+}
+
+const ViewBookmarkPage = () => {
+ const { slug } = useLocalSearchParams();
+ if (typeof slug !== "string") {
+ throw new Error("Unexpected param type");
+ }
+ const {
+ data: bookmark,
+ isPending,
+ refetch,
+ } = api.bookmarks.getBookmark.useQuery({ bookmarkId: slug });
+
+ if (isPending) {
+ return <FullPageSpinner />;
+ }
+
+ if (!bookmark) {
+ return (
+ <FullPageError error="Bookmark not found" onRetry={() => refetch()} />
+ );
+ }
+
+ let title = null;
+ switch (bookmark.content.type) {
+ case BookmarkTypes.LINK:
+ title = bookmark.title ?? bookmark.content.title;
+ break;
+ case BookmarkTypes.TEXT:
+ title = bookmark.title;
+ break;
+ case BookmarkTypes.ASSET:
+ title = bookmark.title ?? bookmark.content.fileName;
+ break;
+ }
+ return (
+ <CustomSafeAreaView>
+ <Stack.Screen
+ options={{
+ headerShown: true,
+ headerTitle: title ?? "Untitled",
+ }}
+ />
+ <View className="w-full p-4">
+ <View className="gap-4 px-4">
+ <TagList bookmark={bookmark} />
+ <NotesEditor bookmark={bookmark} />
+ </View>
+ </View>
+ </CustomSafeAreaView>
+ );
+};
+
+export default ViewBookmarkPage;
diff --git a/apps/mobile/app/dashboard/bookmarks/[slug]/manage_lists.tsx b/apps/mobile/app/dashboard/bookmarks/[slug]/manage_lists.tsx
new file mode 100644
index 00000000..b38261df
--- /dev/null
+++ b/apps/mobile/app/dashboard/bookmarks/[slug]/manage_lists.tsx
@@ -0,0 +1,105 @@
+import React from "react";
+import { FlatList, Pressable, Text, View } from "react-native";
+import Checkbox from "expo-checkbox";
+import { useLocalSearchParams } from "expo-router";
+import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
+import { useToast } from "@/components/ui/Toast";
+
+import {
+ useAddBookmarkToList,
+ useBookmarkLists,
+ useRemoveBookmarkFromList,
+} from "@hoarder/shared-react/hooks/lists";
+import { api } from "@hoarder/shared-react/trpc";
+
+const ListPickerPage = () => {
+ const { slug: bookmarkId } = useLocalSearchParams();
+ if (typeof bookmarkId !== "string") {
+ throw new Error("Unexpected param type");
+ }
+ const { toast } = useToast();
+ const onError = () => {
+ toast({
+ message: "Something went wrong",
+ variant: "destructive",
+ showProgress: false,
+ });
+ };
+ const { data: existingLists } = api.lists.getListsOfBookmark.useQuery(
+ {
+ bookmarkId,
+ },
+ {
+ select: (data) => new Set(data.lists.map((l) => l.id)),
+ },
+ );
+ const { data } = useBookmarkLists();
+
+ const { mutate: addToList } = useAddBookmarkToList({
+ onSuccess: () => {
+ toast({
+ message: `The bookmark has been added to the list!`,
+ showProgress: false,
+ });
+ },
+ onError,
+ });
+
+ const { mutate: removeToList } = useRemoveBookmarkFromList({
+ onSuccess: () => {
+ toast({
+ message: `The bookmark has been removed from the list!`,
+ showProgress: false,
+ });
+ },
+ onError,
+ });
+
+ const toggleList = (listId: string) => {
+ if (!existingLists) {
+ return;
+ }
+ if (existingLists.has(listId)) {
+ removeToList({ bookmarkId, listId });
+ } else {
+ addToList({ bookmarkId, listId });
+ }
+ };
+
+ const { allPaths } = data ?? {};
+ return (
+ <CustomSafeAreaView>
+ <FlatList
+ className="h-full"
+ contentContainerStyle={{
+ gap: 5,
+ }}
+ renderItem={(l) => (
+ <View className="mx-2 flex flex-row items-center rounded-xl border border-input bg-white px-4 py-2 dark:bg-accent">
+ <Pressable
+ key={l.item[l.item.length - 1].id}
+ onPress={() => toggleList(l.item[l.item.length - 1].id)}
+ className="flex w-full flex-row justify-between"
+ >
+ <Text className="text-lg text-accent-foreground">
+ {l.item.map((item) => `${item.icon} ${item.name}`).join(" / ")}
+ </Text>
+ <Checkbox
+ value={
+ existingLists &&
+ existingLists.has(l.item[l.item.length - 1].id)
+ }
+ onValueChange={() => {
+ toggleList(l.item[l.item.length - 1].id);
+ }}
+ />
+ </Pressable>
+ </View>
+ )}
+ data={allPaths}
+ />
+ </CustomSafeAreaView>
+ );
+};
+
+export default ListPickerPage;
diff --git a/apps/mobile/app/dashboard/bookmarks/new.tsx b/apps/mobile/app/dashboard/bookmarks/new.tsx
new file mode 100644
index 00000000..06a16a40
--- /dev/null
+++ b/apps/mobile/app/dashboard/bookmarks/new.tsx
@@ -0,0 +1,76 @@
+import React, { useState } from "react";
+import { Text, View } from "react-native";
+import { router } from "expo-router";
+import { Button } from "@/components/ui/Button";
+import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
+import { Input } from "@/components/ui/Input";
+import { useToast } from "@/components/ui/Toast";
+
+import { useCreateBookmark } from "@hoarder/shared-react/hooks/bookmarks";
+import { BookmarkTypes } from "@hoarder/shared/types/bookmarks";
+
+const NoteEditorPage = () => {
+ const dismiss = () => {
+ router.back();
+ };
+
+ const [text, setText] = useState("");
+ const [error, setError] = useState<string | undefined>();
+ const { toast } = useToast();
+
+ const { mutate: createBookmark } = useCreateBookmark({
+ onSuccess: (resp) => {
+ if (resp.alreadyExists) {
+ toast({
+ message: "Bookmark already exists",
+ });
+ }
+ setText("");
+ dismiss();
+ },
+ onError: (e) => {
+ let message;
+ if (e.data?.zodError) {
+ const zodError = e.data.zodError;
+ message = JSON.stringify(zodError);
+ } else {
+ message = `Something went wrong: ${e.message}`;
+ }
+ setError(message);
+ },
+ });
+
+ const onSubmit = () => {
+ const data = text.trim();
+ try {
+ const url = new URL(data);
+ if (url.protocol != "http:" && url.protocol != "https:") {
+ throw new Error(`Unsupported URL protocol: ${url.protocol}`);
+ }
+ createBookmark({ type: BookmarkTypes.LINK, url: data });
+ } catch (e: unknown) {
+ createBookmark({ type: BookmarkTypes.TEXT, text: data });
+ }
+ };
+
+ return (
+ <CustomSafeAreaView>
+ <View className="gap-2 px-4">
+ {error && (
+ <Text className="w-full text-center text-red-500">{error}</Text>
+ )}
+ <Input
+ onChangeText={setText}
+ multiline
+ placeholder="What's on your mind?"
+ autoFocus
+ autoCapitalize={"none"}
+ textAlignVertical="top"
+ />
+ <Button onPress={onSubmit} label="Save" />
+ </View>
+ </CustomSafeAreaView>
+ );
+};
+
+export default NoteEditorPage;
diff --git a/apps/mobile/app/dashboard/lists/new.tsx b/apps/mobile/app/dashboard/lists/new.tsx
new file mode 100644
index 00000000..998638aa
--- /dev/null
+++ b/apps/mobile/app/dashboard/lists/new.tsx
@@ -0,0 +1,56 @@
+import React, { useState } from "react";
+import { Text, View } from "react-native";
+import { router } from "expo-router";
+import { Button } from "@/components/ui/Button";
+import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
+import { Input } from "@/components/ui/Input";
+import { useToast } from "@/components/ui/Toast";
+
+import { useCreateBookmarkList } from "@hoarder/shared-react/hooks/lists";
+
+const NewListPage = () => {
+ const dismiss = () => {
+ router.back();
+ };
+ const { toast } = useToast();
+ const [text, setText] = useState("");
+
+ const { mutate, isPending } = useCreateBookmarkList({
+ onSuccess: () => {
+ dismiss();
+ },
+ onError: () => {
+ toast({
+ message: "Something went wrong",
+ variant: "destructive",
+ });
+ },
+ });
+
+ const onSubmit = () => {
+ mutate({
+ name: text,
+ icon: "🚀",
+ });
+ };
+
+ return (
+ <CustomSafeAreaView>
+ <View className="gap-2 px-4">
+ <View className="flex flex-row items-center gap-1">
+ <Text className="shrink p-2">🚀</Text>
+ <Input
+ className="flex-1"
+ onChangeText={setText}
+ placeholder="List Name"
+ autoFocus
+ autoCapitalize={"none"}
+ />
+ </View>
+ <Button disabled={isPending} onPress={onSubmit} label="Save" />
+ </View>
+ </CustomSafeAreaView>
+ );
+};
+
+export default NewListPage;