Skip to content

Commit

Permalink
added pgae navigator
Browse files Browse the repository at this point in the history
  • Loading branch information
VijeshVS committed May 31, 2024
1 parent f0681f3 commit e39a949
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 32 deletions.
2 changes: 1 addition & 1 deletion app/app/(dashboard)/links/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function CreatePage() {
}
setLongurl("");
setTitle("");

setShortLink("");
// setLoading(false);
});
}}
Expand Down
176 changes: 150 additions & 26 deletions app/app/(dashboard)/links/page.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,182 @@
"use client"
"use client";

import { DatePickerWithRange } from "@/components/DialogComponents/DatePickerWithRange";
import React, { useEffect, useState } from 'react'
import React, { useEffect, useState } from "react";
import { FilterDialog } from "@/components/DialogComponents/FilterDialog";
import { LinkCard } from "@/components/CardComponents/LinkCard";

import { getLinks } from "@/lib/actions/getLinksAction";
import { DateRange } from "react-day-picker";
import Loading from "./loading";
import { linkType } from "@/interfaces/types";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import { toast } from "@/components/ui/use-toast";

export default function Page() {
const [filteredLinks, setFilteredLinks] = useState<linkType[] | undefined>(
[]
);
const [loading, setLoading] = useState<Boolean>(true);
const current_date = new Date();
const [date, setDate] = React.useState<DateRange | undefined>({
to: new Date(
current_date.getFullYear(),
current_date.getMonth(),
current_date.getDate() + 1
),
from: new Date(2024, 4, 18),
});

const [totalPages,setTotalPages] = useState(0);

export default function Page() {
enum paginateOperation {
NEXT,
PREV,
CLICK
}

const [filteredLinks,setFilteredLinks] = useState<linkType[] | undefined>([])
const [loading,setLoading] = useState<Boolean>(true)
const current_date = new Date()
const [date, setDate] = React.useState<DateRange | undefined>({
to: new Date(current_date.getFullYear(), current_date.getMonth(), current_date.getDate()+1),
from: new Date(2024, 4, 18),
enum pageOrder {
ONE = 0,
TWO = 1,
THREE = 2
}

type paginationType = {
value: number,
pageActive: pageOrder
}

const [paginator,setPaginator] = useState<paginationType>({
value: 1,
pageActive: pageOrder.ONE
})

useEffect(()=>{
setLoading(true)
getLinks().then((res)=>{
const linkList:linkType[] | undefined = res.links;
const from: Date | undefined = date?.from;
const to: Date | undefined = date?.to;
const filterLinks: linkType[] | undefined = linkList?.filter((link)=>{
return (!from || link.created_at >=from) && (!to || link.created_at <= to)
const pagination = (page:pageOrder,action:paginateOperation)=>{
if(page+paginator.value > totalPages && page+paginator.value != 1 || (paginator.pageActive +paginator.value + 1 > totalPages && action == paginateOperation.NEXT)){
toast({
title: "End of the links",
description:"That's all we have"
})
return;
}

if(paginateOperation.NEXT == action){
if(paginator.pageActive == pageOrder.ONE) {
setPaginator((c)=>{
return {...c,pageActive:pageOrder.TWO}
})
}
else if(paginator.pageActive == pageOrder.TWO){
setPaginator((c)=>{
return {...c,pageActive:pageOrder.THREE}
})
}
else{
setPaginator((c)=>{
return {value:c.value+1,pageActive:pageOrder.THREE}
})
}
}
else if(paginateOperation.PREV == action){
if(paginator.pageActive == pageOrder.THREE) {
setPaginator((c)=>{
return {...c,pageActive:pageOrder.TWO}
})
setFilteredLinks(filterLinks)
setLoading(false)
})
}
else if(paginator.pageActive == pageOrder.TWO){
setPaginator((c)=>{
return {...c,pageActive:pageOrder.ONE}
})
}
else{
setPaginator((c)=>{
return {value:c.value - Number(c.value != 1) ,pageActive:pageOrder.ONE}
})
}
}
else {
setPaginator((c)=>{
return {...c,pageActive:page}
})
}
}

useEffect(() => {
setLoading(true);
getLinks((paginator.value + paginator.pageActive).toString()).then((res) => {
const linkList: linkType[] | undefined = res.links;
setTotalPages(res.total_pages || 0)
const from: Date | undefined = date?.from;
const to: Date | undefined = date?.to;
const filterLinks: linkType[] | undefined = linkList?.filter((link) => {
return (
(!from || link.created_at >= from) && (!to || link.created_at <= to)
);
});

setFilteredLinks(filterLinks);
setLoading(false);
});
}, [date,paginator]);

},[date])

return (
<div className="pt-10 md:pl-6 pl-2 w-full pr-2">
<h1 className="font-bold text-3xl ml-3">Links</h1>
<div className="flex mt-6 md:flex-row flex-col">
<div className="ml-2">
<DatePickerWithRange date={date} setDate={setDate} current_date={current_date}/>
<DatePickerWithRange
date={date}
setDate={setDate}
current_date={current_date}
/>
</div>
<div className="mt-3 md:mt-0 ml-0 md:ml-4">
<FilterDialog />
</div>
</div>

{loading?<Loading/>:<div>{filteredLinks?.map((link) => (
<LinkCard key={link.id} link={link} />
))}</div>}
{loading ? (
<Loading />
) : (
<div>
{filteredLinks?.map((link) => (
<LinkCard key={link.id} link={link} />
))}
</div>
)}

<Pagination className="mt-14">
<PaginationContent>
<PaginationItem>
<PaginationPrevious onClick={()=>pagination(0,paginateOperation.PREV)} href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink onClick={()=>pagination(pageOrder.ONE,paginateOperation.CLICK)} isActive={paginator.pageActive == pageOrder.ONE} href="#">{paginator.value}</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink onClick={()=>pagination(pageOrder.TWO,paginateOperation.CLICK)} isActive={paginator.pageActive == pageOrder.TWO} href="#">
{paginator.value + 1}
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink onClick={()=>pagination(pageOrder.THREE,paginateOperation.CLICK)} isActive={paginator.pageActive == pageOrder.THREE} href="#">{paginator.value + 2}</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext onClick={()=>pagination(0,paginateOperation.NEXT)} href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
);
}
121 changes: 121 additions & 0 deletions components/ui/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import * as React from "react"
import {
ChevronLeftIcon,
ChevronRightIcon,
DotsHorizontalIcon,
} from "@radix-ui/react-icons"

import { cn } from "@/lib/utils"
import { ButtonProps, buttonVariants } from "@/components/ui/button"

const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
role="navigation"
aria-label="pagination"
className={cn("mx-auto flex w-full justify-center", className)}
{...props}
/>
)
Pagination.displayName = "Pagination"

const PaginationContent = React.forwardRef<
HTMLUListElement,
React.ComponentProps<"ul">
>(({ className, ...props }, ref) => (
<ul
ref={ref}
className={cn("flex flex-row items-center gap-1", className)}
{...props}
/>
))
PaginationContent.displayName = "PaginationContent"

const PaginationItem = React.forwardRef<
HTMLLIElement,
React.ComponentProps<"li">
>(({ className, ...props }, ref) => (
<li ref={ref} className={cn("", className)} {...props} />
))
PaginationItem.displayName = "PaginationItem"

type PaginationLinkProps = {
isActive?: boolean
} & Pick<ButtonProps, "size"> &
React.ComponentProps<"a">

const PaginationLink = ({
className,
isActive,
size = "icon",
...props
}: PaginationLinkProps) => (
<a
aria-current={isActive ? "page" : undefined}
className={cn(
buttonVariants({
variant: isActive ? "outline" : "ghost",
size,
}),
className
)}
{...props}
/>
)
PaginationLink.displayName = "PaginationLink"

const PaginationPrevious = ({
className,
...props
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to previous page"
size="default"
className={cn("gap-1 pl-2.5", className)}
{...props}
>
<ChevronLeftIcon className="h-4 w-4" />
<span>Previous</span>
</PaginationLink>
)
PaginationPrevious.displayName = "PaginationPrevious"

const PaginationNext = ({
className,
...props
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to next page"
size="default"
className={cn("gap-1 pr-2.5", className)}
{...props}
>
<span>Next</span>
<ChevronRightIcon className="h-4 w-4" />
</PaginationLink>
)
PaginationNext.displayName = "PaginationNext"

const PaginationEllipsis = ({
className,
...props
}: React.ComponentProps<"span">) => (
<span
aria-hidden
className={cn("flex h-9 w-9 items-center justify-center", className)}
{...props}
>
<DotsHorizontalIcon className="h-4 w-4" />
<span className="sr-only">More pages</span>
</span>
)
PaginationEllipsis.displayName = "PaginationEllipsis"

export {
Pagination,
PaginationContent,
PaginationLink,
PaginationItem,
PaginationPrevious,
PaginationNext,
PaginationEllipsis,
}
13 changes: 8 additions & 5 deletions lib/actions/getLinksAction.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
"use server"

import { NextRequest } from "next/server";
import { getServerSession } from "next-auth";
import { ISessionType } from "@/interfaces/url";
import authOptions from "@/lib/authOptions";
import PrismaClientManager from "@/lib/services/pgConnect";
import { HTTP_STATUS, RESPONSE } from "@/lib/constants";
import { HTTP_STATUS } from "@/lib/constants";

export async function getLinks() {
export async function getLinks(pageNumber: string) {
const posgresInstance = PrismaClientManager.getInstance();
const prisma = posgresInstance.getPrismaClient();
const session: ISessionType | null = await getServerSession(authOptions);
// const searchParams = req.nextUrl.searchParams;

const page_size = "10";
const page = "1";
const page_size = "5";
const page = pageNumber;

if (!session?.user) {
return {
Expand All @@ -37,6 +36,9 @@ export async function getLinks() {
status:HTTP_STATUS.OK
}
}

const total_pages = Math.ceil(totalLinks/Number.parseInt(page_size))

const links = await prisma.links.findMany({
where: {
user: {
Expand All @@ -49,6 +51,7 @@ export async function getLinks() {
return {
links,
totalLinks,
total_pages,
status: HTTP_STATUS.CREATED
}
}
Expand Down

0 comments on commit e39a949

Please sign in to comment.