From f1108ff488cb16754cf4570bbe0be07ab628c2d6 Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Sun, 6 Jul 2025 20:34:43 -0700 Subject: [PATCH] feat: add reader-dashboard --- next.config.ts | 27 + .../components/book-modal.tsx | 248 ++++++ .../components/book-reader-modal.tsx | 267 ++++++ .../components/header-reader.tsx | 50 ++ .../components/reader-side-navbar.tsx | 108 +++ .../discussions-and-clubs/page.tsx | 3 + src/app/reader-dashboard/layout.tsx | 26 + src/app/reader-dashboard/library/page.tsx | 827 ++++++++++++++++++ .../reader-dashboard/notifications/page.tsx | 3 + src/app/reader-dashboard/page.tsx | 18 + src/app/reader-dashboard/profile/page.tsx | 3 + .../reader-dashboard/reading-stats/page.tsx | 3 + .../reader-dashboard/transactions/page.tsx | 3 + src/app/reader-dashboard/wishlist/page.tsx | 3 + 14 files changed, 1589 insertions(+) create mode 100644 next.config.ts create mode 100644 src/app/reader-dashboard/components/book-modal.tsx create mode 100644 src/app/reader-dashboard/components/book-reader-modal.tsx create mode 100644 src/app/reader-dashboard/components/header-reader.tsx create mode 100644 src/app/reader-dashboard/components/reader-side-navbar.tsx create mode 100644 src/app/reader-dashboard/discussions-and-clubs/page.tsx create mode 100644 src/app/reader-dashboard/layout.tsx create mode 100644 src/app/reader-dashboard/library/page.tsx create mode 100644 src/app/reader-dashboard/notifications/page.tsx create mode 100644 src/app/reader-dashboard/page.tsx create mode 100644 src/app/reader-dashboard/profile/page.tsx create mode 100644 src/app/reader-dashboard/reading-stats/page.tsx create mode 100644 src/app/reader-dashboard/transactions/page.tsx create mode 100644 src/app/reader-dashboard/wishlist/page.tsx diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..1b8d344 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,27 @@ +// next.config.js +// /** @type {import('next').NextConfig} */ +// const nextConfig = { +// reactStrictMode: true, +// experimental: { +// turbo: { +// enabled: true, // Set turbo to true within an object +// }, +// }, +// }; + +// export default nextConfig; + + +// /** @type {import('next').NextConfig} */ +// const nextConfig = {}; + +// module.exports = nextConfig; + + +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/src/app/reader-dashboard/components/book-modal.tsx b/src/app/reader-dashboard/components/book-modal.tsx new file mode 100644 index 0000000..ba220ce --- /dev/null +++ b/src/app/reader-dashboard/components/book-modal.tsx @@ -0,0 +1,248 @@ +"use client" + +import { ArrowLeft, MoreHorizontal, Star, X } from "lucide-react" +import Image from "next/image" +import { useEffect, useState } from "react" +import { BookReaderModal } from "../components/book-reader-modal" +import imgbook from "../../../../public/Cover.png" +import imgbook1 from "../../../../public/user1.svg" +interface BookModalProps { + book: { + id: string + title: string + author: string + rating: number + status: "read" | "unread" | "progress" + progress?: number + isNFT?: boolean + likes?: number + verified?: boolean + } + onClose: () => void +} + +export function BookModal({ book, onClose }: BookModalProps) { + // Close modal on escape key + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === "Escape") { + onClose() + } + } + document.addEventListener("keydown", handleEscape) + return () => document.removeEventListener("keydown", handleEscape) + }, [onClose]) + + // Prevent body scroll when modal is open + useEffect(() => { + document.body.style.overflow = "hidden" + return () => { + document.body.style.overflow = "unset" + } + }, []) + + const [isReaderOpen, setIsReaderOpen] = useState(false) + + const openReader = () => { + setIsReaderOpen(true) + } + + const closeReader = () => { + setIsReaderOpen(false) + } + + return ( +
+
+ {/* Header */} +
+
+ +

Native Invisible

+
+ +
+
+ Joseph Yanum +
+
+ Joseph Yanum +
+ +
+
+
@joeyanum
+
+
+ + +
+
+ + {/* Main Content */} +
+ {/* Book Info Section */} +
+ {/* Book Cover */} +
+ {book.title} +
+ + {/* Book Details */} +
+

{book.title}

+
+ By {book.author} + {book.verified && ( +
+ +
+ )} +
+ + {/* Rating */} +
+
+ + {book.rating} +
+ of 109 Review +
+ + {/* Access Type */} +
+
Access Type
+
One-time Purchase
+
+ + {/* Reading Progress */} + {book.status === "progress" && book.progress && ( +
+ + {book.progress}% Read + +
+ )} + + {/* Continue Reading Button */} + +
+
+ + {/* Description */} +
+

Description

+

+ "Native Invisibility" delves into the complex and often insidious ways in which indigenous peoples and + their unique experiences are rendered unseen and unheard in the modern era. +

+ +
+ + {/* Book Details Grid */} +
+
+
Genre(s)
+
Fiction
+
Comic
+
+
+
Page count
+
21 Pages
+
+
+
Language
+
English
+
+
+
Date published
+
12 April, 2025
+
+
+ + {/* ISBN */} +
+
ISBN
+
978-3-16-148410-0
+
+ + {/* From Publisher & About Author */} +
+ {/* From the Publisher */} +
+

From the Publisher

+

+ Native Invisibility unveils the crucial ways indigenous cultures are often unseen in our modern world. + This vital book fosters understanding and action for recognition and justice. +

+
+ + {/* About the Author */} +
+

About the Author

+
+ {book.author} +
+
+
+ {book.author} + {book.verified && ( +
+ +
+ )} +
+ +
+
+
+

+ Darrin Collins is a dedicated researcher and writer deeply committed to exploring issues of cultural + visibility, marginalization, and the intersection of identity and technology. His work in Native + Invisibility reflects a long-standing interest in amplifying underrepresented voices and fostering a + more equitable understanding of diverse experiences in the contemporary world. +

+
+
+
+ {/* Book Reader Modal */} + {isReaderOpen && } +
+
+ ) +} diff --git a/src/app/reader-dashboard/components/book-reader-modal.tsx b/src/app/reader-dashboard/components/book-reader-modal.tsx new file mode 100644 index 0000000..5798e77 --- /dev/null +++ b/src/app/reader-dashboard/components/book-reader-modal.tsx @@ -0,0 +1,267 @@ + + +"use client" + +import { ArrowLeft, Plus, Minus, Edit, Bookmark, Highlighter, Maximize, Menu, Sun } from "lucide-react" +import { useState, useEffect } from "react" + +interface BookReaderModalProps { + book: { + id: string + title: string + author: string + progress?: number + } + onClose: () => void +} + +export function BookReaderModal({ book, onClose }: BookReaderModalProps) { + const [currentPage, setCurrentPage] = useState(1) + const [totalPages] = useState(37) + const [zoomLevel, setZoomLevel] = useState(100) + const [isLightMode, setIsLightMode] = useState(true) + + // Add theme classes based on mode + const themeClasses = { + background: isLightMode ? "bg-white" : "bg-gray-900", + text: isLightMode ? "text-gray-900" : "text-gray-100", + textSecondary: isLightMode ? "text-gray-600" : "text-gray-400", + border: isLightMode ? "border-gray-200" : "border-gray-700", + sidebarBg: isLightMode ? "bg-gray-50" : "bg-gray-800", + hover: isLightMode ? "hover:bg-gray-100" : "hover:bg-gray-700", + selectedBg: isLightMode ? "bg-blue-100" : "bg-blue-900", + selectedText: isLightMode ? "text-blue-700" : "text-blue-300", + } + const [selectedChapter, setSelectedChapter] = useState("Chapter 1") + + const tableOfContents = [ + "Cover", + "Praise", + "Title", + "Chapter 1", + "How it Started", + "Let Go", + "Chapter 2", + "How it Started", + "Where Are We", + ] + + // Close modal on escape key + useEffect(() => { + const handleEscape = (e: KeyboardEvent) => { + if (e.key === "Escape") { + onClose() + } + } + document.addEventListener("keydown", handleEscape) + return () => document.removeEventListener("keydown", handleEscape) + }, [onClose]) + + // Prevent body scroll when modal is open + useEffect(() => { + document.body.style.overflow = "hidden" + return () => { + document.body.style.overflow = "unset" + } + }, []) + + const handleZoomIn = () => { + setZoomLevel((prev) => Math.min(prev + 10, 200)) + } + + const handleZoomOut = () => { + setZoomLevel((prev) => Math.max(prev - 10, 50)) + } + + return ( +
+ {/* Header */} +
+
+

{book.title}

+ +
+ + {/* Reading Controls */} +
+ + + + + + +
+ +
+ + Page {currentPage}-{totalPages} + + + Progress {book.progress || 5}% + +
+
+ + {/* Main Content */} +
+ {/* Sidebar - Table of Contents */} +
+
+
+

Table of Content

+ +
+
+ +
+ +
+ + {/* Light Mode Toggle */} +
+ +
+
+ + {/* Content Area */} +
+
+
+

+ It was slow compared to later machines but was significant for demonstrating programmability. +

+ +

Reference:

+

+ Bashe, C. J., Johnson, L. R., Palmer, J. H., & Pugh, E. W. (1986). IBM's Early Computers. MIT Press. +

+ +

+ b. ENIAC (Electronic Numerical Integrator and Computer) (1945) +

+

+ Designed by John Presper Eckert and John Mauchly, ENIAC was the first general-purpose, fully electronic + digital computer. +

+

+ It contained 18,000 vacuum tubes and could perform up to 5,000 operations per second. +

+

+ ENIAC was used primarily for military applications, such as calculating artillery trajectories. +

+ +

Reference:

+

+ Goldstine, H. H. (1972). The Computer from Pascal to von Neumann. Princeton University Press. +

+ +

+ c. EDSAC (Electronic Delay Storage Automatic Calculator) (1949) +

+

+ Created by Maurice Wilkes at the University of Cambridge, EDSAC was the first computer to use the + stored-program concept. +

+

+ It employed mercury delay lines for memory and could execute programs stored in its memory. +

+

+ EDSAC was used in scientific research, marking a shift toward practical computation. +

+ +

Reference:

+

+ Wilkes, M. V. (1951). The Preparation of Programs for an Electronic Digital Computer. Addison-Wesley. +

+ +

+ d. UNIVAC (Universal Automatic Computer) (1951) +

+

+ Developed by Eckert and Mauchly, UNIVAC was the first commercially available computer. +

+

+ It was designed for business and government use, capable of handling both text and numeric data. +

+

+ UNIVAC's success marked the beginning of the commercial computer industry. +

+ +

Reference:

+

+ Campbell-Kelly, M., & Aspray, W. (1996). Computer: A History of the Information Machine. Basic Books. +

+ +

+ It was slow compared to later machines but was significant for demonstrating programmability. +

+ +

Reference:

+

+ Bashe, C. J., Johnson, L. R., Palmer, J. H., & Pugh, E. W. (1986). IBM's Early Computers. MIT Press. +

+ +

+ b. ENIAC (Electronic Numerical Integrator and Computer) (1945) +

+

+ Designed by John Presper Eckert and John Mauchly, ENIAC was the first general-purpose... +

+
+
+
+
+
+ ) +} diff --git a/src/app/reader-dashboard/components/header-reader.tsx b/src/app/reader-dashboard/components/header-reader.tsx new file mode 100644 index 0000000..e7d2ed7 --- /dev/null +++ b/src/app/reader-dashboard/components/header-reader.tsx @@ -0,0 +1,50 @@ +import { Bell } from "lucide-react"; +import Image from "next/image"; +import user from "../../../../public/user1.svg"; +import check from "../../../../public/check.svg"; +import Logo from "../../../../public/logo.svg"; + +export function HeaderReader() { + return ( + +
+ {/* Left Side - Logo */} +
+ Brand logo +
+ + {/* Right Side - Notification and User */} +
+
+ +
+
+
+ Profile +
+
+
+ Joseph Yanum + Verified +
+ @joeyyanum +
+
+
+ ); +} + + + diff --git a/src/app/reader-dashboard/components/reader-side-navbar.tsx b/src/app/reader-dashboard/components/reader-side-navbar.tsx new file mode 100644 index 0000000..5a6faa1 --- /dev/null +++ b/src/app/reader-dashboard/components/reader-side-navbar.tsx @@ -0,0 +1,108 @@ +"use client"; + +import { + Bell, + BookOpen, + LayoutDashboard, + MessageSquare, + DoorClosed, + User, + ClipboardList, + Heart +} from "lucide-react"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; + +export function Sidebar() { + const pathname = usePathname(); + + const navItems = [ + { + icon: LayoutDashboard, + label: "Dashboard", + href: "/reader-dashboard", + }, + { + icon: BookOpen, + label: "My Library", + href: "/reader-dashboard/library" , + }, + { + icon: DoorClosed, + label: "Reading Stats", + href: "/reader-dashboard/reading-stats", + }, + { + icon: Heart, + label: "Wishlist", + href: "/reader-dashboard/wishlist", + badge: 4, + }, + { + icon: ClipboardList, + label: "Trasactions", + href: "/reader-dashboard/transactions", + }, + { + icon: MessageSquare, + label: "Discussion & Clubs", + href: "/reader-dashboard/discussions-and-clubs", + }, + { + icon: Bell, + label: "Notification", + href: "/reader-dashboard/notifications", + }, + { + icon: User, + label: "Profile", + href: "/reader-dashboard/profile", + }, + + ]; + + return ( +
+
+
+ C +
+ ChainLib +
+ + +
+ ); +} diff --git a/src/app/reader-dashboard/discussions-and-clubs/page.tsx b/src/app/reader-dashboard/discussions-and-clubs/page.tsx new file mode 100644 index 0000000..31591c3 --- /dev/null +++ b/src/app/reader-dashboard/discussions-and-clubs/page.tsx @@ -0,0 +1,3 @@ +export default function DiscussionsPage() { + return
Discussions & Clubs
; +} diff --git a/src/app/reader-dashboard/layout.tsx b/src/app/reader-dashboard/layout.tsx new file mode 100644 index 0000000..23b324b --- /dev/null +++ b/src/app/reader-dashboard/layout.tsx @@ -0,0 +1,26 @@ + + + +import type React from "react"; +import { Sidebar } from "./components/reader-side-navbar"; +import "@/app/globals.css"; +import {HeaderReader} from "./components/header-reader"; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + +
+ +
+ {children} +
+
+ + + ); +} \ No newline at end of file diff --git a/src/app/reader-dashboard/library/page.tsx b/src/app/reader-dashboard/library/page.tsx new file mode 100644 index 0000000..7abb815 --- /dev/null +++ b/src/app/reader-dashboard/library/page.tsx @@ -0,0 +1,827 @@ + + + + +"use client" + +import type React from "react" +import { useState } from "react" +import { Search, ChevronDown, BookOpen, Users, Bookmark, CheckCircle, Clock, Eye } from "lucide-react" +import Image from "next/image" +import { BookModal } from "../components/book-modal" +import imgbook from "../../../../public/Cover.png" + +interface StatCard { + title: string + value: number + icon: React.ReactNode + color: string +} + +interface Book { + id: string + title: string + author: string + rating: number + status: "read" | "unread" | "progress" + progress?: number + isNFT?: boolean + likes?: number + verified?: boolean +} + +interface Collection { + id: string + title: string + rating: number + likes: number + owners: number + books: string[] +} + +const statCards: StatCard[] = [ + { + title: "Total Books", + value: 24, + icon: , + color: "bg-blue-100 text-blue-600", + }, + { + title: "Regular Book", + value: 12, + icon: , + color: "bg-green-100 text-green-600", + }, + { + title: "NTF Editions", + value: 4, + icon: , + color: "bg-purple-100 text-purple-600", + }, + { + title: "Series", + value: 8, + icon: , + color: "bg-orange-100 text-orange-600", + }, + { + title: "Collections", + value: 3, + icon: , + color: "bg-indigo-100 text-indigo-600", + }, + { + title: "Read", + value: 3, + icon: , + color: "bg-blue-100 text-blue-600", + }, + { + title: "Progress", + value: 3, + icon: , + color: "bg-blue-100 text-blue-600", + }, + { + title: "Unread", + value: 3, + icon: , + color: "bg-blue-100 text-blue-600", + }, +] + +const recentBooks: Book[] = [ + { + id: "1", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 5, + verified: true, + }, + { + id: "2", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + isNFT: true, + verified: true, + }, + { + id: "3", + title: "Dark World", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + likes: 5, + verified: true, + }, + { + id: "4", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 5, + verified: true, + }, +] + +const regularBooks: Book[] = [ + { + id: "5", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 5, + verified: true, + }, + { + id: "6", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "read", + verified: true, + }, + { + id: "7", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + verified: true, + }, + { + id: "8", + title: "Native Invisibility", + author: "Darrin Collins", + rating: 4.5, + status: "read", + verified: true, + }, +] + +const nftBooks: Book[] = [ + { + id: "9", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 97, + isNFT: true, + verified: true, + }, + { + id: "10", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "read", + isNFT: true, + verified: true, + }, + { + id: "11", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + isNFT: true, + verified: true, + }, + { + id: "12", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + isNFT: true, + verified: true, + }, +] + +const seriesBooks: Book[] = [ + { + id: "13", + title: "Love at Night", + author: "Darrin Collins", + rating: 4.5, + status: "read", + likes: 4, + verified: true, + }, + { + id: "14", + title: "Love at Night", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 46, + likes: 5, + verified: true, + }, + { + id: "15", + title: "Dark World", + author: "Darrin Collins", + rating: 4.5, + status: "unread", + likes: 5, + verified: true, + }, + { + id: "16", + title: "Peace and Hate", + author: "Darrin Collins", + rating: 4.5, + status: "progress", + progress: 79, + likes: 5, + verified: true, + }, +] + +const collections: Collection[] = [ + { + id: "1", + title: "My Best Boook", + rating: 4.5, + likes: 5, + owners: 10, + books: ["book1", "book2", "book3"], + }, + { + id: "2", + title: "My Best Boook", + rating: 4.5, + likes: 5, + owners: 10, + books: ["book1", "book2", "book3"], + }, + { + id: "3", + title: "My Best Boook", + rating: 4.5, + likes: 5, + owners: 10, + books: ["book1", "book2", "book3"], + }, + { + id: "4", + title: "My Best Boook", + rating: 4.5, + likes: 5, + owners: 10, + books: ["book1", "book2", "book3"], + }, +] + +export default function BookLibraryDashboard() { + const [searchQuery, setSearchQuery] = useState("") + const [bookType, setBookType] = useState("Book Type") + const [genre, setGenre] = useState("Genre") + const [bookTypeOpen, setBookTypeOpen] = useState(false) + const [genreOpen, setGenreOpen] = useState(false) + + const [selectedBook, setSelectedBook] = useState(null) + const [isModalOpen, setIsModalOpen] = useState(false) + + const openBookModal = (book: Book) => { + setSelectedBook(book) + setIsModalOpen(true) + } + + const closeBookModal = () => { + setSelectedBook(null) + setIsModalOpen(false) + } + + return ( +
+
+ {/* Search and Filters */} +
+
+ + setSearchQuery(e.target.value)} + className="w-full pl-10 h-12 bg-white border border-gray-200 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" + /> +
+ +
+ {/* Book Type Dropdown */} +
+ + {bookTypeOpen && ( +
+ + + +
+ )} +
+ + {/* Genre Dropdown */} +
+ + {genreOpen && ( +
+ + + + +
+ )} +
+
+
+ + {/* Statistics Cards */} +
+ {statCards.map((card, index) => ( +
+
+
{card.icon}
+
+
+

{card.title}

+

{card.value}

+
+
+ ))} +
+ + {/* Recently Purchased Section */} +
+
+

Recently Purchased

+ +
+ +
+ {recentBooks.map((book) => ( +
openBookModal(book)} + className="bg-white border border-gray-200 rounded-xl shadow-sm hover:shadow-md transition-shadow overflow-hidden cursor-pointer" + > +
+
+ {book.title} +
+ + {/* Status Badges */} +
+ {book.status === "progress" && book.progress && ( + + {book.progress}% Read + + )} + {book.status === "unread" && ( + + Unread + + )} + {book.isNFT && ( + + NFT + + )} +
+
+ +
+

{book.title}

+
+

By {book.author}

+ {book.verified && ( +
+ +
+ )} +
+ +
+
+
+ {Array.from({ length: Math.floor(book.rating) }, (_, i) => ( + + ))} +
+ {book.rating} +
+ + {book.likes && ( +
+ {book.likes} +
+ )} +
+
+
+ ))} +
+
+ + {/* Regular Books Section */} +
+
+

Regular Books

+ +
+ +
+ {regularBooks.map((book) => ( +
openBookModal(book)} + className="bg-white border border-gray-200 rounded-xl shadow-sm hover:shadow-md transition-shadow overflow-hidden cursor-pointer" + > +
+
+ {book.title} +
+ + {/* Status Badges */} +
+ {book.status === "progress" && book.progress && ( + + {book.progress}% Read + + )} + {book.status === "read" && ( + + Completed + + )} + {book.status === "unread" && ( + + Unread + + )} +
+
+ +
+

{book.title}

+
+

By {book.author}

+ {book.verified && ( +
+ +
+ )} +
+ +
+
+
+ {Array.from({ length: Math.floor(book.rating) }, (_, i) => ( + + ))} +
+ {book.rating} +
+
+
+
+ ))} +
+
+ + {/* NFT Edition Section */} +
+
+

NFT Edition

+ +
+ +
+ {nftBooks.map((book) => ( +
openBookModal(book)} + className="bg-white border border-gray-200 rounded-xl shadow-sm hover:shadow-md transition-shadow overflow-hidden cursor-pointer" + > +
+
+ {book.title} +
+ + {/* Status Badges */} +
+ {book.status === "progress" && book.progress && ( + + {book.progress}% Read + + )} + {book.status === "read" && ( + + Completed + + )} + {book.status === "unread" && ( + + Unread + + )} + {book.isNFT && ( + + NFT + + )} +
+
+ +
+

{book.title}

+
+

By {book.author}

+ {book.verified && ( +
+ +
+ )} +
+ +
+
+
+ {Array.from({ length: Math.floor(book.rating) }, (_, i) => ( + + ))} +
+ {book.rating} +
+
+
+
+ ))} +
+
+ + {/* Series Section */} +
+
+

Series

+ +
+ +
+ {seriesBooks.map((book) => ( +
openBookModal(book)} + className="bg-white border border-gray-200 rounded-xl shadow-sm hover:shadow-md transition-shadow overflow-hidden cursor-pointer" + > +
+
+ {book.title} +
+ + {/* Status Badges */} +
+ {book.status === "progress" && book.progress && ( + + {book.progress}% Read + + )} + {book.status === "read" && ( + + Completed + + )} + {book.status === "unread" && ( + + Unread + + )} +
+
+ +
+

{book.title}

+
+

By {book.author}

+ {book.verified && ( +
+ +
+ )} +
+ +
+
+
+ {Array.from({ length: Math.floor(book.rating) }, (_, i) => ( + + ))} +
+ {book.rating} +
+ + {book.likes && ( +
+ {book.likes} +
+ )} +
+
+
+ ))} +
+
+ + {/* Collections Section */} +
+
+

Collections

+ +
+ +
+ {collections.map((collection) => ( +
+ {/* Collection Books Grid */} +
+
+ {/* Top row - 2 books */} +
+ Book cover +
+
+ Book cover +
+ {/* Bottom row - 1 book + Add More */} +
+ Book cover +
+
+ + Add More +
+
+ +
+

{collection.title}

+ +
+
+
+ {Array.from({ length: Math.floor(collection.rating) }, (_, i) => ( + + ))} +
+ {collection.rating} +
+ +
+
+ {collection.likes} +
+
+
+ {collection.owners} +
+ Owners +
+
+
+
+
+
+ ))} +
+
+ {/* Book Modal */} + {isModalOpen && selectedBook && } +
+
+ ) +} diff --git a/src/app/reader-dashboard/notifications/page.tsx b/src/app/reader-dashboard/notifications/page.tsx new file mode 100644 index 0000000..680a38e --- /dev/null +++ b/src/app/reader-dashboard/notifications/page.tsx @@ -0,0 +1,3 @@ +export default function NotificationsPage() { + return
Notifications
; +} diff --git a/src/app/reader-dashboard/page.tsx b/src/app/reader-dashboard/page.tsx new file mode 100644 index 0000000..8146b82 --- /dev/null +++ b/src/app/reader-dashboard/page.tsx @@ -0,0 +1,18 @@ +"use-client"; + + +export default function DashboardHome() { + return ( +
+
+

Reader Dashboard

+

Welcome to your personalized reading space!

+
+
+ ); +} + + + + + diff --git a/src/app/reader-dashboard/profile/page.tsx b/src/app/reader-dashboard/profile/page.tsx new file mode 100644 index 0000000..6917dde --- /dev/null +++ b/src/app/reader-dashboard/profile/page.tsx @@ -0,0 +1,3 @@ +export default function ProfilePage() { + return
Profile Settings
; +} \ No newline at end of file diff --git a/src/app/reader-dashboard/reading-stats/page.tsx b/src/app/reader-dashboard/reading-stats/page.tsx new file mode 100644 index 0000000..84fcd1e --- /dev/null +++ b/src/app/reader-dashboard/reading-stats/page.tsx @@ -0,0 +1,3 @@ +export default function ReadingStatsPage() { + return
Reading Stats
; +} \ No newline at end of file diff --git a/src/app/reader-dashboard/transactions/page.tsx b/src/app/reader-dashboard/transactions/page.tsx new file mode 100644 index 0000000..4bbd3d3 --- /dev/null +++ b/src/app/reader-dashboard/transactions/page.tsx @@ -0,0 +1,3 @@ +export default function TransactionsPage() { + return
Transactions
; +} diff --git a/src/app/reader-dashboard/wishlist/page.tsx b/src/app/reader-dashboard/wishlist/page.tsx new file mode 100644 index 0000000..3aad659 --- /dev/null +++ b/src/app/reader-dashboard/wishlist/page.tsx @@ -0,0 +1,3 @@ +export default function WishlistPage() { + return
Wishlist
; +} \ No newline at end of file