diff --git a/mobile/Components/StatisticsTab/StatisticsTab.tsx b/mobile/Components/StatisticsTab/StatisticsTab.tsx index 1123033a..14fd0c9d 100644 --- a/mobile/Components/StatisticsTab/StatisticsTab.tsx +++ b/mobile/Components/StatisticsTab/StatisticsTab.tsx @@ -13,86 +13,106 @@ import { BarChart } from "react-native-chart-kit"; import ID from "../../Constants/ID"; import { client } from "../../appwrite"; import BookStatusCount from "../BookStatusCount"; +import Backend from "@/Backend"; +import useSWR from "swr"; const databases = new Databases(client); +const backend = new Backend(); + +interface BookInfo { + id: string; + title: string; + author: string; + image_url: string; +} + +const LABELS = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +]; + +async function getBookInfo(book_id: string): Promise { + const book_document = await databases.getDocument( + ID.mainDBID, + ID.bookCollectionID, + book_id, + ); + if (book_document) { + return { + id: book_document.$id, + title: book_document.title, + author: book_document.authors[0].name, + image_url: book_document.editions[0].thumbnail_url, + }; + } + return undefined; +} -const StatisticsTab = () => { - const [loading, setLoading] = React.useState(true); // State variable to track loading status - async function getBookInfo(book_id: string) { - const bookInfo = []; - const account = new Account(client); - let user_id; - try { - user_id = (await account.get()).$id; - } catch (error: any) { - console.warn( - "An unknown error occurred attempting to fetch user details.", - ); - return bookInfo; - } - const book_document = await databases.getDocument( - ID.mainDBID, - ID.bookCollectionID, - book_id, - ); - if (book_document) { - bookInfo.push({ - id: book_document.$id, - title: book_document.title, - author: book_document.authors[0].name, - image_url: book_document.editions[0].thumbnail_url, +async function fetchData() { + const user_id = await backend.getUserId(); + + const queryResponse = await databases.listDocuments( + ID.mainDBID, + ID.bookStatusCollectionID, + [Query.equal("user_id", user_id)], + ); + + const documents = queryResponse.documents.filter( + (doc) => doc.status === "READ", + ); + + const activities = []; + + for (const document of documents) { + const bookInfo = await getBookInfo(document.book.$id); + + if (bookInfo) { + activities.push({ + key: document.$id, + status: document.status, + username: document.user_id, + book: bookInfo, + timestamp: document.$createdAt, }); } - return bookInfo; } - const [activity, setActivity] = React.useState([]); + return activities; +} + +const StatisticsTab = () => { + const { data, error, isLoading, mutate } = useSWR( + { func: fetchData, arg: null }, + backend.swrFetcher, + ); + useFocusEffect( React.useCallback(() => { - const fetchData = async () => { - try { - setLoading(true); - const account = new Account(client); - const response = await account.get(); - const user_id = response.$id; - - const databases = new Databases(client); - const queryResponse = await databases.listDocuments( - ID.mainDBID, - ID.bookStatusCollectionID, - [Query.equal("user_id", user_id)], - ); - - const documents = queryResponse.documents.filter( - (doc) => doc.status === "READ", - ); - - const updatedActivity = await Promise.all( - documents.map(async (document) => { - const bookInfo = await getBookInfo(document.book.$id); - return { - key: document.$id, - status: document.status, - username: document.user_id, - book: bookInfo[0], - timestamp: document.$createdAt, - }; - }), - ); - - setActivity(updatedActivity); - setLoading(false); - } catch (error) { - console.error("Error fetching user data:", error); - setLoading(false); - } - }; - - fetchData(); - }, []), + mutate(); + }, [mutate]), ); - const authorsRead = activity.reduce((acc, cur) => { + if (isLoading) { + return ( + + ); + } + + const authorsRead = data.reduce((acc, cur) => { const author = cur.book.author; acc[author] = (acc[author] || 0) + 1; return acc; @@ -106,111 +126,78 @@ const StatisticsTab = () => { const bookCounts = Array(12).fill(0); - activity.forEach((cur) => { + data.forEach((cur) => { const monthIndex = new Date(cur.timestamp).getMonth(); bookCounts[monthIndex]++; }); - const datasets = [ - { - data: bookCounts, - }, - ]; - const labels = [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - ]; - - const data = { - labels: labels, - datasets: datasets, + const barchartData = { + labels: LABELS, + datasets: [{ data: bookCounts }], }; return ( Your Stats - {loading && ( - - )} - {!loading && ( - <> - - - - Books Read by Month: - - - {labels.map((month, index) => ( - {`${month}: ${bookCounts[index]} books`} - ))} - - - - - - - Most Read Author: {mostReadAuthor} - - + + + Books Read by Month: + + {LABELS.map((month, index) => ( + {`${month}: ${bookCounts[index]} books`} + ))} - `rgba(52, 152, 219, ${opacity})`, - labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`, - style: { - borderRadius: 16, - }, - barPercentage: 0.5, - propsForLabels: { - fontSize: 10, - }, - }} - /> - - - )} + + + + + + Most Read Author: {mostReadAuthor} + + + + `rgba(52, 152, 219, ${opacity})`, + labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`, + style: { + borderRadius: 16, + }, + barPercentage: 0.5, + propsForLabels: { + fontSize: 10, + }, + }} + /> + ); };