diff --git a/dashboard/15-final/app/dashboard/invoices/page.tsx b/dashboard/15-final/app/dashboard/invoices/page.tsx
index fcf178aa..fd35c3f9 100644
--- a/dashboard/15-final/app/dashboard/invoices/page.tsx
+++ b/dashboard/15-final/app/dashboard/invoices/page.tsx
@@ -2,8 +2,10 @@ import Pagination from '@/app/ui/invoices/pagination';
import Search from '@/app/ui/search';
import { CreateInvoice } from '@/app/ui/invoices/buttons';
import Table from '@/app/ui/invoices/table';
-import { fetchFilteredInvoices } from '@/app/lib/data';
import { lusitana } from '@/app/ui/fonts';
+import { InvoicesTableSkeleton } from '@/app/ui/dashboard/skeletons';
+import { Suspense } from 'react';
+import { fetchInvoicesPages } from '@/app/lib/data';
export default async function Page({
searchParams,
@@ -14,12 +16,8 @@ export default async function Page({
};
}) {
const query = searchParams?.query || '';
- const currentPage = Number(searchParams?.page || '1');
-
- const { invoices, totalPages } = await fetchFilteredInvoices(
- query,
- currentPage,
- );
+ const currentPage = Number(searchParams?.page) || 1;
+ const totalPages = await fetchInvoicesPages(query);
return (
@@ -30,9 +28,11 @@ export default async function Page({
-
+ }>
+
+
);
diff --git a/dashboard/15-final/app/lib/data.ts b/dashboard/15-final/app/lib/data.ts
index 61b94a08..b5e75d5f 100644
--- a/dashboard/15-final/app/lib/data.ts
+++ b/dashboard/15-final/app/lib/data.ts
@@ -79,15 +79,15 @@ export async function fetchCardData() {
}
}
+const ITEMS_PER_PAGE = 6;
export async function fetchFilteredInvoices(
query: string,
currentPage: number,
) {
- const itemsPerPage = 6;
- const offset = (currentPage - 1) * itemsPerPage;
+ const offset = (currentPage - 1) * ITEMS_PER_PAGE;
try {
- const data = await sql`
+ const invoices = await sql`
SELECT
invoices.id,
invoices.amount,
@@ -105,34 +105,37 @@ export async function fetchFilteredInvoices(
invoices.date::text ILIKE ${`%${query}%`} OR
invoices.status ILIKE ${`%${query}%`}
ORDER BY invoices.date DESC
- LIMIT ${itemsPerPage} OFFSET ${offset}
+ LIMIT ${ITEMS_PER_PAGE} OFFSET ${offset}
`;
- const count = await sql`
- SELECT COUNT(*)
- FROM invoices
- JOIN customers ON invoices.customer_id = customers.id
- WHERE
- customers.name ILIKE ${`%${query}%`} OR
- customers.email ILIKE ${`%${query}%`} OR
- invoices.amount::text ILIKE ${`%${query}%`} OR
- invoices.date::text ILIKE ${`%${query}%`} OR
- invoices.status ILIKE ${`%${query}%`}
- `;
-
- const totalRecords = Number(count.rows[0].count);
- const totalPages = Math.ceil(totalRecords / itemsPerPage);
-
- return {
- invoices: data.rows,
- totalPages,
- };
+ return invoices.rows;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch invoices.');
}
}
+export async function fetchInvoicesPages(query: string) {
+ try {
+ const count = await sql`SELECT COUNT(*)
+ FROM invoices
+ JOIN customers ON invoices.customer_id = customers.id
+ WHERE
+ customers.name ILIKE ${`%${query}%`} OR
+ customers.email ILIKE ${`%${query}%`} OR
+ invoices.amount::text ILIKE ${`%${query}%`} OR
+ invoices.date::text ILIKE ${`%${query}%`} OR
+ invoices.status ILIKE ${`%${query}%`}
+ `;
+
+ const totalPages = Math.ceil(Number(count.rows[0].count) / ITEMS_PER_PAGE);
+ return totalPages;
+ } catch (error) {
+ console.error('Database Error:', error);
+ throw new Error('Failed to fetch total number of invoices.');
+ }
+}
+
export async function fetchInvoiceById(id: string) {
try {
const data = await sql`
diff --git a/dashboard/15-final/app/ui/dashboard/skeletons.tsx b/dashboard/15-final/app/ui/dashboard/skeletons.tsx
index cdab3bad..c57322d1 100644
--- a/dashboard/15-final/app/ui/dashboard/skeletons.tsx
+++ b/dashboard/15-final/app/ui/dashboard/skeletons.tsx
@@ -90,3 +90,118 @@ export default function DashboardSkeleton() {
>
);
}
+
+export function TableRowSkeleton() {
+ return (
+
+ {/* Customer Name and Image */}
+
+
+ |
+ {/* Email */}
+
+
+ |
+ {/* Amount */}
+
+
+ |
+ {/* Date */}
+
+
+ |
+ {/* Status */}
+
+
+ |
+ {/* Actions */}
+
+
+ |
+
+ );
+}
+
+export function InvoicesMobileSkeleton() {
+ return (
+
+ );
+}
+
+export function InvoicesTableSkeleton() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Customer
+ |
+
+ Email
+ |
+
+ Amount
+ |
+
+ Date
+ |
+
+ Status
+ |
+
+ Edit
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/dashboard/15-final/app/ui/invoices/pagination.tsx b/dashboard/15-final/app/ui/invoices/pagination.tsx
index a9c6dbaa..e9d0293a 100644
--- a/dashboard/15-final/app/ui/invoices/pagination.tsx
+++ b/dashboard/15-final/app/ui/invoices/pagination.tsx
@@ -6,15 +6,11 @@ import Link from 'next/link';
import { generatePagination } from '@/app/lib/utils';
import { usePathname, useSearchParams } from 'next/navigation';
-export default function Pagination({
- currentPage,
- totalPages,
-}: {
- currentPage: number;
- totalPages: number;
-}) {
+export default function Pagination({ totalPages }: { totalPages: number }) {
const pathname = usePathname();
const searchParams = useSearchParams();
+ const currentPage = Number(searchParams.get('page')) || 1;
+ const allPages = generatePagination(currentPage, totalPages);
const createPageURL = (pageNumber: number | string) => {
const params = new URLSearchParams(searchParams);
@@ -22,8 +18,6 @@ export default function Pagination({
return `${pathname}?${params.toString()}`;
};
- const allPages = generatePagination(currentPage, totalPages);
-
return (
-
-
-
-
-
+
+
+
+ {invoices?.map((invoice) => (
+
+
+
+
+
+ {formatCurrency(invoice.amount)}
+
+
{formatDateToLocal(invoice.date)}
+
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ Customer
+ |
+
+ Email
+ |
+
+ Amount
+ |
+
+ Date
+ |
+
+ Status
+ |
+
+ Edit
+ |
+
+
+
{invoices?.map((invoice) => (
-
-
-
-
-
{invoice.email}
+
+
+ |
+
+ {invoice.email}
+ |
+
+ {formatCurrency(invoice.amount)}
+ |
+
+ {formatDateToLocal(invoice.date)}
+ |
+
-
-
-
-
- {formatCurrency(invoice.amount)}
-
- {formatDateToLocal(invoice.date)}
-
-
+ |
+
+
-
-
- ))}
-
-
-
-
-
- Customer
- |
-
- Email
- |
-
- Amount
- |
-
- Date
- |
-
- Status
- |
-
- Edit
- |
+
-
-
- {invoices?.map((invoice) => (
-
-
-
- |
-
- {invoice.email}
- |
-
- {formatCurrency(invoice.amount)}
- |
-
- {formatDateToLocal(invoice.date)}
- |
-
-
- |
-
-
-
- |
-
- ))}
-
-
-
+ ))}
+ |
+