11import Link from 'next/link' ;
2- import { PlusCircle } from 'lucide-react' ;
2+ import { ChevronLeft , ChevronRight , PlusCircle } from 'lucide-react' ;
33import { auth , } from '@clerk/nextjs/server' ;
4- import { eq , and , isNull } from 'drizzle-orm'
4+ import { eq , and , isNull , count } from 'drizzle-orm'
55
66import { db } from '@/db' ;
77import { Invoices , Customers } from '@/db/schema' ;
@@ -11,6 +11,7 @@ import { AVAILABLE_STATUSES } from '@/data/invoices';
1111import { Badge } from '@/components/ui/Badge' ;
1212import { Table , TableBody , TableCell , TableHead , TableHeader , TableRow } from '@/components/ui/Table' ;
1313import Container from '@/components/Container' ;
14+ import { Button } from '@/components/ui/Button' ;
1415
1516const INVOICES_PER_PAGE = 10 ;
1617
@@ -31,6 +32,17 @@ export default async function Dashboard({ searchParams }: { searchParams: { page
3132 . limit ( INVOICES_PER_PAGE )
3233 . offset ( INVOICES_PER_PAGE * ( currentPage - 1 ) ) ;
3334
35+ const [ { count : invoicesCount } ] = await db . select ( {
36+ count : count ( )
37+ } ) . from ( Invoices )
38+ . innerJoin ( Customers , eq ( Invoices . customer_id , Customers . id ) )
39+ . where (
40+ and (
41+ eq ( Invoices . user_id , userId ) ,
42+ isNull ( Invoices . organization_id )
43+ )
44+ ) ;
45+
3446 const invoices = result ?. map ( ( { invoices, customers} ) => {
3547 return {
3648 ...invoices ,
@@ -113,6 +125,73 @@ export default async function Dashboard({ searchParams }: { searchParams: { page
113125 } ) }
114126 </ TableBody >
115127 </ Table >
128+
129+ < ul className = "flex justify-between items-center text-sm mt-8" >
130+ < li >
131+ { currentPage > 1 && (
132+ < Link href = { {
133+ pathname : '/dashboard' ,
134+ query : {
135+ page : currentPage - 1
136+ }
137+ } } >
138+ < span className = "flex items-center gap-1" >
139+ < ChevronLeft className = "w-5 h-5" /> Previous
140+ </ span >
141+ </ Link >
142+ ) }
143+ { currentPage <= 1 && (
144+ < span className = "text-zinc-400 flex items-center gap-1" >
145+ < ChevronLeft className = "w-5 h-5" /> Previous
146+ </ span >
147+ ) }
148+ </ li >
149+
150+ { typeof invoicesCount === 'number' && (
151+ < li className = "flex-grow flex justify-center" >
152+ < ul className = "flex items-center gap-3" >
153+ { [ ...new Array ( Math . ceil ( invoicesCount / INVOICES_PER_PAGE ) ) ] . map ( ( _ , index ) => {
154+ const page = index + 1 ;
155+ return (
156+ < li key = { page } >
157+ < Button variant = { page === currentPage ? 'default' : 'outline' } asChild size = "sm" className = "h-auto px-2.5 py-1" >
158+ < Link href = { {
159+ pathname : '/dashboard' ,
160+ query : {
161+ page
162+ }
163+ } } >
164+ { page }
165+ </ Link >
166+ </ Button >
167+ </ li >
168+ )
169+ } ) }
170+ </ ul >
171+ </ li >
172+ ) }
173+
174+ < li >
175+ { currentPage < Math . ceil ( invoicesCount / INVOICES_PER_PAGE ) && (
176+ < Link href = { {
177+ pathname : '/dashboard' ,
178+ query : {
179+ page : currentPage + 1
180+ }
181+ } } >
182+ < span className = "flex items-center gap-1" >
183+ Next < ChevronRight className = "w-5 h-5" />
184+ </ span >
185+ </ Link >
186+ ) }
187+ { currentPage >= Math . ceil ( invoicesCount / INVOICES_PER_PAGE ) && (
188+ < span className = "text-zinc-400 flex items-center gap-1" >
189+ Next < ChevronRight className = "w-5 h-5" />
190+ </ span >
191+ ) }
192+ </ li >
193+ </ ul >
194+
116195 </ Container >
117196 ) ;
118197}
0 commit comments