From 380b7b2e77307283678c8ed2def6c5fedc90ab61 Mon Sep 17 00:00:00 2001 From: S-Dhruv Date: Thu, 24 Jul 2025 00:14:24 +0530 Subject: [PATCH 1/5] Added Analytics Page --- package.json | 2 +- src/app/analytics/page.tsx | 75 ++++++++ src/app/book-lisiting-page/page.tsx | 2 - src/components/analytics/ChartDetails.tsx | 31 +++ src/components/analytics/ReaderAnalytics.tsx | 86 +++++++++ src/components/analytics/SignUpChart.tsx | 57 ++++++ src/components/analytics/WritersAnalytics.tsx | 178 ++++++++++++++++++ 7 files changed, 428 insertions(+), 3 deletions(-) create mode 100644 src/app/analytics/page.tsx create mode 100644 src/components/analytics/ChartDetails.tsx create mode 100644 src/components/analytics/ReaderAnalytics.tsx create mode 100644 src/components/analytics/SignUpChart.tsx create mode 100644 src/components/analytics/WritersAnalytics.tsx diff --git a/package.json b/package.json index eb3d0fa..c2b91ef 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "react-dom": "^18.3.1", "react-hot-toast": "^2.5.2", "react-icons": "^5.5.0", - "recharts": "^2.15.3", + "recharts": "^2.15.4", "sharp": "^0.33.5", "starknet": "^6.23.1", "starknetkit": "^2.12.1", diff --git a/src/app/analytics/page.tsx b/src/app/analytics/page.tsx new file mode 100644 index 0000000..9843798 --- /dev/null +++ b/src/app/analytics/page.tsx @@ -0,0 +1,75 @@ +"use client"; + +import React, { useState } from "react"; +import SignupChart from "@/components/analytics/SignUpChart"; +import ChartDetails from "@/components/analytics/ChartDetails"; +import ReadersAnalytics from "@/components/analytics/ReaderAnalytics"; +import WritersAnalytics from "@/components/analytics/WritersAnalytics"; +const Page = () => { + const [selectedTab, setSelectedTab] = useState("This Week"); + const [fromDate, setFromDate] = useState(""); + const [toDate, setToDate] = useState(""); + + const tabs = ["This Week", "This Month", "This Year", "All Time"]; + + return ( +
+

Total Signups

+ +
+
+ {tabs.map((tab) => ( + + ))} +
+ +
+ setFromDate(e.target.value)} + className="border border-gray-300 rounded-md px-2 py-1 text-sm" + /> + to + setToDate(e.target.value)} + className="border border-gray-300 rounded-md px-2 py-1 text-sm" + /> + +
+
+ +
+
+ +
+
+ +
+
+ + +
+ ); +}; + +export default Page; diff --git a/src/app/book-lisiting-page/page.tsx b/src/app/book-lisiting-page/page.tsx index 5513879..fc3363d 100644 --- a/src/app/book-lisiting-page/page.tsx +++ b/src/app/book-lisiting-page/page.tsx @@ -74,8 +74,6 @@ export default function Page() { - - return (
diff --git a/src/components/analytics/ChartDetails.tsx b/src/components/analytics/ChartDetails.tsx new file mode 100644 index 0000000..3efeb55 --- /dev/null +++ b/src/components/analytics/ChartDetails.tsx @@ -0,0 +1,31 @@ +"use client"; +import React from "react"; + +const stats = [ + { label: "Total Writers", value: "3,566" }, + { label: "Total Readers", value: "105,094" }, + { label: "Active Writers", value: "27" }, + { label: "Active Readers", value: "459" }, + { label: "Total Books", value: "10,903" }, + { label: "Total Revenue", value: "$370.00" }, +]; + +const ChartDetails = () => { + return ( +
+
+ {stats.map((s, i) => ( +
+

{s.label}

+

{s.value}

+
+ ))} +
+
+ ); +}; + +export default ChartDetails; diff --git a/src/components/analytics/ReaderAnalytics.tsx b/src/components/analytics/ReaderAnalytics.tsx new file mode 100644 index 0000000..a5bbad6 --- /dev/null +++ b/src/components/analytics/ReaderAnalytics.tsx @@ -0,0 +1,86 @@ +import { + PieChart, + Pie, + Cell, + Tooltip, + Legend, + ResponsiveContainer, +} from "recharts"; + +const genreData = [ + { name: "Fiction", value: 40, color: "#2F80ED" }, + { name: "Fantasy", value: 10, color: "#27AE60" }, + { name: "Science", value: 11, color: "#EB5757" }, + { name: "Romance", value: 12, color: "#9B51E0" }, + { name: "Mystery", value: 10, color: "#F2C94C" }, +]; + +const stats = [ + { label: "Total Readers", value: 3566 }, + { label: "Active Subscription", value: 2210 }, + { label: "Expired Subscription", value: 597 }, + { label: "Active Readers", value: 27 }, + { label: "Suspended", value: 459 }, +]; + +export default function ReadersAnalytics() { + return ( +
+

Readers Analytics

+ +
+ {["This Week", "This Month", "This Year", "All Time"].map((label) => ( + + ))} +
+ + to + + +
+
+ +
+
+ + + + {genreData.map((entry, index) => ( + + ))} + + + + + +
+ +
+ {stats.map((stat, idx) => ( +
+

{stat.label}

+

+ {stat.value.toLocaleString()} +

+
+ ))} +
+
+
+ ); +} diff --git a/src/components/analytics/SignUpChart.tsx b/src/components/analytics/SignUpChart.tsx new file mode 100644 index 0000000..35e42be --- /dev/null +++ b/src/components/analytics/SignUpChart.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { + LineChart, + Line, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + ResponsiveContainer, + Legend, +} from "recharts"; + +const data = [ + { name: "Mon", Readers: 35, Writers: 22 }, + { name: "Tue", Readers: 45, Writers: 30 }, + { name: "Wed", Readers: 48, Writers: 33 }, + { name: "Thu", Readers: 40, Writers: 28 }, + { name: "Fri", Readers: 35, Writers: 55 }, + { name: "Sat", Readers: 60, Writers: 40 }, + { name: "Sun", Readers: 58, Writers: 38 }, +]; + +const SignupChart = () => { + return ( +
+ + + + + + + + + + + +
+ ); +}; + +export default SignupChart; diff --git a/src/components/analytics/WritersAnalytics.tsx b/src/components/analytics/WritersAnalytics.tsx new file mode 100644 index 0000000..899414a --- /dev/null +++ b/src/components/analytics/WritersAnalytics.tsx @@ -0,0 +1,178 @@ +import { + PieChart, + Pie, + Cell, + Tooltip, + Legend, + ResponsiveContainer, +} from "recharts"; +import { Star } from "lucide-react"; + +const genreData = [ + { name: "Fiction", value: 40, color: "#2F80ED" }, + { name: "Fantasy", value: 10, color: "#27AE60" }, + { name: "Science", value: 11, color: "#EB5757" }, + { name: "Romance", value: 12, color: "#9B51E0" }, + { name: "Mystery", value: 10, color: "#F2C94C" }, +]; + +const writerStats = [ + { label: "Verified Writers", value: 3566 }, + { label: "Unverified Writers", value: 546 }, + { label: "Active Writers", value: 27 }, + { label: "Suspended", value: 459 }, + { label: "Regular Book", value: 27 }, + { label: "NFT Edition", value: 459 }, + { label: "Total Published", value: 27 }, +]; + +const bookStats = [ + { label: "Read", value: 192, change: "-22%" }, + { label: "Read Compl Rate", value: "75%", change: "+8%" }, + { label: "Sale", value: 62, change: "+9%" }, + { label: "Total Earning", value: "3150.00" }, + { label: "Average Rating", value: 3.5 }, +]; + +const topBooks = [ + "The Act", + "Live at Night", + "Prince of Peace", + "Late Every Night", + "The 91 Law of Power", +]; + +export default function WritersAnalytics() { + return ( +
+

Writers Analytics

+ + {/* Filters */} +
+ {["This Week", "This Month", "This Year", "All Time"].map((label) => ( + + ))} + +
+ + to + + +
+
+ +
+
+ + + + {genreData.map((entry, index) => ( + + ))} + + + + + +
+ +
+ {writerStats.map((stat, i) => ( +
+

{stat.label}

+

+ {stat.value.toLocaleString()} +

+
+ ))} +
+
+ +
+
+

+ Stats for The Act +

+
+ {bookStats.map((stat, i) => ( +
+
+

{stat.label}

+

+ {stat.label === "Total Earning" ? ( + `$${stat.value}` + ) : stat.label === "Average Rating" ? ( + + {" "} + {stat.value} + + ) : ( + stat.value + )} +

+
+ {stat.change && ( + + {stat.change} + + )} +
+ ))} +
+
+ +
+
+

Top Performing Books

+ +
+
    + {topBooks.map((book, i) => ( +
  • + + {i + 1}.{" "} + {book} + + +
  • + ))} +
+
+
+
+ ); +} From 02c5a7e882e5c05e95dd6646a67c7a27ab2ea645 Mon Sep 17 00:00:00 2001 From: S-Dhruv Date: Thu, 24 Jul 2025 00:52:50 +0530 Subject: [PATCH 2/5] Added admin-dashboard and changed the next.config.js for external images --- next.config.js | 15 ++- src/app/admin-dashboard/page.tsx | 31 +++++ src/assets/data/dummyData.ts | 126 ++++++++++++++++++ src/components/analytics/AuthorCard.tsx | 25 ++++ src/components/analytics/BookCard.tsx | 49 +++++++ src/components/analytics/Header.tsx | 32 +++++ src/components/analytics/Icon.tsx | 77 +++++++++++ src/components/analytics/PayoutRequests.tsx | 51 +++++++ .../analytics/PayoutRequestsRow.tsx | 42 ++++++ src/components/analytics/StatCard.tsx | 31 +++++ src/components/analytics/TopAuthors.tsx | 20 +++ src/components/analytics/Transactions.tsx | 44 ++++++ src/components/analytics/TrendingBooks.tsx | 20 +++ 13 files changed, 556 insertions(+), 7 deletions(-) create mode 100644 src/app/admin-dashboard/page.tsx create mode 100644 src/assets/data/dummyData.ts create mode 100644 src/components/analytics/AuthorCard.tsx create mode 100644 src/components/analytics/BookCard.tsx create mode 100644 src/components/analytics/Header.tsx create mode 100644 src/components/analytics/Icon.tsx create mode 100644 src/components/analytics/PayoutRequests.tsx create mode 100644 src/components/analytics/PayoutRequestsRow.tsx create mode 100644 src/components/analytics/StatCard.tsx create mode 100644 src/components/analytics/TopAuthors.tsx create mode 100644 src/components/analytics/Transactions.tsx create mode 100644 src/components/analytics/TrendingBooks.tsx diff --git a/next.config.js b/next.config.js index d0a1a48..c578203 100644 --- a/next.config.js +++ b/next.config.js @@ -2,15 +2,16 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - experimental: { - turbo: { - enabled: true, // Set turbo to true within an object - }, - }, images: { - domains: ['randomuser.me'], + remotePatterns: [ + { + protocol: 'https', + hostname: 'placehold.co', + port: '', + pathname: '/**', + }, + ], }, - }; // export default nextConfig; diff --git a/src/app/admin-dashboard/page.tsx b/src/app/admin-dashboard/page.tsx new file mode 100644 index 0000000..d72a158 --- /dev/null +++ b/src/app/admin-dashboard/page.tsx @@ -0,0 +1,31 @@ +"use client" +import StatCard from "@/components/analytics/StatCard"; +import { stats } from "../../assets/data/dummyData"; +import Transactions from "@/components/analytics/Transactions"; +import PayoutRequests from "@/components/analytics/PayoutRequests"; +import TrendingBooks from "@/components/analytics/TrendingBooks"; +import TopAuthors from "@/components/analytics/TopAuthors"; +import Header from "@/components/analytics/Header"; + +const DashboardPage = () => { + return ( +
+
+
+
+ {stats.map((stat, index) => ( + + ))} +
+
+ +
+ + + +
+
+ ); +}; + +export default DashboardPage; diff --git a/src/assets/data/dummyData.ts b/src/assets/data/dummyData.ts new file mode 100644 index 0000000..6b9e5e4 --- /dev/null +++ b/src/assets/data/dummyData.ts @@ -0,0 +1,126 @@ +export const stats = [ + { + title: "Number of Regular", + value: "257", + icon: "briefcase", + color: "bg-blue-100", + textColor: "text-blue-500", + }, + { + title: "NFT Books", + value: "83", + icon: "book", + color: "bg-purple-100", + textColor: "text-purple-500", + }, + { + title: "Readers", + value: "1093", + icon: "users", + color: "bg-green-100", + textColor: "text-green-500", + }, + { + title: "Writers", + value: "204", + icon: "wallet", + color: "bg-orange-100", + textColor: "text-orange-500", + }, +] as const; +export const payoutRequests = [ + { + author: "Olu Ademola", + email: "oluade..@gmail.com", + amount: "900.67 STR", + wallet: "0xABC...789", + date: "27 May, 2025", + status: "Pending", + }, + { + author: "Olu Ademola", + email: "oluade..@gmail.com", + amount: "900.67 STR", + wallet: "0xABC...789", + date: "27 May, 2025", + status: "Pending", + }, + { + author: "Olu Ademola", + email: "oluade..@gmail.com", + amount: "900.67 STR", + wallet: "0xABC...789", + date: "27 May, 2025", + status: "Pending", + }, + { + author: "Olu Ademola", + email: "oluade..@gmail.com", + amount: "900.67 STR", + wallet: "0xABC...789", + date: "27 May, 2025", + status: "Pending", + }, + { + author: "Olu Ademola", + email: "oluade..@gmail.com", + amount: "900.67 STR", + wallet: "0xABC...789", + date: "27 May, 2025", + status: "Pending", + }, +]; + +export const trendingBooks = [ + { + title: "Native Invisibility", + author: "by Darrin Collins", + price: "193 STRK", + rating: 4.5, + cover: "/placeholder-image.png", + }, + { + title: "Native Invisibility", + author: "by Darrin Collins", + price: "193 STRK", + rating: 4.5, + cover: "/placeholder-image.png", + }, + { + title: "Native Invisibility", + author: "by Darrin Collins", + price: "193 STRK", + rating: 4.5, + cover: "/placeholder-image.png", + }, + { + title: "Native Invisibility", + author: "by Darrin Collins", + price: "193 STRK", + rating: 4.5, + cover: "/placeholder-image.png", + }, +]; + +export const topAuthors = [ + { + name: "Elizabeth Joe", + image: "https://placehold.co/150x150/E0E0E0/000000?text=E.J", + }, + { + name: "Alex Paul", + image: "https://placehold.co/150x150/D0D0D0/000000?text=A.P", + }, + { + name: "Samson Toluwase", + image: "https://placehold.co/150x150/C0C0C0/000000?text=S.T", + }, + { + name: "Vansika Maya", + image: "https://placehold.co/150x150/B0B0B0/000000?text=V.M", + }, + { + name: "Samson Toluwase", + image: "https://placehold.co/150x150/A0A0A0/000000?text=S.T", + }, +]; diff --git a/src/components/analytics/AuthorCard.tsx b/src/components/analytics/AuthorCard.tsx new file mode 100644 index 0000000..86b141d --- /dev/null +++ b/src/components/analytics/AuthorCard.tsx @@ -0,0 +1,25 @@ +"use client"; +import Image from "next/image"; + +type AuthorCardProps = { + name: string; + image: string; +}; + +const AuthorCard: React.FC = ({ name, image }) => ( +
+ {name} { + (e.target as HTMLImageElement).src = + "https://placehold.co/100x100/CCCCCC/000000?text=Author"; + }} + /> +

{name}

+
+); +export default AuthorCard; diff --git a/src/components/analytics/BookCard.tsx b/src/components/analytics/BookCard.tsx new file mode 100644 index 0000000..29e5f7f --- /dev/null +++ b/src/components/analytics/BookCard.tsx @@ -0,0 +1,49 @@ +"use client"; +import Image from "next/image"; + +type BookCardProps = { + title: string; + author: string; + price: string; + rating: number; + cover: string; +}; + +const BookCard: React.FC = ({ + title, + author, + price, + rating, + cover, +}) => ( +
+ {title} { + (e.target as HTMLImageElement).src = + "https://placehold.co/60x80/E0E0E0/000000?text=Book"; + }} + /> +
+

{title}

+

{author}

+

{price}

+
+ + + + {rating} +
+
+
+); +export default BookCard; diff --git a/src/components/analytics/Header.tsx b/src/components/analytics/Header.tsx new file mode 100644 index 0000000..a1e9156 --- /dev/null +++ b/src/components/analytics/Header.tsx @@ -0,0 +1,32 @@ +"use client" +const Header = () => ( +
+
+ + + +
+
+ + to + + + +
+
+); +export default Header; diff --git a/src/components/analytics/Icon.tsx b/src/components/analytics/Icon.tsx new file mode 100644 index 0000000..e7c611f --- /dev/null +++ b/src/components/analytics/Icon.tsx @@ -0,0 +1,77 @@ +"use client" +import React from "react"; + +type IconName = + | "briefcase" + | "book" + | "users" + | "wallet" + | "chevron-down" + | "arrow-up"; + +type IconProps = { + name: IconName; +} & React.SVGProps; + +const iconPaths: Record = { + briefcase: ( + + ), + book: ( + + ), + users: ( + + ), + wallet: ( + + ), + "chevron-down": ( + + ), + "arrow-up": ( + + ), +}; + +const Icon: React.FC = ({ name, ...props }) => { + return ( + + {iconPaths[name]} + + ); +}; + +export default Icon; diff --git a/src/components/analytics/PayoutRequests.tsx b/src/components/analytics/PayoutRequests.tsx new file mode 100644 index 0000000..8f1f322 --- /dev/null +++ b/src/components/analytics/PayoutRequests.tsx @@ -0,0 +1,51 @@ +"use client" +import { payoutRequests } from "../../assets/data/dummyData"; +import PayoutRequestRow from "./PayoutRequestsRow"; +import Icon from "./Icon"; + +const PayoutRequests = () => ( +
+
+

+ New Payout Requests +

+ +
+
+ + + + + + + + + + + + + {payoutRequests.map((request, index) => ( + + ))} + +
+ Author + + Amount + + Wallet Address + + Request Date + + Status +
+
+
+

Showing 1 to 5 of 12

+ +
+
+); +export default PayoutRequests; diff --git a/src/components/analytics/PayoutRequestsRow.tsx b/src/components/analytics/PayoutRequestsRow.tsx new file mode 100644 index 0000000..341e9fc --- /dev/null +++ b/src/components/analytics/PayoutRequestsRow.tsx @@ -0,0 +1,42 @@ +"use client" +type PayoutRequestRowProps = { + author: string; + email: string; + amount: string; + wallet: string; + date: string; + status: string; +}; + +const PayoutRequestRow: React.FC = ({ + author, + email, + amount, + wallet, + date, + status, +}) => ( + + +

{author}

+

{email}

+ + {amount} + {wallet} + {date} + + + {status} + + + + + + + +); +export default PayoutRequestRow; diff --git a/src/components/analytics/StatCard.tsx b/src/components/analytics/StatCard.tsx new file mode 100644 index 0000000..3e5eb0d --- /dev/null +++ b/src/components/analytics/StatCard.tsx @@ -0,0 +1,31 @@ +"use client" +import Icon from "./Icon"; + +type StatCardProps = { + title: string, + value: string, + icon: "briefcase" | "book" | "users" | "wallet", + color: string, + textColor: string, +}; + +const StatCard: React.FC = ({ + title, + value, + icon, + color, + textColor, +}) => { + return ( +
+
+ +
+
+

{title}

+

{value}

+
+
+ ); +}; +export default StatCard; diff --git a/src/components/analytics/TopAuthors.tsx b/src/components/analytics/TopAuthors.tsx new file mode 100644 index 0000000..4086cdb --- /dev/null +++ b/src/components/analytics/TopAuthors.tsx @@ -0,0 +1,20 @@ +"use client" +import { topAuthors } from "../../assets/data/dummyData"; +import AuthorCard from "./AuthorCard"; + +const TopAuthors = () => ( +
+
+

Top Authors

+ +
+
+ {topAuthors.map((author, index) => ( + + ))} +
+
+); +export default TopAuthors; diff --git a/src/components/analytics/Transactions.tsx b/src/components/analytics/Transactions.tsx new file mode 100644 index 0000000..455393d --- /dev/null +++ b/src/components/analytics/Transactions.tsx @@ -0,0 +1,44 @@ +"use client" +import Icon from "./Icon"; + +const Transactions = () => ( +
+
+

Transactions

+ +
+
+
+

Total Transactions

+

109,837.06

+
+ 20% + +
+
+
+

Commission Eared

+

+ 21,070.93 STR +

+

Pending Payout

+

+ 12,070.93 STR +

+
+
+

Payout Sent

+

+ 51,070.93 STR +

+

Payout Sent

+

+ 21,070.93 STR +

+
+
+
+); +export default Transactions; diff --git a/src/components/analytics/TrendingBooks.tsx b/src/components/analytics/TrendingBooks.tsx new file mode 100644 index 0000000..e3b7141 --- /dev/null +++ b/src/components/analytics/TrendingBooks.tsx @@ -0,0 +1,20 @@ +"use client"; +import { trendingBooks } from "../../assets/data/dummyData"; +import BookCard from "./BookCard"; + +const TrendingBooks = () => ( +
+
+

Trending Books

+ +
+
+ {trendingBooks.map((book, index) => ( + + ))} +
+
+); +export default TrendingBooks; From 8a9954711323343f115e256798ab749b622bbb4e Mon Sep 17 00:00:00 2001 From: S-Dhruv Date: Thu, 24 Jul 2025 16:29:32 +0530 Subject: [PATCH 3/5] Adjusted Dashboard and Analytics --- next.config.js | 22 +++---- src/app/admin-dashboard/page.tsx | 31 --------- src/app/analytics/page.tsx | 75 --------------------- src/app/dashboard/admin/analytics/page.tsx | 77 ++++++++++++++++++---- src/app/dashboard/admin/page.tsx | 31 +++++---- src/assets/data/dummyData.ts | 8 +-- src/components/analytics/AuthorCard.tsx | 8 +-- src/components/analytics/BookCard.tsx | 8 +-- src/components/analytics/Icon.tsx | 2 +- 9 files changed, 106 insertions(+), 156 deletions(-) delete mode 100644 src/app/admin-dashboard/page.tsx delete mode 100644 src/app/analytics/page.tsx diff --git a/next.config.js b/next.config.js index c578203..4f1486c 100644 --- a/next.config.js +++ b/next.config.js @@ -1,25 +1,25 @@ // next.config.js + /** @type {import('next').NextConfig} */ + const nextConfig = { reactStrictMode: true, + + experimental: { + turbo: { + enabled: true, // Set turbo to true within an object + }, + }, + images: { - remotePatterns: [ - { - protocol: 'https', - hostname: 'placehold.co', - port: '', - pathname: '/**', - }, - ], + domains: ["randomuser.me"], }, }; // export default nextConfig; - // /** @type {import('next').NextConfig} */ + // const nextConfig = {}; // module.exports = nextConfig; - - diff --git a/src/app/admin-dashboard/page.tsx b/src/app/admin-dashboard/page.tsx deleted file mode 100644 index d72a158..0000000 --- a/src/app/admin-dashboard/page.tsx +++ /dev/null @@ -1,31 +0,0 @@ -"use client" -import StatCard from "@/components/analytics/StatCard"; -import { stats } from "../../assets/data/dummyData"; -import Transactions from "@/components/analytics/Transactions"; -import PayoutRequests from "@/components/analytics/PayoutRequests"; -import TrendingBooks from "@/components/analytics/TrendingBooks"; -import TopAuthors from "@/components/analytics/TopAuthors"; -import Header from "@/components/analytics/Header"; - -const DashboardPage = () => { - return ( -
-
-
-
- {stats.map((stat, index) => ( - - ))} -
-
- -
- - - -
-
- ); -}; - -export default DashboardPage; diff --git a/src/app/analytics/page.tsx b/src/app/analytics/page.tsx deleted file mode 100644 index 9843798..0000000 --- a/src/app/analytics/page.tsx +++ /dev/null @@ -1,75 +0,0 @@ -"use client"; - -import React, { useState } from "react"; -import SignupChart from "@/components/analytics/SignUpChart"; -import ChartDetails from "@/components/analytics/ChartDetails"; -import ReadersAnalytics from "@/components/analytics/ReaderAnalytics"; -import WritersAnalytics from "@/components/analytics/WritersAnalytics"; -const Page = () => { - const [selectedTab, setSelectedTab] = useState("This Week"); - const [fromDate, setFromDate] = useState(""); - const [toDate, setToDate] = useState(""); - - const tabs = ["This Week", "This Month", "This Year", "All Time"]; - - return ( -
-

Total Signups

- -
-
- {tabs.map((tab) => ( - - ))} -
- -
- setFromDate(e.target.value)} - className="border border-gray-300 rounded-md px-2 py-1 text-sm" - /> - to - setToDate(e.target.value)} - className="border border-gray-300 rounded-md px-2 py-1 text-sm" - /> - -
-
- -
-
- -
-
- -
-
- - -
- ); -}; - -export default Page; diff --git a/src/app/dashboard/admin/analytics/page.tsx b/src/app/dashboard/admin/analytics/page.tsx index b08df33..f29a025 100644 --- a/src/app/dashboard/admin/analytics/page.tsx +++ b/src/app/dashboard/admin/analytics/page.tsx @@ -1,21 +1,76 @@ -"use-client"; +"use client"; +import React, { useState } from "react"; import { Header } from "@/components/dashboard/header"; - - +import SignupChart from "@/components/analytics/SignUpChart"; +import ChartDetails from "@/components/analytics/ChartDetails"; +import ReadersAnalytics from "@/components/analytics/ReaderAnalytics"; +import WritersAnalytics from "@/components/analytics/WritersAnalytics"; export default function Analytics() { + const [selectedTab, setSelectedTab] = useState("This Week"); + const [fromDate, setFromDate] = useState(""); + const [toDate, setToDate] = useState(""); + + const tabs = ["This Week", "This Month", "This Year", "All Time"]; - return ( <>
-
-
-

Analytics

-

- Welcome to Analytics -

+
+

Total Signups

+ +
+
+ {tabs.map((tab) => ( + + ))} +
+ +
+ setFromDate(e.target.value)} + className="border border-gray-300 rounded-md px-2 py-1 text-sm" + /> + to + setToDate(e.target.value)} + className="border border-gray-300 rounded-md px-2 py-1 text-sm" + /> + +
+
+ +
+
+ +
+
+ +
-
+ + + ); } diff --git a/src/app/dashboard/admin/page.tsx b/src/app/dashboard/admin/page.tsx index 8452c0d..fb13140 100644 --- a/src/app/dashboard/admin/page.tsx +++ b/src/app/dashboard/admin/page.tsx @@ -1,24 +1,33 @@ -"use-client"; +"use client"; +import StatCard from "@/components/analytics/StatCard"; +import { stats } from "@/assets/data/dummyData"; +import Transactions from "@/components/analytics/Transactions"; +import PayoutRequests from "@/components/analytics/PayoutRequests"; +import TrendingBooks from "@/components/analytics/TrendingBooks"; +import TopAuthors from "@/components/analytics/TopAuthors"; import StarknetProvider from "@/components/blockchain/StarknetProviders"; import { WalletProvider } from "@/components/blockchain/wallet-connect-context"; import { Header } from "@/components/dashboard/header"; - export default function DashboardHome() { - return ( <>
-
-
-

- Admin Dashboard -

-

- Welcome to your personalized admin space! -

+
+
+
+ {stats.map((stat, index) => ( + + ))} +
+
+ +
+ + +
diff --git a/src/assets/data/dummyData.ts b/src/assets/data/dummyData.ts index 6b9e5e4..d0ac141 100644 --- a/src/assets/data/dummyData.ts +++ b/src/assets/data/dummyData.ts @@ -77,28 +77,28 @@ export const trendingBooks = [ author: "by Darrin Collins", price: "193 STRK", rating: 4.5, - cover: "/placeholder-image.png", + cover: "", }, { title: "Native Invisibility", author: "by Darrin Collins", price: "193 STRK", rating: 4.5, - cover: "/placeholder-image.png", + cover: "", }, { title: "Native Invisibility", author: "by Darrin Collins", price: "193 STRK", rating: 4.5, - cover: "/placeholder-image.png", + cover: "", }, { title: "Native Invisibility", author: "by Darrin Collins", price: "193 STRK", rating: 4.5, - cover: "/placeholder-image.png", + cover: "", }, ]; diff --git a/src/components/analytics/AuthorCard.tsx b/src/components/analytics/AuthorCard.tsx index 86b141d..30c8ff6 100644 --- a/src/components/analytics/AuthorCard.tsx +++ b/src/components/analytics/AuthorCard.tsx @@ -1,6 +1,6 @@ "use client"; import Image from "next/image"; - +import Image2 from "@/assets/Images/footerimage.png"; type AuthorCardProps = { name: string; image: string; @@ -9,15 +9,11 @@ type AuthorCardProps = { const AuthorCard: React.FC = ({ name, image }) => (
{name} { - (e.target as HTMLImageElement).src = - "https://placehold.co/100x100/CCCCCC/000000?text=Author"; - }} />

{name}

diff --git a/src/components/analytics/BookCard.tsx b/src/components/analytics/BookCard.tsx index 29e5f7f..6cf00d6 100644 --- a/src/components/analytics/BookCard.tsx +++ b/src/components/analytics/BookCard.tsx @@ -1,6 +1,6 @@ "use client"; import Image from "next/image"; - +import Image2 from "@/assets/Images/footerimage.png"; type BookCardProps = { title: string; author: string; @@ -18,15 +18,11 @@ const BookCard: React.FC = ({ }) => (
{title} { - (e.target as HTMLImageElement).src = - "https://placehold.co/60x80/E0E0E0/000000?text=Book"; - }} />

{title}

diff --git a/src/components/analytics/Icon.tsx b/src/components/analytics/Icon.tsx index e7c611f..f2737e9 100644 --- a/src/components/analytics/Icon.tsx +++ b/src/components/analytics/Icon.tsx @@ -1,4 +1,4 @@ -"use client" +"use client"; import React from "react"; type IconName = From daf851e666c526adcde0fe4f0402c33329da26c7 Mon Sep 17 00:00:00 2001 From: S-Dhruv Date: Mon, 28 Jul 2025 14:38:20 +0530 Subject: [PATCH 4/5] Redesigned to make it look like the FIGMA design --- src/app/dashboard/admin/analytics/page.tsx | 7 +- src/app/dashboard/admin/page.tsx | 253 +++++++++++++++++- src/assets/icons/Book.tsx | 21 ++ src/assets/icons/Book2.tsx | 19 ++ src/assets/icons/Icon.tsx | 31 +++ src/assets/icons/Reader.tsx | 19 ++ src/assets/icons/Writer.tsx | 19 ++ src/components/analytics/ChartDetails.tsx | 2 +- src/components/analytics/ReaderAnalytics.tsx | 4 +- src/components/analytics/WritersAnalytics.tsx | 3 +- 10 files changed, 359 insertions(+), 19 deletions(-) create mode 100644 src/assets/icons/Book.tsx create mode 100644 src/assets/icons/Book2.tsx create mode 100644 src/assets/icons/Icon.tsx create mode 100644 src/assets/icons/Reader.tsx create mode 100644 src/assets/icons/Writer.tsx diff --git a/src/app/dashboard/admin/analytics/page.tsx b/src/app/dashboard/admin/analytics/page.tsx index f29a025..0cbe486 100644 --- a/src/app/dashboard/admin/analytics/page.tsx +++ b/src/app/dashboard/admin/analytics/page.tsx @@ -60,14 +60,15 @@ export default function Analytics() {
-
-
+
+
-
+
+ diff --git a/src/app/dashboard/admin/page.tsx b/src/app/dashboard/admin/page.tsx index fb13140..67db596 100644 --- a/src/app/dashboard/admin/page.tsx +++ b/src/app/dashboard/admin/page.tsx @@ -8,26 +8,257 @@ import TopAuthors from "@/components/analytics/TopAuthors"; import StarknetProvider from "@/components/blockchain/StarknetProviders"; import { WalletProvider } from "@/components/blockchain/wallet-connect-context"; import { Header } from "@/components/dashboard/header"; - +import Icon from "@/assets/icons/Icon"; +import Book from "@/assets/icons/Book"; +import Reader from "@/assets/icons/Reader"; +import Writer from "@/assets/icons/Writer"; +import { + BookOpenText, + ImagePlus, + BookCopy, + BookMarked, + Filter, +} from "lucide-react"; +import Book2 from "@/assets/icons/Book2"; +const books = new Array(4).fill({ + title: "Native Invisibility", + author: "Darrin Collins", + price: "193 STRK", + rating: 4.5, + imgSrc: "https://m.media-amazon.com/images/I/81af+MCATTL.jpg", +}); +const statCard = (label: string, value: string) => ( +
+

{label}

+
+

{value} STR

+ +
+
+); export default function DashboardHome() { return ( <>
-
-
-
- {stats.map((stat, index) => ( - +
+
+ {[ + { + label: "Number of Regular", + value: "257", + color: "text-blue-600", + icon: , + }, + { + label: "NFT Books", + value: "83", + color: "text-purple-600", + icon: , + }, + { + label: "Readers", + value: "1093", + color: "text-green-600", + icon: , + }, + { + label: "Writers", + value: "204", + color: "text-orange-500", + icon: , + }, + ].map((card, idx) => ( +
+
+
+

{card.label}

+ {card.icon} +
+

+ {card.value} +

+
+
+ ))} +
+ +
+
+

+ Transactions +

+
+ +
+
+

Total Transactions

+
+ +

+ 109,837.06 +

+
+ + 20% ▲ + +
+ +
+ {statCard("Commission Eared", "21,070.93")} + {statCard("Payout Sent", "51,070.93")} + {statCard("Pending Payout", "12,070.93")} + {statCard("Payout Sent", "21,070.93")} +
+
+
+ +
+
+

New Payout Requests

+ +
+
+ + + + + + + + + + + + + {Array(5) + .fill(0) + .map((_, i) => ( + + + + + + + + + ))} + +
AuthorAmountWallet AddressRequest DateStatusActions
+
+

Olu Ademola

+

+ olusx_dgmail.com +

+
+
+
+ + 500.67 STR +
+
0xABC...78927 May,2025 + + Pending + + + + +
+
+ Showing 1 to 5 of 12 +
+
+
+ +
+

Trending Books

+
+ {books.map((book, idx) => ( +
+ Book +
+

{book.title}

+

+ By {book.author}{" "} +

+
+
+ {" "} + {book.price} +
+
+
+ {book.rating} +
+
+
))}
-
- +
+ +
+
+

Top Authors

+ +
+ +
+ {[ + { + name: "Elizabeth Joe", + img: "https://randomuser.me/api/portraits/women/65.jpg", + }, + { + name: "Alex Paul", + img: "https://randomuser.me/api/portraits/men/32.jpg", + }, + { + name: "Samson Tersoor", + img: "https://randomuser.me/api/portraits/men/77.jpg", + }, + { + name: "Vamika Maya", + img: "https://randomuser.me/api/portraits/women/49.jpg", + }, + { + name: "Samson Tersoor", + img: "https://randomuser.me/api/portraits/women/44.jpg", + }, + ].map((author, i) => ( +
+
+ {author.name} +
+
+ ))}
- - -
diff --git a/src/assets/icons/Book.tsx b/src/assets/icons/Book.tsx new file mode 100644 index 0000000..07dd8be --- /dev/null +++ b/src/assets/icons/Book.tsx @@ -0,0 +1,21 @@ +// CheckIcon.tsx +const Book = (props: React.SVGProps) => ( + // CheckIcon.tsx + + + + +); + +export default Book; diff --git a/src/assets/icons/Book2.tsx b/src/assets/icons/Book2.tsx new file mode 100644 index 0000000..aa345b4 --- /dev/null +++ b/src/assets/icons/Book2.tsx @@ -0,0 +1,19 @@ +// CheckIcon.tsx +const Book2 = (props: React.SVGProps) => ( + // CheckIcon.tsx + + + + +); + +export default Book2; diff --git a/src/assets/icons/Icon.tsx b/src/assets/icons/Icon.tsx new file mode 100644 index 0000000..4c5c5e8 --- /dev/null +++ b/src/assets/icons/Icon.tsx @@ -0,0 +1,31 @@ +const Icon = (props: React.SVGProps) => ( + + + + + + + + + +); + +export default Icon; diff --git a/src/assets/icons/Reader.tsx b/src/assets/icons/Reader.tsx new file mode 100644 index 0000000..9307ce3 --- /dev/null +++ b/src/assets/icons/Reader.tsx @@ -0,0 +1,19 @@ +// CheckIcon.tsx +const Reader = (props: React.SVGProps) => ( + // CheckIcon.tsx + + + + +); + +export default Reader; diff --git a/src/assets/icons/Writer.tsx b/src/assets/icons/Writer.tsx new file mode 100644 index 0000000..43239e5 --- /dev/null +++ b/src/assets/icons/Writer.tsx @@ -0,0 +1,19 @@ +// CheckIcon.tsx +const Writer = (props: React.SVGProps) => ( + // CheckIcon.tsx + + + + +); + +export default Writer; diff --git a/src/components/analytics/ChartDetails.tsx b/src/components/analytics/ChartDetails.tsx index 3efeb55..aa79da9 100644 --- a/src/components/analytics/ChartDetails.tsx +++ b/src/components/analytics/ChartDetails.tsx @@ -12,7 +12,7 @@ const stats = [ const ChartDetails = () => { return ( -
+
{stats.map((s, i) => (
-
-
+
+

Writers Analytics

- {/* Filters */}
{["This Week", "This Month", "This Year", "All Time"].map((label) => (