Loading...
;
+ if (bookError || reviewsError) return Loading top books...
;
+ }
+
+ if (error) {
+ return (
+
+ Error loading books. Please try again later.
+
+ );
+ }
+
+ if (!Array.isArray(books) || books.length === 0) {
+ return No books found.
;
+ }
+
+ return (
+
+ {books.map((book: any, idx: number) => {
+ const bookId = book.id || book._id || idx;
+ return (
+
+
+ #{idx + 1}
+
+
{book.title}
+
+
+ ★
+
+ {Number(book.avgRating).toFixed(2) ?? 'N/A'} / 5.0
+
+
+
+
+ {book.reviews?.length ?? 0} review
+ {(book.reviews?.length ?? 0) !== 1 && 's'}
+
+
+
+ 📖 View Details
+
+
+ );
+ })}
+
+ );
+};
+
+export default BookList;
diff --git a/components/ReactQueryProvider.tsx b/components/ReactQueryProvider.tsx
new file mode 100644
index 0000000..6eacfbb
--- /dev/null
+++ b/components/ReactQueryProvider.tsx
@@ -0,0 +1,8 @@
+'use client';
+import { QueryClient, QueryClientProvider } from 'react-query';
+import React, { ReactNode, useState } from 'react';
+
+export default function ReactQueryProvider({ children }: { children: ReactNode }) {
+ const [queryClient] = useState(() => new QueryClient());
+ return