From 464b33ea9bf91a9fa94caa2130ef83a3c8e8922e Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Thu, 29 May 2025 16:04:45 +0100 Subject: [PATCH 1/7] Setup earnings page and implemented earnings summary tab amd the link wallet section --- public/braavos.svg | 9 ++ public/paste-icon.svg | 3 + src/app/book-lisiting-page/page.tsx | 5 +- src/app/dashboard/earnings/page.tsx | 53 +++++++-- .../ dashboard-earnings/EarningSummary.tsx | 39 +++++++ .../ dashboard-earnings/LinkWallet.tsx | 102 ++++++++++++++++++ src/components/layout/Footer.tsx | 10 -- src/components/layout/Header.tsx | 11 -- src/lib/interfaces/EarningTabInterface.ts | 8 ++ src/lib/utils.ts | 42 ++++++++ 10 files changed, 250 insertions(+), 32 deletions(-) create mode 100644 public/braavos.svg create mode 100644 public/paste-icon.svg create mode 100644 src/components/ dashboard-earnings/EarningSummary.tsx create mode 100644 src/components/ dashboard-earnings/LinkWallet.tsx delete mode 100644 src/components/layout/Footer.tsx delete mode 100644 src/components/layout/Header.tsx create mode 100644 src/lib/interfaces/EarningTabInterface.ts diff --git a/public/braavos.svg b/public/braavos.svg new file mode 100644 index 0000000..19f7949 --- /dev/null +++ b/public/braavos.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/paste-icon.svg b/public/paste-icon.svg new file mode 100644 index 0000000..64f21d4 --- /dev/null +++ b/public/paste-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/app/book-lisiting-page/page.tsx b/src/app/book-lisiting-page/page.tsx index 5fb04a4..5b00548 100644 --- a/src/app/book-lisiting-page/page.tsx +++ b/src/app/book-lisiting-page/page.tsx @@ -6,8 +6,6 @@ import ExploreBooks from "@/components/BookListingPage/ExploreBooks"; import NewRelease from "@/components/BookListingPage/NewRelease"; import NftEdition from "@/components/BookListingPage/NftEdition"; import Trending from "@/components/BookListingPage/Trending"; -import Footer from "@/components/layout/Footer"; -import Header from "@/components/layout/Header"; import { Input } from "@/components/ui/input"; import bookData from "@/lib/MockData"; import { useMemo, useState } from "react"; @@ -80,7 +78,6 @@ export default function Page() { return (
-
@@ -99,7 +96,7 @@ export default function Page() { -
+
) } \ No newline at end of file diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index ee55de9..62778f2 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -1,15 +1,54 @@ +"use client" +import EarningsSummary from "@/components/ dashboard-earnings/EarningSummary" +import LinkWallet from "@/components/ dashboard-earnings/LinkWallet" +import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" +import { useEffect, useState } from "react" + +const earningsSumaryDetails: EarningTab[] = [ + { title: "Current Balance", amount: 3150.0, border: "border-[var(--color-primary-100)]" }, + { title: "Pending Payout", amount: 100.06, border: "border-[#2396413D]" }, + { title: "Total Payout", amount: 2500.01, border: "border-[#822ECB3D]" }, + { title: "Total Earned", amount: 2730.19, border: "border-[var(--color-primary-100)]" }, +] function EarningsPage() { + const [walletAddress, setWalletAddress] = useState({ + braavos: "", + argent: "", + }) + + const ADDRESS_KEY = "walletAddressKey" + + // This function loads saved addresses + useEffect(() => { + const savedAddresses = localStorage.getItem(ADDRESS_KEY) + if (savedAddresses) { + try { + const parsedAddresses = JSON.parse(savedAddresses) + setWalletAddress(parsedAddresses) + } + catch (error) { + console.error("Failed to parse saved addresses:", error) + } + } + }, []) + + + // this function saves wallet address to local storage + useEffect(() => { + if (walletAddress.braavos || walletAddress.argent) { + localStorage.setItem(ADDRESS_KEY, JSON.stringify(walletAddress)) + } + }, [walletAddress]) + return ( -
-

Earnings

-

- This is the earnings page. You can view your earnings here. -

+
+ +
- ); + ) } -export default EarningsPage; \ No newline at end of file +export default EarningsPage diff --git a/src/components/ dashboard-earnings/EarningSummary.tsx b/src/components/ dashboard-earnings/EarningSummary.tsx new file mode 100644 index 0000000..bf5016a --- /dev/null +++ b/src/components/ dashboard-earnings/EarningSummary.tsx @@ -0,0 +1,39 @@ +import { EarningTab } from "@/lib/interfaces/EarningTabInterface"; +import { Button } from "../ui/button"; +import Image from "next/image"; + + +interface EarningsSummaryProps { + earningsSumaryDetails: EarningTab[]; +} + +const +EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { + return ( +
+
+ {earningsSumaryDetails.map((item, index) => ( +
+

{item.title}

+ +
+icon +

{item.amount.toFixed(2)}

+
+ +
+ ))} +
+ + + + + +
+ ); +}; + +export default EarningsSummary; diff --git a/src/components/ dashboard-earnings/LinkWallet.tsx b/src/components/ dashboard-earnings/LinkWallet.tsx new file mode 100644 index 0000000..38871e7 --- /dev/null +++ b/src/components/ dashboard-earnings/LinkWallet.tsx @@ -0,0 +1,102 @@ +"use client" + +import type React from "react" + +import Image from "next/image" +import { Input } from "../ui/input" +import { handlePaste } from "../../lib/utils" + +interface WalletAddressType { + braavos: string + argent: string +} + +interface LinkWalletProps { + walletAddress: WalletAddressType + setWalletAddress: React.Dispatch> +} + +export default function LinkWallet({ walletAddress, setWalletAddress }: LinkWalletProps) { + const handleChange = (e: React.FormEvent) => { + const target = e.target as HTMLInputElement + const { name, value } = target + + setWalletAddress((prev) => ({ + ...prev, + [name]: value, + })) + } + + return ( +
+
+

Link Wallet

+ + Change Wallet Address + +
+ +
+
+
+
+ Wallet Icon +

+ Braavos (Starknet) +

+
+
+ +
+ + +
+
+ +
+
+
+ Wallet Icon +

+ Argent (Starknet) +

+
+
+ +
+ + +
+
+
+
+ ) +} diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx deleted file mode 100644 index f1f436c..0000000 --- a/src/components/layout/Footer.tsx +++ /dev/null @@ -1,10 +0,0 @@ - - -function Footer (){ - return( -

Footer

- ) -} - - -export default Footer; \ No newline at end of file diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx deleted file mode 100644 index 8e633cd..0000000 --- a/src/components/layout/Header.tsx +++ /dev/null @@ -1,11 +0,0 @@ - - - -function Header(){ - return( -

Header

- ) -} - - -export default Header; \ No newline at end of file diff --git a/src/lib/interfaces/EarningTabInterface.ts b/src/lib/interfaces/EarningTabInterface.ts new file mode 100644 index 0000000..ceb0e3d --- /dev/null +++ b/src/lib/interfaces/EarningTabInterface.ts @@ -0,0 +1,8 @@ + + +export interface EarningTab { + title: string; + amount: number; + border: string +} + diff --git a/src/lib/utils.ts b/src/lib/utils.ts index bd0c391..f34cc6b 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,3 +4,45 @@ import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } + + +interface WalletAddressType { + braavos: string + argent: string +} + +export const handlePaste = async ( + walletType: string, + setWalletAddress: React.Dispatch>, +) => { + try { + if (!navigator.clipboard) { + throw new Error("Clipboard API not available") + } + + const clipboardText = await navigator.clipboard.readText() + + + setWalletAddress((prev) => ({ + ...prev, + [walletType]: clipboardText.trim(), + })) + + console.log(`Pasted to ${walletType}:`, clipboardText.trim()) + return clipboardText.trim() + } catch (error) { + console.error("Failed to read clipboard:", error) + + + const fallbackText = prompt("Clipboard access denied. Please paste your wallet address:") + if (fallbackText) { + setWalletAddress((prev) => ({ + ...prev, + [walletType]: fallbackText.trim(), + })) + return fallbackText.trim() + } + + return null + } +} From 051e818706a623e5d7ad30b33dd6c662e9eb859d Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Sat, 31 May 2025 12:47:50 +0100 Subject: [PATCH 2/7] added a seection --- package.json | 2 + src/app/dashboard/earnings/page.tsx | 42 +++++++++++++-- src/components/ dashboard-earnings/Chart.tsx | 51 +++++++++++++++++++ .../ dashboard-earnings/EarningSummary.tsx | 41 +++++++-------- .../ dashboard-earnings/RevenueBreakdown.tsx | 40 +++++++++++++++ src/lib/interfaces/RevenueChartInterface.ts | 6 +++ 6 files changed, 155 insertions(+), 27 deletions(-) create mode 100644 src/components/ dashboard-earnings/Chart.tsx create mode 100644 src/components/ dashboard-earnings/RevenueBreakdown.tsx create mode 100644 src/lib/interfaces/RevenueChartInterface.ts diff --git a/package.json b/package.json index d11cd1a..97cd779 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@starknet-react/chains": "^3.1.2", "@starknet-react/core": "^3.7.2", "@starknet-react/typescript-config": "^0.0.1", + "chart.js": "^4.4.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "framer-motion": "^12.5.0", @@ -34,6 +35,7 @@ "react-dom": "^18.3.1", "react-hot-toast": "^2.5.2", "react-icons": "^5.5.0", + "recharts": "^2.15.3", "sharp": "^0.33.5", "starknet": "^6.23.1", "tailwind-merge": "^2.6.0", diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index 62778f2..8d5a110 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -3,16 +3,47 @@ import EarningsSummary from "@/components/ dashboard-earnings/EarningSummary" import LinkWallet from "@/components/ dashboard-earnings/LinkWallet" +import RevenueBreakdown from "@/components/ dashboard-earnings/RevenueBreakdown" import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" +import { RevenueChartInterface } from "@/lib/interfaces/RevenueChartInterface" import { useEffect, useState } from "react" const earningsSumaryDetails: EarningTab[] = [ - { title: "Current Balance", amount: 3150.0, border: "border-[var(--color-primary-100)]" }, - { title: "Pending Payout", amount: 100.06, border: "border-[#2396413D]" }, - { title: "Total Payout", amount: 2500.01, border: "border-[#822ECB3D]" }, - { title: "Total Earned", amount: 2730.19, border: "border-[var(--color-primary-100)]" }, + { title: "Current Balance", amount: 3150.0 , border: "#D6ECFF" }, + { title: "Pending Payout", amount: 100.06, border: "#2396413D" }, + { title: "Total Payout", amount: 2500.01, border: "#822ECB3D" }, + { title: "Total Earned", amount: 2730.19, border: "#D6ECFF" }, ] +const chartData: RevenueChartInterface[] = [ + { + name: "Monthly Subcription Payment", + value: 121, + color: "#236FEA", + percentage: "40%" + }, + { + name: "NFT Royalty", + value: 12, + color: "#FBBC05", + percentage: "10%" + }, + { + name: "NFT", + value: 101, + color: "#822ECB", + percentage: "22%" + }, + { + name: "Book Purchase", + value: 131, + color: "#34A853", + percentage: "28%" + }, +] + + + function EarningsPage() { const [walletAddress, setWalletAddress] = useState({ braavos: "", @@ -46,7 +77,8 @@ function EarningsPage() { return (
- + +
) } diff --git a/src/components/ dashboard-earnings/Chart.tsx b/src/components/ dashboard-earnings/Chart.tsx new file mode 100644 index 0000000..fb7cdb3 --- /dev/null +++ b/src/components/ dashboard-earnings/Chart.tsx @@ -0,0 +1,51 @@ +import { RevenueChartInterface } from "@/lib/interfaces/RevenueChartInterface"; +import { + BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, + Cell +} from 'recharts'; + + + +interface RevenueChartProps { + chartData: RevenueChartInterface[] +} + + + +export default function RevenueChart({chartData}: RevenueChartProps) { + + + + console.log(chartData) + + + + + return ( + +
+ + + + + `$${value}`} tick={{ dy: 10 }} tickLine={false} axisLine={{ stroke: '#D1D1D1', strokeWidth: 1 }} /> + + + + {chartData.map((entry, index) => ( + + ))} + + + + + + + +
+ ) +} \ No newline at end of file diff --git a/src/components/ dashboard-earnings/EarningSummary.tsx b/src/components/ dashboard-earnings/EarningSummary.tsx index bf5016a..30a6178 100644 --- a/src/components/ dashboard-earnings/EarningSummary.tsx +++ b/src/components/ dashboard-earnings/EarningSummary.tsx @@ -1,39 +1,36 @@ -import { EarningTab } from "@/lib/interfaces/EarningTabInterface"; -import { Button } from "../ui/button"; -import Image from "next/image"; - +import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" +import { Button } from "../ui/button" +import Image from "next/image" interface EarningsSummaryProps { - earningsSumaryDetails: EarningTab[]; + earningsSumaryDetails: EarningTab[] } -const -EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { +const EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { return ( -
-
+
+
{earningsSumaryDetails.map((item, index) => (
-

{item.title}

+

{item.title}

-
-icon -

{item.amount.toFixed(2)}

+
+ icon +

{item.amount.toFixed(2)}

-
))}
- - - - +
- ); -}; + ) +} -export default EarningsSummary; +export default EarningsSummary diff --git a/src/components/ dashboard-earnings/RevenueBreakdown.tsx b/src/components/ dashboard-earnings/RevenueBreakdown.tsx new file mode 100644 index 0000000..12a22de --- /dev/null +++ b/src/components/ dashboard-earnings/RevenueBreakdown.tsx @@ -0,0 +1,40 @@ +import { RevenueChartInterface } from "@/lib/interfaces/RevenueChartInterface"; +import RevenueChart from "./Chart"; + + + + +interface RevenueBreakdownProps { + chartData: RevenueChartInterface[] +} + + + + +export default function RevenueBreakdown({ chartData }: RevenueBreakdownProps) { + return ( +
+ +

Revenue Breakdown

+ + + + + +
+ + + + + +
    + + {chartData.map((item, index) => ( +
  • {item.name}
  • + ))} + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/lib/interfaces/RevenueChartInterface.ts b/src/lib/interfaces/RevenueChartInterface.ts new file mode 100644 index 0000000..4ee3d84 --- /dev/null +++ b/src/lib/interfaces/RevenueChartInterface.ts @@ -0,0 +1,6 @@ +export interface RevenueChartInterface { + name: string; + color: string; + value: number; + percentage: string; +} From 2aba7dc5e1096d47cccf64c24b8a22f2b62bb1bc Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Sat, 31 May 2025 15:33:11 +0100 Subject: [PATCH 3/7] transaction history --- src/app/dashboard/earnings/page.tsx | 2 + .../ dashboard-earnings/RevenueBreakdown.tsx | 2 +- .../TransactionHistory.tsx | 84 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/components/ dashboard-earnings/TransactionHistory.tsx diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index 8d5a110..e1082da 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -7,6 +7,7 @@ import RevenueBreakdown from "@/components/ dashboard-earnings/RevenueBreakdown" import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" import { RevenueChartInterface } from "@/lib/interfaces/RevenueChartInterface" import { useEffect, useState } from "react" +import TransactionHistory from "../../../components/ dashboard-earnings/TransactionHistory" const earningsSumaryDetails: EarningTab[] = [ { title: "Current Balance", amount: 3150.0 , border: "#D6ECFF" }, @@ -77,6 +78,7 @@ function EarningsPage() { return (
+
diff --git a/src/components/ dashboard-earnings/RevenueBreakdown.tsx b/src/components/ dashboard-earnings/RevenueBreakdown.tsx index 12a22de..6ad0258 100644 --- a/src/components/ dashboard-earnings/RevenueBreakdown.tsx +++ b/src/components/ dashboard-earnings/RevenueBreakdown.tsx @@ -13,7 +13,7 @@ interface RevenueBreakdownProps { export default function RevenueBreakdown({ chartData }: RevenueBreakdownProps) { return ( -
+

Revenue Breakdown

diff --git a/src/components/ dashboard-earnings/TransactionHistory.tsx b/src/components/ dashboard-earnings/TransactionHistory.tsx new file mode 100644 index 0000000..183ee3e --- /dev/null +++ b/src/components/ dashboard-earnings/TransactionHistory.tsx @@ -0,0 +1,84 @@ +import { ChevronLeft, ChevronRight } from "lucide-react"; +import { Button } from "../ui/button"; + + + + + +export default function TransactionHistory () { + return ( +
+

Transaction History

+
+ + +
+
+ + + + +
+ + +
+ +
+ +to + +
+ +
+ +
+ + + +
+ + + + + + + +
+

+ Showing 1 to 5 of 12 +

+ + + + +
+ +
+ + +
+ + +
+ + + + + + + + + + +
+ + + + + + +
+
+
+ ) +} \ No newline at end of file From 47f0508af9fe1870d95475a27624b407540abe14 Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Wed, 4 Jun 2025 06:03:14 +0100 Subject: [PATCH 4/7] updates --- .../ dashboard-earnings/FilterBar.tsx | 29 ++ .../ dashboard-earnings/LoanRow.tsx | 34 ++ .../TransactionHistory.tsx | 66 +-- .../ dashboard-earnings/TransactionTable.tsx | 115 +++++ src/lib/MockData.ts | 476 ++++++++++++++++-- .../TransactionIHistoryInterface.ts | 10 + src/lib/utils.ts | 8 + 7 files changed, 645 insertions(+), 93 deletions(-) create mode 100644 src/components/ dashboard-earnings/FilterBar.tsx create mode 100644 src/components/ dashboard-earnings/LoanRow.tsx create mode 100644 src/components/ dashboard-earnings/TransactionTable.tsx create mode 100644 src/lib/interfaces/TransactionIHistoryInterface.ts diff --git a/src/components/ dashboard-earnings/FilterBar.tsx b/src/components/ dashboard-earnings/FilterBar.tsx new file mode 100644 index 0000000..0223cea --- /dev/null +++ b/src/components/ dashboard-earnings/FilterBar.tsx @@ -0,0 +1,29 @@ + + +export default function FilterBar() { + return ( +
+
+ + + +
+ + +
+ + + + + + +
+ + + +
+ +
+
+ ); +} diff --git a/src/components/ dashboard-earnings/LoanRow.tsx b/src/components/ dashboard-earnings/LoanRow.tsx new file mode 100644 index 0000000..b705765 --- /dev/null +++ b/src/components/ dashboard-earnings/LoanRow.tsx @@ -0,0 +1,34 @@ +import { TransactionHistoryInterface } from "@/lib/interfaces/TransactionIHistoryInterface"; +import { formatDate } from "@/lib/utils"; +import React from "react"; + + +interface LoanRowProps { + tableData: TransactionHistoryInterface + +} + + + +export default function LoanRow({ tableData}: LoanRowProps) { + + + + + + + return ( + + {tableData.transactionId} + {tableData.transactionType} + {tableData.amount} STRK + {tableData.status ? "Successful" : "Failed"} + {formatDate(tableData.date)} + + + + + ); +} diff --git a/src/components/ dashboard-earnings/TransactionHistory.tsx b/src/components/ dashboard-earnings/TransactionHistory.tsx index 183ee3e..9410a51 100644 --- a/src/components/ dashboard-earnings/TransactionHistory.tsx +++ b/src/components/ dashboard-earnings/TransactionHistory.tsx @@ -1,84 +1,28 @@ -import { ChevronLeft, ChevronRight } from "lucide-react"; -import { Button } from "../ui/button"; +import TransactionTable from "./TransactionTable"; -export default function TransactionHistory () { +export default function TransactionHistory() { return (
-

Transaction History

-
+

Transaction History

-
-
- - - -
+ -
-
- -to - -
- -
-
- -
- - -
-

- Showing 1 to 5 of 12 -

- - - - -
- -
- - -
- - -
- - - - - - - - - - -
- - - - - - -
-
-
+
) } \ No newline at end of file diff --git a/src/components/ dashboard-earnings/TransactionTable.tsx b/src/components/ dashboard-earnings/TransactionTable.tsx new file mode 100644 index 0000000..012fc92 --- /dev/null +++ b/src/components/ dashboard-earnings/TransactionTable.tsx @@ -0,0 +1,115 @@ +import React, { useState } from 'react'; +import { ChevronLeft, ChevronRight } from 'lucide-react'; +import { transactionHistoryData } from '@/lib/MockData'; +import FilterBar from './FilterBar'; +import LoanRow from './LoanRow'; + +export default function TransactionTable() { + const [currentPage, setCurrentPage] = useState(1); + const itemsPerPage = 5; + + const totalPages = Math.ceil(transactionHistoryData.length / itemsPerPage); + + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = currentPage * itemsPerPage; + + const handlePrev = () => { + if (currentPage > 1) setCurrentPage((prev) => prev - 1); + }; + + const handleNext = () => { + if (currentPage < totalPages) setCurrentPage((prev) => prev + 1); + }; + + const generatePagination = () => { + const delta = 1; + const range = []; + const left = Math.max(2, currentPage - delta); + const right = Math.min(totalPages - 1, currentPage + delta); + + range.push(1); + if (left > 2) range.push('...'); + + for (let i = left; i <= right; i++) { + range.push(i); + } + + if (right < totalPages - 1) range.push('...'); + if (totalPages > 1) range.push(totalPages); + + return range; + }; + + return ( +
+ + +
+ + + + + + + + + + + + + {transactionHistoryData.slice(startIndex, endIndex).map((loanDetails, i) => ( + + ))} + +
Transaction IDTransaction TypeAmount (STRK)StatusDate
+ + {/* Pagination Footer */} +
+

+ Showing {startIndex + 1} to{' '} + {endIndex > transactionHistoryData.length ? transactionHistoryData.length : endIndex} of{' '} + {transactionHistoryData.length} +

+ +
+ + + + +
    + {generatePagination().map((page, index) => ( +
  • typeof page === 'number' && setCurrentPage(page)} + className={`px-2 py-1 rounded cursor-pointer text-sm ${ + page === currentPage + ? 'text-white bg-[#096CFF]' + : typeof page === 'number' + ? 'text-[#888888] hover:text-[#096CFF]' + : 'cursor-default text-[#888888]' + }`} + > + {page} +
  • + ))} +
+ + +
+
+
+
+ ); +} diff --git a/src/lib/MockData.ts b/src/lib/MockData.ts index 9a66898..743cb29 100644 --- a/src/lib/MockData.ts +++ b/src/lib/MockData.ts @@ -1,36 +1,448 @@ import { Book } from "./interfaces/BookInterface"; +import { TransactionHistoryInterface } from "./interfaces/TransactionIHistoryInterface"; -const bookData: Book[] = [ - { id: 1, bookTitle: "Native Invisibility", author: "Darrin Collins", isNFT: true, image: "/images/bookCover1.png", price: 15, rating: 4, date: new Date("2024-04-01") }, - { id: 2, bookTitle: "Whispers of Tomorrow", author: "Lena Fitzgerald", isNFT: false, image: "/images/bookCover1.png", price: 22, rating: 3, date: new Date("2024-03-28") }, - { id: 3, bookTitle: "Echoes of the Forgotten", author: "Marcus Reed", isNFT: true, image: "/images/bookCover1.png", price: 30, rating: 5, date: new Date("2024-04-20") }, - { id: 4, bookTitle: "Fragments of Reality", author: "Sophia Turner", isNFT: false, image: "/images/bookCover1.png", price: 18, rating: 2, date: new Date("2024-04-15") }, - { id: 5, bookTitle: "The Last Horizon", author: "Isaiah Brooks", isNFT: true, image: "/images/bookCover1.png", price: 35, rating: 5, date: new Date("2024-02-10") }, - { id: 6, bookTitle: "Silent Songs", author: "Amelia Hart", isNFT: false, image: "/images/bookCover1.png", price: 27, rating: 3, date: new Date("2024-01-30") }, - { id: 7, bookTitle: "Beyond the Edge", author: "Noah Chambers", isNFT: true, image: "/images/bookCover1.png", price: 24, rating: 4, date: new Date("2024-04-22") }, - { id: 8, bookTitle: "Twilight's Embrace", author: "Olivia Bennett", isNFT: false, image: "/images/bookCover1.png", price: 20, rating: 2, date: new Date("2024-03-12") }, - { id: 9, bookTitle: "Shadows and Sparks", author: "Ethan Cruz", isNFT: true, image: "/images/bookCover1.png", price: 32, rating: 5, date: new Date("2024-04-19") }, - { id: 10, bookTitle: "Canvas of Dreams", author: "Maya Jensen", isNFT: false, image: "/images/bookCover1.png", price: 14, rating: 1, date: new Date("2024-03-05") }, - { id: 11, bookTitle: "Winds of Destiny", author: "Lucas Hayes", isNFT: true, image: "/images/bookCover1.png", price: 38, rating: 5, date: new Date("2024-04-23") }, - { id: 12, bookTitle: "Mirror of Illusions", author: "Ella Simmons", isNFT: false, image: "/images/bookCover1.png", price: 17, rating: 2, date: new Date("2024-02-28") }, - { id: 13, bookTitle: "Veil of Secrets", author: "Gabriel Vaughn", isNFT: true, image: "/images/bookCover1.png", price: 29, rating: 4, date: new Date("2024-04-18") }, - { id: 14, bookTitle: "Tides of Memory", author: "Chloe Monroe", isNFT: false, image: "/images/bookCover1.png", price: 19, rating: 3, date: new Date("2024-01-18") }, - { id: 15, bookTitle: "Broken Compass", author: "Henry Castillo", isNFT: true, image: "/images/bookCover1.png", price: 36, rating: 5, date: new Date("2024-04-21") }, - { id: 16, bookTitle: "Letters to Nowhere", author: "Aria Flores", isNFT: false, image: "/images/bookCover1.png", price: 12, rating: 2, date: new Date("2024-03-07") }, - { id: 17, bookTitle: "Crimson Skies", author: "Leo Montgomery", isNFT: true, image: "/images/bookCover1.png", price: 25, rating: 5, date: new Date("2024-04-11") }, - { id: 18, bookTitle: "Paths Uncharted", author: "Zoe Wallace", isNFT: false, image: "/images/bookCover1.png", price: 21, rating: 3, date: new Date("2024-02-25") }, - { id: 19, bookTitle: "Silent Reverie", author: "Nathaniel West", isNFT: true, image: "/images/bookCover1.png", price: 34, rating: 4, date: new Date("2024-04-16") }, - { id: 20, bookTitle: "Gates of Tomorrow", author: "Lily Armstrong", isNFT: false, image: "/images/bookCover1.png", price: 13, rating: 1, date: new Date("2024-02-11") }, - { id: 21, bookTitle: "Beneath the Surface", author: "Mason Ellis", isNFT: true, image: "/images/bookCover1.png", price: 40, rating: 5, date: new Date("2024-04-26") }, - { id: 22, bookTitle: "Embers of Hope", author: "Grace Nolan", isNFT: false, image: "/images/bookCover1.png", price: 16, rating: 2, date: new Date("2024-03-18") }, - { id: 23, bookTitle: "River of Stars", author: "Sebastian Keller", isNFT: true, image: "/images/bookCover1.png", price: 28, rating: 4, date: new Date("2024-04-24") }, - { id: 24, bookTitle: "Secrets of the Deep", author: "Isla Warner", isNFT: false, image: "/images/bookCover1.png", price: 23, rating: 3, date: new Date("2024-01-15") }, - { id: 25, bookTitle: "Ashes and Echoes", author: "Owen Sharp", isNFT: true, image: "/images/bookCover1.png", price: 39, rating: 5, date: new Date("2024-04-17") }, - { id: 26, bookTitle: "Whispers in the Wind", author: "Sienna Cross", isNFT: false, image: "/images/bookCover1.png", price: 11, rating: 2, date: new Date("2024-03-09") }, - { id: 27, bookTitle: "Lanterns of the Past", author: "Caleb Drake", isNFT: true, image: "/images/bookCover1.png", price: 37, rating: 5, date: new Date("2024-04-13") }, - { id: 28, bookTitle: "Moonlight Sonata", author: "Hannah Frost", isNFT: false, image: "/images/bookCover1.png", price: 26, rating: 4, date: new Date("2024-03-01") }, - { id: 29, bookTitle: "Valley of Mist", author: "Dominic Rhodes", isNFT: true, image: "/images/bookCover1.png", price: 31, rating: 5, date: new Date("2024-04-12") }, - { id: 30, bookTitle: "Songs of the Sea", author: "Penelope Brooks", isNFT: false, image: "/images/bookCover1.png", price: 15, rating: 2, date: new Date("2024-02-07") }, +export const bookData: Book[] = [ + { + id: 1, + bookTitle: "Native Invisibility", + author: "Darrin Collins", + isNFT: true, + image: "/images/bookCover1.png", + price: 15, + rating: 4, + date: new Date("2024-04-01"), + }, + { + id: 2, + bookTitle: "Whispers of Tomorrow", + author: "Lena Fitzgerald", + isNFT: false, + image: "/images/bookCover1.png", + price: 22, + rating: 3, + date: new Date("2024-03-28"), + }, + { + id: 3, + bookTitle: "Echoes of the Forgotten", + author: "Marcus Reed", + isNFT: true, + image: "/images/bookCover1.png", + price: 30, + rating: 5, + date: new Date("2024-04-20"), + }, + { + id: 4, + bookTitle: "Fragments of Reality", + author: "Sophia Turner", + isNFT: false, + image: "/images/bookCover1.png", + price: 18, + rating: 2, + date: new Date("2024-04-15"), + }, + { + id: 5, + bookTitle: "The Last Horizon", + author: "Isaiah Brooks", + isNFT: true, + image: "/images/bookCover1.png", + price: 35, + rating: 5, + date: new Date("2024-02-10"), + }, + { + id: 6, + bookTitle: "Silent Songs", + author: "Amelia Hart", + isNFT: false, + image: "/images/bookCover1.png", + price: 27, + rating: 3, + date: new Date("2024-01-30"), + }, + { + id: 7, + bookTitle: "Beyond the Edge", + author: "Noah Chambers", + isNFT: true, + image: "/images/bookCover1.png", + price: 24, + rating: 4, + date: new Date("2024-04-22"), + }, + { + id: 8, + bookTitle: "Twilight's Embrace", + author: "Olivia Bennett", + isNFT: false, + image: "/images/bookCover1.png", + price: 20, + rating: 2, + date: new Date("2024-03-12"), + }, + { + id: 9, + bookTitle: "Shadows and Sparks", + author: "Ethan Cruz", + isNFT: true, + image: "/images/bookCover1.png", + price: 32, + rating: 5, + date: new Date("2024-04-19"), + }, + { + id: 10, + bookTitle: "Canvas of Dreams", + author: "Maya Jensen", + isNFT: false, + image: "/images/bookCover1.png", + price: 14, + rating: 1, + date: new Date("2024-03-05"), + }, + { + id: 11, + bookTitle: "Winds of Destiny", + author: "Lucas Hayes", + isNFT: true, + image: "/images/bookCover1.png", + price: 38, + rating: 5, + date: new Date("2024-04-23"), + }, + { + id: 12, + bookTitle: "Mirror of Illusions", + author: "Ella Simmons", + isNFT: false, + image: "/images/bookCover1.png", + price: 17, + rating: 2, + date: new Date("2024-02-28"), + }, + { + id: 13, + bookTitle: "Veil of Secrets", + author: "Gabriel Vaughn", + isNFT: true, + image: "/images/bookCover1.png", + price: 29, + rating: 4, + date: new Date("2024-04-18"), + }, + { + id: 14, + bookTitle: "Tides of Memory", + author: "Chloe Monroe", + isNFT: false, + image: "/images/bookCover1.png", + price: 19, + rating: 3, + date: new Date("2024-01-18"), + }, + { + id: 15, + bookTitle: "Broken Compass", + author: "Henry Castillo", + isNFT: true, + image: "/images/bookCover1.png", + price: 36, + rating: 5, + date: new Date("2024-04-21"), + }, + { + id: 16, + bookTitle: "Letters to Nowhere", + author: "Aria Flores", + isNFT: false, + image: "/images/bookCover1.png", + price: 12, + rating: 2, + date: new Date("2024-03-07"), + }, + { + id: 17, + bookTitle: "Crimson Skies", + author: "Leo Montgomery", + isNFT: true, + image: "/images/bookCover1.png", + price: 25, + rating: 5, + date: new Date("2024-04-11"), + }, + { + id: 18, + bookTitle: "Paths Uncharted", + author: "Zoe Wallace", + isNFT: false, + image: "/images/bookCover1.png", + price: 21, + rating: 3, + date: new Date("2024-02-25"), + }, + { + id: 19, + bookTitle: "Silent Reverie", + author: "Nathaniel West", + isNFT: true, + image: "/images/bookCover1.png", + price: 34, + rating: 4, + date: new Date("2024-04-16"), + }, + { + id: 20, + bookTitle: "Gates of Tomorrow", + author: "Lily Armstrong", + isNFT: false, + image: "/images/bookCover1.png", + price: 13, + rating: 1, + date: new Date("2024-02-11"), + }, + { + id: 21, + bookTitle: "Beneath the Surface", + author: "Mason Ellis", + isNFT: true, + image: "/images/bookCover1.png", + price: 40, + rating: 5, + date: new Date("2024-04-26"), + }, + { + id: 22, + bookTitle: "Embers of Hope", + author: "Grace Nolan", + isNFT: false, + image: "/images/bookCover1.png", + price: 16, + rating: 2, + date: new Date("2024-03-18"), + }, + { + id: 23, + bookTitle: "River of Stars", + author: "Sebastian Keller", + isNFT: true, + image: "/images/bookCover1.png", + price: 28, + rating: 4, + date: new Date("2024-04-24"), + }, + { + id: 24, + bookTitle: "Secrets of the Deep", + author: "Isla Warner", + isNFT: false, + image: "/images/bookCover1.png", + price: 23, + rating: 3, + date: new Date("2024-01-15"), + }, + { + id: 25, + bookTitle: "Ashes and Echoes", + author: "Owen Sharp", + isNFT: true, + image: "/images/bookCover1.png", + price: 39, + rating: 5, + date: new Date("2024-04-17"), + }, + { + id: 26, + bookTitle: "Whispers in the Wind", + author: "Sienna Cross", + isNFT: false, + image: "/images/bookCover1.png", + price: 11, + rating: 2, + date: new Date("2024-03-09"), + }, + { + id: 27, + bookTitle: "Lanterns of the Past", + author: "Caleb Drake", + isNFT: true, + image: "/images/bookCover1.png", + price: 37, + rating: 5, + date: new Date("2024-04-13"), + }, + { + id: 28, + bookTitle: "Moonlight Sonata", + author: "Hannah Frost", + isNFT: false, + image: "/images/bookCover1.png", + price: 26, + rating: 4, + date: new Date("2024-03-01"), + }, + { + id: 29, + bookTitle: "Valley of Mist", + author: "Dominic Rhodes", + isNFT: true, + image: "/images/bookCover1.png", + price: 31, + rating: 5, + date: new Date("2024-04-12"), + }, + { + id: 30, + bookTitle: "Songs of the Sea", + author: "Penelope Brooks", + isNFT: false, + image: "/images/bookCover1.png", + price: 15, + rating: 2, + date: new Date("2024-02-07"), + }, ]; -export default bookData; +export const transactionHistoryData: TransactionHistoryInterface[] = [ + { + transactionId: "Tran-124B", + transactionType: "Monthly Payment", + amount: 10.99, + status: true, + date: new Date("2024-02-07"), + }, + { + transactionId: "Tran-124C", + transactionType: "Book Purchase", + amount: 79.09, + status: true, + date: new Date("2024-04-25"), + }, + { + transactionId: "Tran-124D", + transactionType: "Withdraw", + amount: 1560.0, + status: false, + date: new Date("2024-04-20"), + }, + { + transactionId: "Tran-124E", + transactionType: "NFT Royalties", + amount: 7.02, + status: true, + date: new Date("2024-04-18"), + }, + { + transactionId: "Tran-124F", + transactionType: "NFT Royalties", + amount: 8.09, + status: true, + date: new Date("2024-04-18"), + }, + { + transactionId: "Tran-124G", + transactionType: "Utility Bill", + amount: 45.99, + status: true, + date: new Date("2024-03-14"), + }, + { + transactionId: "Tran-124H", + transactionType: "Subscription Fee", + amount: 5.0, + status: false, + date: new Date("2024-05-02"), + }, + { + transactionId: "Tran-124I", + transactionType: "Airtime Recharge", + amount: 3.5, + status: true, + date: new Date("2024-01-27"), + }, + { + transactionId: "Tran-124J", + transactionType: "Loan Repayment", + amount: 500.0, + status: true, + date: new Date("2024-03-10"), + }, + { + transactionId: "Tran-124K", + transactionType: "Gift Card Purchase", + amount: 50.0, + status: false, + date: new Date("2024-02-21"), + }, + { + transactionId: "Tran-124L", + transactionType: "Course Fee", + amount: 120.0, + status: true, + date: new Date("2024-03-05"), + }, + { + transactionId: "Tran-124M", + transactionType: "Insurance Premium", + amount: 250.0, + status: true, + date: new Date("2024-01-12"), + }, + { + transactionId: "Tran-124N", + transactionType: "Refund", + amount: 99.99, + status: true, + date: new Date("2024-04-09"), + }, + { + transactionId: "Tran-124O", + transactionType: "Consultation Fee", + amount: 30.0, + status: false, + date: new Date("2024-05-01"), + }, + { + transactionId: "Tran-124P", + transactionType: "Web Hosting", + amount: 15.0, + status: true, + date: new Date("2024-03-16"), + }, + { + transactionId: "Tran-124Q", + transactionType: "Conference Ticket", + amount: 200.0, + status: true, + date: new Date("2024-04-02"), + }, + { + transactionId: "Tran-124R", + transactionType: "Donation", + amount: 25.0, + status: false, + date: new Date("2024-02-18"), + }, + { + transactionId: "Tran-124S", + transactionType: "Freelance Payment", + amount: 350.0, + status: true, + date: new Date("2024-04-29"), + }, + { + transactionId: "Tran-124T", + transactionType: "Ticket Booking", + amount: 60.0, + status: true, + date: new Date("2024-05-03"), + }, + { + transactionId: "Tran-124U", + transactionType: "NFT Sale", + amount: 1000.0, + status: true, + date: new Date("2024-04-22"), + }, +]; diff --git a/src/lib/interfaces/TransactionIHistoryInterface.ts b/src/lib/interfaces/TransactionIHistoryInterface.ts new file mode 100644 index 0000000..1c5f718 --- /dev/null +++ b/src/lib/interfaces/TransactionIHistoryInterface.ts @@ -0,0 +1,10 @@ + + + +export interface TransactionHistoryInterface { + transactionId: string; + transactionType: string; + amount: number; + status: boolean; + date: Date; +} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f34cc6b..46f28b5 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -46,3 +46,11 @@ export const handlePaste = async ( return null } } + + + +export const formatDate = (date: Date) => + date.toLocaleDateString("en-GB", { + day: "2-digit", + month: "long", + }); From 54db71f9bb8e429b00855eab65925555632f280b Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Thu, 5 Jun 2025 14:45:42 +0100 Subject: [PATCH 5/7] updates --- src/app/dashboard/earnings/page.tsx | 2 +- src/app/globals.css | 1 + src/app/layout.tsx | 10 +- src/components/ dashboard-earnings/Chart.tsx | 4 +- .../ dashboard-earnings/EarningSummary.tsx | 10 +- .../ dashboard-earnings/FilterBar.tsx | 30 ++- .../ dashboard-earnings/LoanRow.tsx | 5 +- .../ dashboard-earnings/RevenueBreakdown.tsx | 2 +- .../TransactionModalButton.tsx | 211 ++++++++++++++++++ .../ dashboard-earnings/TransactionTable.tsx | 4 +- src/components/common/Modal.tsx | 14 +- 11 files changed, 265 insertions(+), 28 deletions(-) create mode 100644 src/components/ dashboard-earnings/TransactionModalButton.tsx diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index e1082da..80f4f54 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -76,7 +76,7 @@ function EarningsPage() { }, [walletAddress]) return ( -
+
diff --git a/src/app/globals.css b/src/app/globals.css index 98ac33e..25a91f5 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -84,6 +84,7 @@ /* Font Family */ --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); + --font-inter: var(--font-inter); /* DIsplay TextSizes */ --text-display-large: 57px; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fb17e01..2ebcf3b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,19 +3,27 @@ import "./globals.css"; import NavBar from "@/components/landingpage/NavBar"; import { Providers } from "@/components/blockchain/Providers"; import Footer from "@/components/landingpage/Footer"; +import { Inter } from "next/font/google"; + export const metadata: Metadata = { title: "ChainLib", description: "An E-Libray Platform", }; +const inter = Inter({ + subsets: ["latin"], + display: "swap", + variable: "--font-inter", +}); + export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( - + {children} diff --git a/src/components/ dashboard-earnings/Chart.tsx b/src/components/ dashboard-earnings/Chart.tsx index fb7cdb3..07a53f1 100644 --- a/src/components/ dashboard-earnings/Chart.tsx +++ b/src/components/ dashboard-earnings/Chart.tsx @@ -16,14 +16,14 @@ export default function RevenueChart({chartData}: RevenueChartProps) { - console.log(chartData) + return ( -
+
diff --git a/src/components/ dashboard-earnings/EarningSummary.tsx b/src/components/ dashboard-earnings/EarningSummary.tsx index 30a6178..5531c23 100644 --- a/src/components/ dashboard-earnings/EarningSummary.tsx +++ b/src/components/ dashboard-earnings/EarningSummary.tsx @@ -9,24 +9,24 @@ interface EarningsSummaryProps { const EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { return (
-
+
{earningsSumaryDetails.map((item, index) => (
-

{item.title}

+

{item.title}

icon -

{item.amount.toFixed(2)}

+

{item.amount.toFixed(2)}

))}
-
diff --git a/src/components/ dashboard-earnings/FilterBar.tsx b/src/components/ dashboard-earnings/FilterBar.tsx index 0223cea..90c250d 100644 --- a/src/components/ dashboard-earnings/FilterBar.tsx +++ b/src/components/ dashboard-earnings/FilterBar.tsx @@ -1,16 +1,34 @@ +import { Input } from "../ui/input"; export default function FilterBar() { return ( -
+
- - - + + +
-
+
+ + + +to + + + @@ -22,7 +40,7 @@ export default function FilterBar() {
- +
); diff --git a/src/components/ dashboard-earnings/LoanRow.tsx b/src/components/ dashboard-earnings/LoanRow.tsx index b705765..7bde864 100644 --- a/src/components/ dashboard-earnings/LoanRow.tsx +++ b/src/components/ dashboard-earnings/LoanRow.tsx @@ -1,6 +1,7 @@ import { TransactionHistoryInterface } from "@/lib/interfaces/TransactionIHistoryInterface"; import { formatDate } from "@/lib/utils"; import React from "react"; +import TransactionModalButton from "./TransactionModalButton"; interface LoanRowProps { @@ -25,9 +26,7 @@ export default function LoanRow({ tableData}: LoanRowProps) { {tableData.status ? "Successful" : "Failed"} {formatDate(tableData.date)} - + ); diff --git a/src/components/ dashboard-earnings/RevenueBreakdown.tsx b/src/components/ dashboard-earnings/RevenueBreakdown.tsx index 6ad0258..a041dce 100644 --- a/src/components/ dashboard-earnings/RevenueBreakdown.tsx +++ b/src/components/ dashboard-earnings/RevenueBreakdown.tsx @@ -21,7 +21,7 @@ export default function RevenueBreakdown({ chartData }: RevenueBreakdownProps) { -
+
diff --git a/src/components/ dashboard-earnings/TransactionModalButton.tsx b/src/components/ dashboard-earnings/TransactionModalButton.tsx new file mode 100644 index 0000000..f9055d8 --- /dev/null +++ b/src/components/ dashboard-earnings/TransactionModalButton.tsx @@ -0,0 +1,211 @@ +"use client" + +import * as React from "react" +import Box from "@mui/material/Box" +import Modal from "@mui/material/Modal" +import { X } from "lucide-react" +import { Button, Stack } from "@mui/material" +import Image from "next/image" + +const style = { + position: "absolute", + top: "50%", + left: "50%", + transform: "translate(-50%, -50%)", + width: "100%", + minWidth: "345px", + maxWidth: "853px", + height: "fit-content", + bgcolor: "#FFFFFF", + border: "none", + boxShadow: 24, + paddingTop: "32px", + paddingBottom: "32px", + paddingLeft: 6, + paddingRight: 6, + borderRadius: "8px", +} + + + +const amountDetails = [ + { + heading: "Amount Paid", + value: 800.00, + }, + { + heading: "Royalty Earned", + value: 80.00, + }, + { + heading: "Platform Commission", + value: 80.00, + }, +] + + +const transactionDetails = [ + { + heading: "Transaction Type", + value: "Book Purchase", + }, + { + heading: "Status", + value: Successful, + }, + { + heading: "Date", + value: "12 March, 2025 ", + }, + { + heading: "Time", + value: "16:32 ", + }, +] + + + +const NFTdetails = [ + { + heading: "NFT ID", + value: "#0002", + }, + { + heading: "Buyer", + value: "USER-0001", + }, + { + heading: "Transaction ID", + value: "TRANS-00112", + }, + { + heading: "Transaction Hash", + value: "0x5a3f7b...d6e7f8g", + }, + { + heading: "Confirmation Status", + value: "12/12", + }, +] + +export default function TransactionModalButton() { + const [open, setOpen] = React.useState(false) + const handleOpen = () => setOpen(true) + const handleClose = () => setOpen(false) + + return ( +
+ + + +
+ +

Transaction Details

+ + + + + + + + + + + +

99 Laws of Power

+

NFT Edition

+

eBook

+
+
+ + +
+ + + + + {amountDetails.map((item, index) => ( + +

token icon {item.heading}

+

token icon {item.value} STRK

+ ))} +
+ +
+ + + + + + + + + + + + {transactionDetails.map((item, index) => ( + +

{item.heading}

+

{item.value}

+ ))} +
+ + + + + +
+ + + + {NFTdetails.map((item, index) => ( + +

{item.heading}

+

{item.value} STRK

+ ))} +
+ +
+ + + + + +
+ + + + + + + +
+
+
+
+
+ ) +} diff --git a/src/components/ dashboard-earnings/TransactionTable.tsx b/src/components/ dashboard-earnings/TransactionTable.tsx index 012fc92..3ee7bf7 100644 --- a/src/components/ dashboard-earnings/TransactionTable.tsx +++ b/src/components/ dashboard-earnings/TransactionTable.tsx @@ -41,7 +41,7 @@ export default function TransactionTable() { }; return ( -
+
@@ -95,7 +95,7 @@ export default function TransactionTable() { onClick={() => typeof page === 'number' && setCurrentPage(page)} className={`px-2 py-1 rounded cursor-pointer text-sm ${ page === currentPage - ? 'text-white bg-[#096CFF]' + ? 'text-[#096CFF]' : typeof page === 'number' ? 'text-[#888888] hover:text-[#096CFF]' : 'cursor-default text-[#888888]' diff --git a/src/components/common/Modal.tsx b/src/components/common/Modal.tsx index 4ed36e3..0f100f8 100644 --- a/src/components/common/Modal.tsx +++ b/src/components/common/Modal.tsx @@ -48,18 +48,18 @@ export default function ProfileCompletionModal({ return (
-
e.stopPropagation()} > - - +
@@ -70,15 +70,15 @@ export default function ProfileCompletionModal({ experience and connect you with the right opportunities.

- +
- -
); -} \ No newline at end of file +} \ No newline at end of file From ebd357f20773379632f6aa6fa75b65ff22be1ac9 Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Fri, 6 Jun 2025 11:52:28 +0100 Subject: [PATCH 6/7] updates --- src/app/dashboard/earnings/page.tsx | 20 ++- .../ dashboard-earnings/EarningSummary.tsx | 6 +- .../ dashboard-earnings/LinkWallet.tsx | 2 +- .../RequestPaymentModal.tsx | 144 ++++++++++++++++++ .../TransactionModalButton.tsx | 60 ++++---- src/lib/interfaces/PaymentPropInterface.ts | 8 + src/lib/interfaces/WalletAddressType.ts | 4 + 7 files changed, 210 insertions(+), 34 deletions(-) create mode 100644 src/components/ dashboard-earnings/RequestPaymentModal.tsx create mode 100644 src/lib/interfaces/PaymentPropInterface.ts create mode 100644 src/lib/interfaces/WalletAddressType.ts diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index 80f4f54..20dbf27 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -8,6 +8,9 @@ import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" import { RevenueChartInterface } from "@/lib/interfaces/RevenueChartInterface" import { useEffect, useState } from "react" import TransactionHistory from "../../../components/ dashboard-earnings/TransactionHistory" +import RequestPaymentModal from "@/components/ dashboard-earnings/RequestPaymentModal" +import { PaymentPropInterface } from "@/lib/interfaces/PaymentPropInterface" + const earningsSumaryDetails: EarningTab[] = [ { title: "Current Balance", amount: 3150.0 , border: "#D6ECFF" }, @@ -16,6 +19,9 @@ const earningsSumaryDetails: EarningTab[] = [ { title: "Total Earned", amount: 2730.19, border: "#D6ECFF" }, ] + + + const chartData: RevenueChartInterface[] = [ { name: "Monthly Subcription Payment", @@ -46,6 +52,7 @@ const chartData: RevenueChartInterface[] = [ function EarningsPage() { + const [openRequestModal, setOpenRequestModal] = useState(false) const [walletAddress, setWalletAddress] = useState({ braavos: "", argent: "", @@ -53,6 +60,14 @@ function EarningsPage() { const ADDRESS_KEY = "walletAddressKey" + const [paymentDetails, setPaymentDetails] = useState ({ + amount: 0.00, + wallet: "", + walletAddress: "" +}) + + + // This function loads saved addresses useEffect(() => { const savedAddresses = localStorage.getItem(ADDRESS_KEY) @@ -76,11 +91,12 @@ function EarningsPage() { }, [walletAddress]) return ( -
- +
+ +{openRequestModal && }
) } diff --git a/src/components/ dashboard-earnings/EarningSummary.tsx b/src/components/ dashboard-earnings/EarningSummary.tsx index 5531c23..64c9b4e 100644 --- a/src/components/ dashboard-earnings/EarningSummary.tsx +++ b/src/components/ dashboard-earnings/EarningSummary.tsx @@ -1,12 +1,14 @@ import type { EarningTab } from "@/lib/interfaces/EarningTabInterface" import { Button } from "../ui/button" import Image from "next/image" +import React from "react" interface EarningsSummaryProps { earningsSumaryDetails: EarningTab[] + setOpenRequestModal: React.Dispatch> } -const EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { +const EarningsSummary = ({ earningsSumaryDetails, setOpenRequestModal }: EarningsSummaryProps) => { return (
@@ -26,7 +28,7 @@ const EarningsSummary = ({ earningsSumaryDetails }: EarningsSummaryProps) => { ))}
-
diff --git a/src/components/ dashboard-earnings/LinkWallet.tsx b/src/components/ dashboard-earnings/LinkWallet.tsx index 38871e7..25097f6 100644 --- a/src/components/ dashboard-earnings/LinkWallet.tsx +++ b/src/components/ dashboard-earnings/LinkWallet.tsx @@ -6,7 +6,7 @@ import Image from "next/image" import { Input } from "../ui/input" import { handlePaste } from "../../lib/utils" -interface WalletAddressType { +export interface WalletAddressType { braavos: string argent: string } diff --git a/src/components/ dashboard-earnings/RequestPaymentModal.tsx b/src/components/ dashboard-earnings/RequestPaymentModal.tsx new file mode 100644 index 0000000..dc99b7a --- /dev/null +++ b/src/components/ dashboard-earnings/RequestPaymentModal.tsx @@ -0,0 +1,144 @@ + +import { Ghost, X } from "lucide-react"; +import { Button } from "../ui/button"; +import { PaymentPropInterface } from "@/lib/interfaces/PaymentPropInterface"; +import Image from "next/image" +import { Input } from "../ui/input"; +import React from "react"; +import { MenuItem, Select, SelectChangeEvent } from "@mui/material"; +import { WalletAddressType } from "./LinkWallet"; + + + + + +interface RequestPaymentModalProps { + paymentDetails: PaymentPropInterface; + setPaymentDetails: React.Dispatch>; + walletAddress: WalletAddressType; + setOpenRequestModal: React.Dispatch> +} + +export default function RequestPaymentModal({ paymentDetails, setPaymentDetails, walletAddress, setOpenRequestModal }: RequestPaymentModalProps) { + + + const handleChange = (event: SelectChangeEvent) => { + const { name, value } = event.target + + setPaymentDetails((prev) => ({ + ...prev, + [name]: event.target.value + })) + }; + + + const truncWalletAddress = paymentDetails.walletAddress.slice(0, 5) + "....." + paymentDetails.walletAddress.slice(paymentDetails.walletAddress.length - 6, paymentDetails.walletAddress.length - 1) + + return ( +
setOpenRequestModal(false)} className="w-full min-h-screen fixed top-0 left-0 bg-black/50 px-5 py-10 z-50"> + +
+ + + + + +
e.stopPropagation() + } + className="w-full max-w-[621px] bg-[#ffffff] min-w-[300px] flex flex-col py-4 px-6 gap-4 rounded-2xl " > + + +

Request Payment

+ + + +
+ +
+

Current Balance Subtotal

+

1793 STRK

+
+ +
+ +
+

Enter Amount

+

($12 USDT)

+
+ +
+ {"token + + + +
+ + +
+

Destination wallet address

+
+ + + + + {paymentDetails.walletAddress.trim().length > 0 ? truncWalletAddress : "--"} +
+ + +
+ +
+ + + + + + + + +
+ + + + +
+ + + + +
+ +
+ ); +} diff --git a/src/components/ dashboard-earnings/TransactionModalButton.tsx b/src/components/ dashboard-earnings/TransactionModalButton.tsx index f9055d8..716e43e 100644 --- a/src/components/ dashboard-earnings/TransactionModalButton.tsx +++ b/src/components/ dashboard-earnings/TransactionModalButton.tsx @@ -3,7 +3,7 @@ import * as React from "react" import Box from "@mui/material/Box" import Modal from "@mui/material/Modal" -import { X } from "lucide-react" +import { Upload, X } from "lucide-react" import { Button, Stack } from "@mui/material" import Image from "next/image" @@ -13,16 +13,14 @@ const style = { left: "50%", transform: "translate(-50%, -50%)", width: "100%", - minWidth: "345px", + minWidth: "350px", maxWidth: "853px", - height: "fit-content", + height: "full", bgcolor: "#FFFFFF", border: "none", boxShadow: 24, - paddingTop: "32px", - paddingBottom: "32px", - paddingLeft: 6, - paddingRight: 6, + paddingTop: "24px", + paddingBottom: "24px", borderRadius: "8px", } @@ -51,13 +49,13 @@ const transactionDetails = [ }, { heading: "Status", - value: Successful, + value: Successful, }, - { + { heading: "Date", value: "12 March, 2025 ", }, - { + { heading: "Time", value: "16:32 ", }, @@ -74,15 +72,15 @@ const NFTdetails = [ heading: "Buyer", value: "USER-0001", }, - { + { heading: "Transaction ID", value: "TRANS-00112", }, - { + { heading: "Transaction Hash", - value: "0x5a3f7b...d6e7f8g", + value: <>

0x5a3f7b...d6e7f8g

}, - { + { heading: "Confirmation Status", value: "12/12", }, @@ -104,8 +102,8 @@ export default function TransactionModalButton() { aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description" > - -
+ +
@@ -113,7 +111,8 @@ export default function TransactionModalButton() { - + @@ -121,18 +120,18 @@ export default function TransactionModalButton() { -

99 Laws of Power

+

99 Laws of Power

NFT Edition

eBook

-
+
- + {amountDetails.map((item, index) => (

token icon {item.heading}

@@ -144,14 +143,14 @@ export default function TransactionModalButton() { - + - + {transactionDetails.map((item, index) => (

{item.heading}

@@ -163,14 +162,14 @@ export default function TransactionModalButton() { -
+
- + {NFTdetails.map((item, index) => (

{item.heading}

-

{item.value} STRK

+

{item.value}

))}
@@ -181,7 +180,7 @@ export default function TransactionModalButton() {
- + + className=" w-full md:basis-1/2 ">Back
diff --git a/src/lib/interfaces/PaymentPropInterface.ts b/src/lib/interfaces/PaymentPropInterface.ts new file mode 100644 index 0000000..7a31996 --- /dev/null +++ b/src/lib/interfaces/PaymentPropInterface.ts @@ -0,0 +1,8 @@ + + + +export interface PaymentPropInterface { +wallet: string; +amount: number; +walletAddress: string +} \ No newline at end of file diff --git a/src/lib/interfaces/WalletAddressType.ts b/src/lib/interfaces/WalletAddressType.ts new file mode 100644 index 0000000..b653e35 --- /dev/null +++ b/src/lib/interfaces/WalletAddressType.ts @@ -0,0 +1,4 @@ +export interface WalletAddressType { + braavos: string + argent: string +} \ No newline at end of file From 393141e7d7281c5dc42bc755d136c5c0bb7e2186 Mon Sep 17 00:00:00 2001 From: chiscookeke11 Date: Mon, 9 Jun 2025 10:21:14 +0100 Subject: [PATCH 7/7] update --- src/app/book-lisiting-page/page.tsx | 2 +- .../book-lisiting-page/review/[id]/page.tsx | 2 +- src/app/dashboard/earnings/page.tsx | 2 +- .../ dashboard-earnings/MobileLoanRow.tsx | 29 ++ .../ dashboard-earnings/MobileTable.tsx | 93 +++++++ .../RequestPaymentModal.tsx | 251 ++++++++++++------ .../TransactionHistory.tsx | 4 +- .../ dashboard-earnings/TransactionTable.tsx | 153 ++++++----- src/components/BookListingPage/NewRelease.tsx | 2 +- src/components/BookListingPage/NftEdition.tsx | 3 +- src/components/BookListingPage/Trending.tsx | 3 +- src/lib/hooks/useIsMobile.ts | 17 ++ 12 files changed, 403 insertions(+), 158 deletions(-) create mode 100644 src/components/ dashboard-earnings/MobileLoanRow.tsx create mode 100644 src/components/ dashboard-earnings/MobileTable.tsx create mode 100644 src/lib/hooks/useIsMobile.ts diff --git a/src/app/book-lisiting-page/page.tsx b/src/app/book-lisiting-page/page.tsx index 5b00548..5513879 100644 --- a/src/app/book-lisiting-page/page.tsx +++ b/src/app/book-lisiting-page/page.tsx @@ -7,7 +7,7 @@ import NewRelease from "@/components/BookListingPage/NewRelease"; import NftEdition from "@/components/BookListingPage/NftEdition"; import Trending from "@/components/BookListingPage/Trending"; import { Input } from "@/components/ui/input"; -import bookData from "@/lib/MockData"; +import { bookData } from "@/lib/MockData"; import { useMemo, useState } from "react"; diff --git a/src/app/book-lisiting-page/review/[id]/page.tsx b/src/app/book-lisiting-page/review/[id]/page.tsx index 77b4011..dafb59e 100644 --- a/src/app/book-lisiting-page/review/[id]/page.tsx +++ b/src/app/book-lisiting-page/review/[id]/page.tsx @@ -1,7 +1,7 @@ "use client" -import bookData from '@/lib/MockData'; +import { bookData } from '@/lib/MockData'; import { useParams } from 'next/navigation'; diff --git a/src/app/dashboard/earnings/page.tsx b/src/app/dashboard/earnings/page.tsx index 20dbf27..60cbf2a 100644 --- a/src/app/dashboard/earnings/page.tsx +++ b/src/app/dashboard/earnings/page.tsx @@ -91,7 +91,7 @@ function EarningsPage() { }, [walletAddress]) return ( -
+
diff --git a/src/components/ dashboard-earnings/MobileLoanRow.tsx b/src/components/ dashboard-earnings/MobileLoanRow.tsx new file mode 100644 index 0000000..40534d2 --- /dev/null +++ b/src/components/ dashboard-earnings/MobileLoanRow.tsx @@ -0,0 +1,29 @@ +import { TransactionHistoryInterface } from "@/lib/interfaces/TransactionIHistoryInterface"; +import { formatDate } from "@/lib/utils"; +import React from "react"; + + +interface MobileLoanRowProps { + tableData: TransactionHistoryInterface + +} + + + +export default function MobileLoanRow({ tableData }: MobileLoanRowProps) { + + + + + + + return ( + + {tableData.transactionType} {formatDate(tableData.date)} + {tableData.amount} STRK + {tableData.status ? "Successful" : "Failed"} + + + + ); +} diff --git a/src/components/ dashboard-earnings/MobileTable.tsx b/src/components/ dashboard-earnings/MobileTable.tsx new file mode 100644 index 0000000..7ab2c2f --- /dev/null +++ b/src/components/ dashboard-earnings/MobileTable.tsx @@ -0,0 +1,93 @@ +"use client" + +import { ChevronLeft, ChevronRight } from "lucide-react" +import type { TransactionHistoryInterface } from "@/lib/interfaces/TransactionIHistoryInterface" +import MobileLoanRow from "./MobileLoanRow" + +interface MobileTableProps { + transactionHistoryData: TransactionHistoryInterface[] + startIndex: number + endIndex: number + currentPage: number + totalPages: number + handlePrev: () => void + handleNext: () => void + generatePagination: () => (number | string)[] + setCurrentPage: (page: number) => void +} + +export default function MobileTable({ + transactionHistoryData, + startIndex, + endIndex, + currentPage, + totalPages, + handlePrev, + handleNext, + generatePagination, + setCurrentPage, +}: MobileTableProps) { + return ( +
+
+ + + + + + + + + {transactionHistoryData.slice(startIndex, endIndex).map((loanDetails, i) => ( + + ))} + +
Transaction TypeAmount (USD)
+
+ + {/* Mobile Pagination Footer */} +
+

+ Showing {startIndex + 1} to{" "} + {endIndex > transactionHistoryData.length ? transactionHistoryData.length : endIndex} of{" "} + {transactionHistoryData.length} +

+ +
+ + +
    + {generatePagination().map((page, index) => ( +
  • typeof page === "number" && setCurrentPage(page)} + className={`px-2 py-1 rounded cursor-pointer text-xs ${page === currentPage + ? "text-[#096CFF] bg-[#096CFF]/10" + : typeof page === "number" + ? "text-[#888888] hover:text-[#096CFF]" + : "cursor-default text-[#888888]" + }`} + > + {page} +
  • + ))} +
+ + +
+
+
+ ) +} diff --git a/src/components/ dashboard-earnings/RequestPaymentModal.tsx b/src/components/ dashboard-earnings/RequestPaymentModal.tsx index dc99b7a..5f38a7a 100644 --- a/src/components/ dashboard-earnings/RequestPaymentModal.tsx +++ b/src/components/ dashboard-earnings/RequestPaymentModal.tsx @@ -1,144 +1,231 @@ +"use client" -import { Ghost, X } from "lucide-react"; -import { Button } from "../ui/button"; -import { PaymentPropInterface } from "@/lib/interfaces/PaymentPropInterface"; +import { X } from "lucide-react" +import { Button } from "@/components/ui/button" +import type { PaymentPropInterface } from "@/lib/interfaces/PaymentPropInterface" import Image from "next/image" -import { Input } from "../ui/input"; -import React from "react"; -import { MenuItem, Select, SelectChangeEvent } from "@mui/material"; -import { WalletAddressType } from "./LinkWallet"; - - - - +import { Input } from "@/components/ui/input" +import type React from "react" +import { useState } from "react" +import type { WalletAddressType } from "./LinkWallet" interface RequestPaymentModalProps { - paymentDetails: PaymentPropInterface; - setPaymentDetails: React.Dispatch>; - walletAddress: WalletAddressType; - setOpenRequestModal: React.Dispatch> + paymentDetails: PaymentPropInterface + setPaymentDetails: React.Dispatch> + walletAddress: WalletAddressType + setOpenRequestModal: React.Dispatch> } -export default function RequestPaymentModal({ paymentDetails, setPaymentDetails, walletAddress, setOpenRequestModal }: RequestPaymentModalProps) { +export default function RequestPaymentModal({paymentDetails, setPaymentDetails, walletAddress, setOpenRequestModal,}: RequestPaymentModalProps) { + const [selectedWallet, setSelectedWallet] = useState<"argent" | "braavos">("argent") + const [currentStep, setCurrentStep] = useState("1") + + const maxBalance = 1793 + + const handleAmountChange = (event: React.ChangeEvent) => { + const value = event.target.value.replace(/[^\d.]/g, "") + const numericValue = Number.parseFloat(value) || 0 - const handleChange = (event: SelectChangeEvent) => { - const { name, value } = event.target + const finalValue = Math.min(numericValue, maxBalance) setPaymentDetails((prev) => ({ ...prev, - [name]: event.target.value + amount: finalValue, })) - }; + } + const handleMaxClick = () => { + setPaymentDetails((prev) => ({ + ...prev, + amount: maxBalance, + })) + } - const truncWalletAddress = paymentDetails.walletAddress.slice(0, 5) + "....." + paymentDetails.walletAddress.slice(paymentDetails.walletAddress.length - 6, paymentDetails.walletAddress.length - 1) + const handleWalletChange = (event: React.ChangeEvent) => { + const wallet = event.target.value as "argent" | "braavos" + setSelectedWallet(wallet) - return ( -
setOpenRequestModal(false)} className="w-full min-h-screen fixed top-0 left-0 bg-black/50 px-5 py-10 z-50"> + setPaymentDetails((prev) => ({ + ...prev, + walletAddress: walletAddress[wallet] || "", + selectedWallet: wallet, + })) + } -
+ const truncateWalletAddress = (address: string) => { + if (!address || address.length < 12) return address + return address.slice(0, 5) + "....." + address.slice(-6) + } + const currentWalletAddress = walletAddress[selectedWallet] || "" + const truncatedAddress = truncateWalletAddress(currentWalletAddress) + const submitRequest = () => { + alert("Confirmed") + setPaymentDetails({ + amount: 0, + wallet: "", + walletAddress: "" + }) + setOpenRequestModal(false) + } -
e.stopPropagation() - } - className="w-full max-w-[621px] bg-[#ffffff] min-w-[300px] flex flex-col py-4 px-6 gap-4 rounded-2xl " > -

Request Payment

- - -
- -
-

Current Balance Subtotal

-

1793 STRK

+ +
+

Current Balance Subtotal

+

+ icon + {maxBalance} STRK +

-
- -
-

Enter Amount

-

($12 USDT)

+
+
+

Enter Amount

+

($12 USDT)

-
+
{"token - + STRK + +
+ +
+

Destination wallet address

+
+ + + {currentWalletAddress ? truncatedAddress : "--"} + +
+
+ + +
-
-

Destination wallet address

-
- - - - {paymentDetails.walletAddress.trim().length > 0 ? truncWalletAddress : "--"} -
-
-
+
e.stopPropagation()} + className={`w-full max-w-[621px] bg-[#ffffff] min-w-[300px] flex flex-col py-4 px-6 gap-4 rounded-2xl transform duration-150 ease-in-out absolute ${ currentStep === "2" ? "translate-x-0" : "translate-x-[300%] " }`} + > + +

Confirm Details

+
+
+

Amount to be sent

+
+

icon {paymentDetails.amount} STRK

+
($12 USDT)
+
+
+
+

Destination wallet address

+ + {currentWalletAddress ? truncatedAddress : "--"} + +
- +
+

Gas fees

+
icon 8 STRK
+
- -
+
+

Estimated time of delivery

+
24-48 Hours
+
+
+ +
-
- ); + ) } diff --git a/src/components/ dashboard-earnings/TransactionHistory.tsx b/src/components/ dashboard-earnings/TransactionHistory.tsx index 9410a51..f66368a 100644 --- a/src/components/ dashboard-earnings/TransactionHistory.tsx +++ b/src/components/ dashboard-earnings/TransactionHistory.tsx @@ -11,7 +11,7 @@ export default function TransactionHistory() { - + @@ -23,6 +23,6 @@ export default function TransactionHistory() { -
+ ) } \ No newline at end of file diff --git a/src/components/ dashboard-earnings/TransactionTable.tsx b/src/components/ dashboard-earnings/TransactionTable.tsx index 3ee7bf7..ea7e4b8 100644 --- a/src/components/ dashboard-earnings/TransactionTable.tsx +++ b/src/components/ dashboard-earnings/TransactionTable.tsx @@ -3,11 +3,13 @@ import { ChevronLeft, ChevronRight } from 'lucide-react'; import { transactionHistoryData } from '@/lib/MockData'; import FilterBar from './FilterBar'; import LoanRow from './LoanRow'; +import MobileTable from './MobileTable'; +import useIsMobile from '@/lib/hooks/useIsMobile'; + export default function TransactionTable() { const [currentPage, setCurrentPage] = useState(1); const itemsPerPage = 5; - const totalPages = Math.ceil(transactionHistoryData.length / itemsPerPage); const startIndex = (currentPage - 1) * itemsPerPage; @@ -40,76 +42,91 @@ export default function TransactionTable() { return range; }; - return ( -
- - -
- - - - - - - - - - - - - {transactionHistoryData.slice(startIndex, endIndex).map((loanDetails, i) => ( - - ))} - -
Transaction IDTransaction TypeAmount (STRK)StatusDate
- - {/* Pagination Footer */} -
-

- Showing {startIndex + 1} to{' '} - {endIndex > transactionHistoryData.length ? transactionHistoryData.length : endIndex} of{' '} - {transactionHistoryData.length} -

- -
- - - - -
    - {generatePagination().map((page, index) => ( -
  • typeof page === 'number' && setCurrentPage(page)} - className={`px-2 py-1 rounded cursor-pointer text-sm ${ - page === currentPage - ? 'text-[#096CFF]' - : typeof page === 'number' - ? 'text-[#888888] hover:text-[#096CFF]' - : 'cursor-default text-[#888888]' - }`} - > - {page} -
  • + const isMobile = useIsMobile(); + + if (!isMobile) { + return ( +
    + + +
    + + + + + + + + + + + + + {transactionHistoryData.slice(startIndex, endIndex).map((loanDetails, i) => ( + ))} - - - + +
    Transaction IDTransaction TypeAmount (STRK)StatusDate
    + + {/* Pagination Footer */} +
    +

    + Showing {startIndex + 1} to{' '} + {endIndex > transactionHistoryData.length ? transactionHistoryData.length : endIndex} of{' '} + {transactionHistoryData.length} +

    + +
    + + + + +
      + {generatePagination().map((page, index) => ( +
    • typeof page === 'number' && setCurrentPage(page)} + className={`px-2 py-1 rounded cursor-pointer text-sm ${page === currentPage + ? 'text-[#096CFF]' + : typeof page === 'number' + ? 'text-[#888888] hover:text-[#096CFF]' + : 'cursor-default text-[#888888]' + }`} + > + {page} +
    • + ))} +
    +
    -
+ ); + } + + return ( + ); } diff --git a/src/components/BookListingPage/NewRelease.tsx b/src/components/BookListingPage/NewRelease.tsx index 7302aa2..0ba2a4b 100644 --- a/src/components/BookListingPage/NewRelease.tsx +++ b/src/components/BookListingPage/NewRelease.tsx @@ -1,9 +1,9 @@ "use client" -import bookData from "@/lib/MockData"; import BookCard from "../reader/BookCard"; import { useState } from "react"; import { Button } from "../ui/button"; import Spinner from "../ui/Spinner"; +import { bookData } from "@/lib/MockData"; diff --git a/src/components/BookListingPage/NftEdition.tsx b/src/components/BookListingPage/NftEdition.tsx index c5972ea..62b46dc 100644 --- a/src/components/BookListingPage/NftEdition.tsx +++ b/src/components/BookListingPage/NftEdition.tsx @@ -1,6 +1,7 @@ "use client" -import bookData from "@/lib/MockData"; + +import { bookData } from "@/lib/MockData"; import BookCard from "../reader/BookCard"; import { Splide, SplideSlide } from '@splidejs/react-splide'; import '@splidejs/react-splide/css'; diff --git a/src/components/BookListingPage/Trending.tsx b/src/components/BookListingPage/Trending.tsx index c1f143d..47402e6 100644 --- a/src/components/BookListingPage/Trending.tsx +++ b/src/components/BookListingPage/Trending.tsx @@ -1,9 +1,10 @@ "use client" -import bookData from "@/lib/MockData"; + import BookCard from "../reader/BookCard"; import { useState } from "react"; import { Button } from "../ui/button"; import Spinner from "../ui/Spinner"; +import { bookData } from "@/lib/MockData"; export default function Trending() { diff --git a/src/lib/hooks/useIsMobile.ts b/src/lib/hooks/useIsMobile.ts new file mode 100644 index 0000000..22fed35 --- /dev/null +++ b/src/lib/hooks/useIsMobile.ts @@ -0,0 +1,17 @@ +import { useEffect, useState } from 'react'; + +export default function useIsMobile(breakpoint = 768) { + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const handleResize = () => { + setIsMobile(window.innerWidth <= breakpoint); + }; + + handleResize(); // initial check + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [breakpoint]); + + return isMobile; +}