From 53aedb801240e1bf975e191b4a6854651b2ed575 Mon Sep 17 00:00:00 2001 From: Collin Schaafsma Date: Sat, 12 Oct 2024 13:51:18 -0600 Subject: [PATCH] recent transactions --- .../_components/recent-transactions-card.tsx | 109 ++++++++++++++---- drizzle/schema.ts | 7 ++ services/analytic.ts | 26 ++++- 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/app/(app)/dashboard/_components/recent-transactions-card.tsx b/app/(app)/dashboard/_components/recent-transactions-card.tsx index 63c0210..2bca1e9 100644 --- a/app/(app)/dashboard/_components/recent-transactions-card.tsx +++ b/app/(app)/dashboard/_components/recent-transactions-card.tsx @@ -1,3 +1,6 @@ +import { Suspense } from "react" +import { analytic } from "@/services/analytic" +import { invoice } from "@/services/invoice" import { Card, CardContent, @@ -5,6 +8,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card" +import { Skeleton } from "@/components/ui/skeleton" import { Table, TableBody, @@ -13,26 +17,87 @@ import { TableHeader, TableRow, } from "@/components/ui/table" +import { ErrorBoundary } from "@/components/error-boundary" -export function RecentTransactionsCard({ className }: { className?: string }) { - const recentTransactions = [ - { id: 1, email: "johndoe@example.com", amount: 1200, status: "Completed" }, - { id: 2, email: "janedoe@example.com", amount: 850, status: "Pending" }, - { id: 3, email: "jimsmith@example.com", amount: 2300, status: "Completed" }, - { id: 4, email: "jilljones@example.com", amount: 1750, status: "Failed" }, - { - id: 5, - email: "mikebrown@example.com", - amount: 3100, - status: "Completed", - }, - ] +async function LoadRecentTransactions() { + const recentTransactions = await invoice.list({ + range: { from: new Date(1978, 0, 1), to: new Date() }, + limit: 5, + }) + + if (recentTransactions.length === 0) { + return ( + + No transactions found + + ) + } + + return ( + <> + {recentTransactions.map(transaction => ( + + + {transaction.user.email} + + ${transaction.amountPaid / 100} + {transaction.status} + + ))} + + ) +} + +function RecentTransactionsSkeleton() { + return ( + + + + + + ) +} + +function RecentTransactionsErrorFallback() { + return ( + + +
Failed to load recent transactions
+
+
+ ) +} +async function SalesThisMonth() { + const salesCountThisMonth = await analytic.salesCount({ + from: new Date(new Date().getFullYear(), new Date().getMonth(), 1), + to: new Date(), + }) + + return ( + <> + You made {salesCountThisMonth}{" "} + {salesCountThisMonth === 1 ? "sale" : "sales"} this month. + + ) +} + +function SalesThisMonthSkeleton() { + return <>You made 0 sales this month. +} + +export function RecentTransactionsCard({ className }: { className?: string }) { return ( Recent Transactions - You made 265 sales this month. + + + }> + + + + @@ -44,17 +109,11 @@ export function RecentTransactionsCard({ className }: { className?: string }) { - {recentTransactions.map(transaction => ( - - - {transaction.email} - - ${transaction.amount} - - {transaction.status} - - - ))} + }> + }> + + +
diff --git a/drizzle/schema.ts b/drizzle/schema.ts index 6214927..6aea2ff 100644 --- a/drizzle/schema.ts +++ b/drizzle/schema.ts @@ -380,6 +380,13 @@ export const invoices = pgTable("invoice", { .references(() => users.id), }) +export const invoicesRelations = relations(invoices, ({ one }) => ({ + user: one(users, { + fields: [invoices.userId], + references: [users.id], + }), +})) + // Product types export type Product = InferSelectModel export type NewProduct = InferInsertModel diff --git a/services/analytic.ts b/services/analytic.ts index daaebf0..f35face 100644 --- a/services/analytic.ts +++ b/services/analytic.ts @@ -1,5 +1,8 @@ import { unstable_cache as ioCache } from "next/cache" +import { and, between, count, eq } from "drizzle-orm" import { ListContactsResponse, Resend } from "resend" +import { db } from "@/drizzle/db" +import { checkoutSessions } from "@/drizzle/schema" import { resendAudienceId, resendEnabled } from "@/lib/constants" import { logger } from "@/lib/logger" import { customer } from "./customer" @@ -198,7 +201,7 @@ export const analytic = { * @returns {Promise} - The calculated gross. */ async gross(range: { from: Date; to: Date }) { - const invoices = await invoice.list(range) + const invoices = await invoice.list({ range }) const gross = invoices.reduce((acc, invoice) => { return acc + invoice.amountPaid }, 0) @@ -216,4 +219,25 @@ export const analytic = { async customerCount(range: { from: Date; to: Date }) { return (await customer.count(range))[0].count }, + /** + * Sales Count + * + * This function calculates the sales count for the dashboard. + * + * @returns {Promise} - The calculated sales count. + */ + async salesCount(range: { from: Date; to: Date }) { + return ( + await db + .select({ count: count() }) + .from(checkoutSessions) + .where( + and( + between(checkoutSessions.created, range.from, range.to), + eq(checkoutSessions.status, "complete"), + eq(checkoutSessions.paymentStatus, "paid") + ) + ) + )[0].count + }, }