From 6f2b32ee4a0a234713c08b05aaf95dd040220617 Mon Sep 17 00:00:00 2001 From: Yehoshua Sandler Date: Wed, 30 Apr 2025 16:02:06 -0500 Subject: [PATCH] feat: user feed stats use real data now --- public/images/book-loan.svg | 1 + public/images/book-shelf.svg | 1 + public/images/mail.svg | 1 + src/app/(frontend)/page.tsx | 4 +- src/collections/Checkouts/Checkouts.ts | 2 +- src/components/Feed/UserFeed.tsx | 152 ++++++++++++++++++++----- src/components/HomeHero.tsx | 2 +- 7 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 public/images/book-loan.svg create mode 100644 public/images/book-shelf.svg create mode 100644 public/images/mail.svg diff --git a/public/images/book-loan.svg b/public/images/book-loan.svg new file mode 100644 index 0000000..67edeeb --- /dev/null +++ b/public/images/book-loan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/book-shelf.svg b/public/images/book-shelf.svg new file mode 100644 index 0000000..7f3471c --- /dev/null +++ b/public/images/book-shelf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/mail.svg b/public/images/mail.svg new file mode 100644 index 0000000..6310e09 --- /dev/null +++ b/public/images/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/(frontend)/page.tsx b/src/app/(frontend)/page.tsx index d881da2..8df9a3b 100644 --- a/src/app/(frontend)/page.tsx +++ b/src/app/(frontend)/page.tsx @@ -103,7 +103,9 @@ export default async function HomePage() { Manage - {user && } + + {user && } + diff --git a/src/collections/Checkouts/Checkouts.ts b/src/collections/Checkouts/Checkouts.ts index 1294d39..e1ec68b 100644 --- a/src/collections/Checkouts/Checkouts.ts +++ b/src/collections/Checkouts/Checkouts.ts @@ -43,7 +43,7 @@ const Checkouts: CollectionConfig = { collection: 'copies', on: 'book', hasMany: false, - } + }, ] } diff --git a/src/components/Feed/UserFeed.tsx b/src/components/Feed/UserFeed.tsx index 13bd166..0a913f2 100644 --- a/src/components/Feed/UserFeed.tsx +++ b/src/components/Feed/UserFeed.tsx @@ -1,4 +1,4 @@ -import type { Book, HoldRequest, Repository, User } from '@/payload-types' +import type { Book, Checkout, HoldRequest, Repository, User } from '@/payload-types' import { getPayload, PaginatedDocs } from 'payload' import config from '@/payload.config' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../ui/card' @@ -16,9 +16,10 @@ const stats = [ type Props = { user?: User + repos: PaginatedDocs | null } const UserFeed = async (props: Props) => { - const { user } = props + const { user, repos } = props const isLoggedIn = !!user if (!isLoggedIn) @@ -51,42 +52,137 @@ const UserFeed = async (props: Props) => { }, })) as PaginatedDocs + const currentlyHeldBooks = (await payload.find({ + collection: 'holdRequests', + limit: 10, + depth: 3, + select: { + copy: true, + dateRequested: true, + repository: true, + book: true, + }, + where: { + 'repository.owner': { + equals: user?.id, + }, + isHolding: { + equals: true, + }, + }, + })) as PaginatedDocs + + let loanedOutBooks: PaginatedDocs | null = null + if (user.id) + loanedOutBooks = (await payload.find({ + collection: 'checkouts', + limit: 10, + depth: 2, + select: { + book: true, + dateDue: true, + loanerReturnedDate: true, + isReturned: true, + ownerVerifiedReturnedDate: true, + }, + where: { + and: [ + { + 'copy.repository.owner': { + equals: user.id, + }, + }, + { + isReturned: { + not_equals: true, + }, + }, + ], + }, + })) as PaginatedDocs + + const totalHoldNotifications = repos?.docs.flatMap((r) => r.holdRequests?.docs).length || 0 + const outBoundLoanCount = loanedOutBooks?.totalDocs || 0 + const currentlyHoldingCount = currentlyHeldBooks?.totalDocs || 0 + + const stats = [ + { + name: 'Hold Request', + iconSrc: '/images/mail.svg', + value: totalHoldNotifications, + href: '#', + ctaText: 'Answer Requests', + shouldAnimate: totalHoldNotifications > 0, + }, + { + name: 'Loaned Out', + iconSrc: '/images/book-loan.svg', + value: outBoundLoanCount, + href: '#', + ctaText: 'Handle Returns', + shouldAnimate: false, + }, + { + name: 'Currently Holding', + iconSrc: '/images/book-shelf.svg', + value: currentlyHoldingCount, + href: '#', + ctaText: 'Loan Out', + shouldAnimate: false, + }, + ] + return (

Outbound Activity

- {stats.map((item) => ( -
- {!!item.shouldHighlight && ( - - )} -
{item.name}
-
- {item.stat} -
-
- ))} + {stats.map((s) => { + return ( +
+
+
+ {s.name} +
+

+ {s.name} +

+
+
+

{s.value}

+ +
+
+ ) + })}

Inbound Activity

-

Your Holds

-
    +

    Your Holds

    +
      {holdRequests.docs?.map((h) => { const book = h.book as Book const repository = h.repository as Repository @@ -98,7 +194,7 @@ const UserFeed = async (props: Props) => { return (
    • - + {book.title} diff --git a/src/components/HomeHero.tsx b/src/components/HomeHero.tsx index 41a1ab0..0e2819d 100644 --- a/src/components/HomeHero.tsx +++ b/src/components/HomeHero.tsx @@ -77,7 +77,7 @@ const HomeHero = (props: Props) => {