aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/mobile/app/dashboard/(tabs)/_layout.tsx9
-rw-r--r--packages/mobile/app/dashboard/(tabs)/lists.tsx67
-rw-r--r--packages/mobile/app/dashboard/_layout.tsx17
-rw-r--r--packages/mobile/app/dashboard/archive.tsx11
-rw-r--r--packages/mobile/app/dashboard/favourites.tsx11
-rw-r--r--packages/mobile/app/dashboard/lists/[slug].tsx31
-rw-r--r--packages/mobile/components/bookmarks/BookmarkList.tsx14
7 files changed, 157 insertions, 3 deletions
diff --git a/packages/mobile/app/dashboard/(tabs)/_layout.tsx b/packages/mobile/app/dashboard/(tabs)/_layout.tsx
index c15f37f1..74557eda 100644
--- a/packages/mobile/app/dashboard/(tabs)/_layout.tsx
+++ b/packages/mobile/app/dashboard/(tabs)/_layout.tsx
@@ -1,5 +1,5 @@
import { Tabs } from "expo-router";
-import { Home, Settings } from "lucide-react-native";
+import { ClipboardList, Home, Settings } from "lucide-react-native";
import React from "react";
export default function TabLayout() {
@@ -13,6 +13,13 @@ export default function TabLayout() {
}}
/>
<Tabs.Screen
+ name="lists"
+ options={{
+ title: "Lists",
+ tabBarIcon: ({ color }) => <ClipboardList color={color} />,
+ }}
+ />
+ <Tabs.Screen
name="settings"
options={{
title: "Settings",
diff --git a/packages/mobile/app/dashboard/(tabs)/lists.tsx b/packages/mobile/app/dashboard/(tabs)/lists.tsx
new file mode 100644
index 00000000..b534ddda
--- /dev/null
+++ b/packages/mobile/app/dashboard/(tabs)/lists.tsx
@@ -0,0 +1,67 @@
+import { Link } from "expo-router";
+import { useEffect, useState } from "react";
+import { FlatList, View } from "react-native";
+
+import { api } from "@/lib/trpc";
+
+export default function Lists() {
+ const [refreshing, setRefreshing] = useState(false);
+ const { data: lists, isPending } = api.lists.list.useQuery();
+ const apiUtils = api.useUtils();
+
+ useEffect(() => {
+ setRefreshing(isPending);
+ }, [isPending]);
+
+ if (!lists) {
+ // Add spinner
+ return <View />;
+ }
+
+ const onRefresh = () => {
+ apiUtils.lists.list.invalidate();
+ };
+
+ const links = [
+ {
+ id: "fav",
+ logo: "⭐️",
+ name: "Favourites",
+ href: "/dashboard/favourites",
+ },
+ {
+ id: "arch",
+ logo: "🗄️",
+ name: "Archive",
+ href: "/dashboard/archive",
+ },
+ ];
+
+ links.push(
+ ...lists.lists.map((l) => ({
+ id: l.id,
+ logo: l.icon,
+ name: l.name,
+ href: `/dashboard/lists/${l.id}`,
+ })),
+ );
+
+ return (
+ <FlatList
+ contentContainerStyle={{
+ gap: 10,
+ marginTop: 10,
+ }}
+ renderItem={(l) => (
+ <View className="mx-2 block rounded-xl border border-gray-100 bg-white px-4 py-2">
+ <Link key={l.item.id} href={l.item.href} className="text-lg">
+ {l.item.logo} {l.item.name}
+ </Link>
+ </View>
+ )}
+ data={links}
+ refreshing={refreshing}
+ onRefresh={onRefresh}
+ />
+ );
+}
diff --git a/packages/mobile/app/dashboard/_layout.tsx b/packages/mobile/app/dashboard/_layout.tsx
index 590c82b1..4dd03d95 100644
--- a/packages/mobile/app/dashboard/_layout.tsx
+++ b/packages/mobile/app/dashboard/_layout.tsx
@@ -3,7 +3,22 @@ import { Stack } from "expo-router/stack";
export default function Dashboard() {
return (
<Stack>
- <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
+ <Stack.Screen
+ name="(tabs)"
+ options={{ headerShown: false, title: "Home" }}
+ />
+ <Stack.Screen
+ name="favourites"
+ options={{
+ title: "⭐️ Favourites",
+ }}
+ />
+ <Stack.Screen
+ name="archive"
+ options={{
+ title: "🗄️ Archive",
+ }}
+ />
</Stack>
);
}
diff --git a/packages/mobile/app/dashboard/archive.tsx b/packages/mobile/app/dashboard/archive.tsx
new file mode 100644
index 00000000..d75cfe22
--- /dev/null
+++ b/packages/mobile/app/dashboard/archive.tsx
@@ -0,0 +1,11 @@
+import { View } from "react-native";
+
+import BookmarkList from "@/components/bookmarks/BookmarkList";
+
+export default function Archive() {
+ return (
+ <View>
+ <BookmarkList archived />
+ </View>
+ );
+}
diff --git a/packages/mobile/app/dashboard/favourites.tsx b/packages/mobile/app/dashboard/favourites.tsx
new file mode 100644
index 00000000..90374f18
--- /dev/null
+++ b/packages/mobile/app/dashboard/favourites.tsx
@@ -0,0 +1,11 @@
+import { View } from "react-native";
+
+import BookmarkList from "@/components/bookmarks/BookmarkList";
+
+export default function Favourites() {
+ return (
+ <View>
+ <BookmarkList archived={false} favourited />
+ </View>
+ );
+}
diff --git a/packages/mobile/app/dashboard/lists/[slug].tsx b/packages/mobile/app/dashboard/lists/[slug].tsx
new file mode 100644
index 00000000..5ebc4446
--- /dev/null
+++ b/packages/mobile/app/dashboard/lists/[slug].tsx
@@ -0,0 +1,31 @@
+import { useLocalSearchParams, Stack } from "expo-router";
+import { View } from "react-native";
+
+import BookmarkList from "@/components/bookmarks/BookmarkList";
+import { api } from "@/lib/trpc";
+
+export default function ListView() {
+ const { slug } = useLocalSearchParams();
+ if (typeof slug !== "string") {
+ throw new Error("Unexpected param type");
+ }
+ const { data: list } = api.lists.get.useQuery({ listId: slug });
+
+ if (!list) {
+ // TODO: Spinner
+ return <View />;
+ }
+
+ return (
+ <>
+ <Stack.Screen
+ options={{
+ headerTitle: `${list.icon} ${list.name}`,
+ }}
+ />
+ <View>
+ <BookmarkList archived={false} ids={list.bookmarks} />
+ </View>
+ </>
+ );
+}
diff --git a/packages/mobile/components/bookmarks/BookmarkList.tsx b/packages/mobile/components/bookmarks/BookmarkList.tsx
index bb4b8668..223b1bf4 100644
--- a/packages/mobile/components/bookmarks/BookmarkList.tsx
+++ b/packages/mobile/components/bookmarks/BookmarkList.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
-import { FlatList } from "react-native";
+import { FlatList, Text, View } from "react-native";
import BookmarkCard from "./BookmarkCard";
@@ -8,9 +8,11 @@ import { api } from "@/lib/trpc";
export default function BookmarkList({
favourited,
archived,
+ ids,
}: {
favourited?: boolean;
archived?: boolean;
+ ids?: string[];
}) {
const apiUtils = api.useUtils();
const [refreshing, setRefreshing] = useState(false);
@@ -18,6 +20,7 @@ export default function BookmarkList({
api.bookmarks.getBookmarks.useQuery({
favourited,
archived,
+ ids,
});
useEffect(() => {
@@ -34,9 +37,18 @@ export default function BookmarkList({
apiUtils.bookmarks.getBookmark.invalidate();
};
+ if (!data.bookmarks.length) {
+ return (
+ <View className="h-full items-center justify-center">
+ <Text className="text-xl">No Bookmarks</Text>
+ </View>
+ );
+ }
+
return (
<FlatList
contentContainerStyle={{
+ marginTop: 10,
gap: 10,
}}
renderItem={(b) => <BookmarkCard key={b.item.id} bookmark={b.item} />}