Skip to content

Commit

Permalink
Merge pull request #6 from usual2970/feat/pagination
Browse files Browse the repository at this point in the history
Feat/pagination
  • Loading branch information
usual2970 authored Sep 2, 2024
2 parents d826e64 + 10a9efe commit 6967107
Show file tree
Hide file tree
Showing 12 changed files with 553 additions and 263 deletions.
Binary file added certimate
Binary file not shown.
1 change: 1 addition & 0 deletions ui/dist/assets/index-BPSHHpDP.css

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions ui/dist/assets/index-CglXs5Ou.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion ui/dist/assets/index-DHLrqoj1.css

This file was deleted.

249 changes: 0 additions & 249 deletions ui/dist/assets/index-nGGiqZOp.js

This file was deleted.

4 changes: 2 additions & 2 deletions ui/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Certimate - Your Trusted SSL Automation Partner</title>
<script type="module" crossorigin src="/assets/index-nGGiqZOp.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DHLrqoj1.css">
<script type="module" crossorigin src="/assets/index-CglXs5Ou.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BPSHHpDP.css">
</head>
<body class="bg-background">
<div id="root"></div>
Expand Down
102 changes: 102 additions & 0 deletions ui/src/components/certimate/XPagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
} from "../ui/pagination";

type PaginationProps = {
totalPages: number;
currentPage: number;
onPageChange: (page: number) => void;
};

type PageNumber = number | string;

const XPagination = ({
totalPages,
currentPage,
onPageChange,
}: PaginationProps) => {
const pageNeighbours = 1; // Number of page numbers to show on either side of the current page

const getPageNumbers = () => {
const totalNumbers = pageNeighbours * 2 + 3; // total pages to display (left + right neighbours + current + 2 for start and end)
const totalBlocks = totalNumbers + 2; // adding 2 for the start and end page numbers

if (totalPages > totalBlocks) {
let pages: PageNumber[] = [];

const leftBound = Math.max(2, currentPage - pageNeighbours);
const rightBound = Math.min(totalPages - 1, currentPage + pageNeighbours);

const beforeLastPage = totalPages - 1;

pages = range(leftBound, rightBound);

if (currentPage > pageNeighbours + 2) {
pages.unshift("...");
}
if (currentPage < beforeLastPage - pageNeighbours) {
pages.push("...");
}

pages.unshift(1);
pages.push(totalPages);

return pages;
}

return range(1, totalPages);
};

const range = (from: number, to: number, step = 1) => {
let i = from;
const range = [];

while (i <= to) {
range.push(i);
i += step;
}

return range;
};

const pages = getPageNumbers();

return (
<>
<Pagination className="dark:text-stone-200 justify-end mt-3">
<PaginationContent>
{pages.map((page, index) => {
if (page === "...") {
return (
<PaginationItem key={index}>
<PaginationEllipsis />
</PaginationItem>
);
}

return (
<PaginationItem key={index}>
<PaginationLink
href="#"
isActive={currentPage == page}
onClick={(e) => {
e.preventDefault();
onPageChange(page as number);
}}
>
{page}
</PaginationLink>
</PaginationItem>
);
})}
</PaginationContent>
</Pagination>
</>
);
};

export default XPagination;
117 changes: 117 additions & 0 deletions ui/src/components/ui/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import * as React from "react";
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";

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}
>
<ChevronLeft className="h-4 w-4" />
<span>上一页</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>下一页</span>
<ChevronRight 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}
>
<MoreHorizontal className="h-4 w-4" />
<span className="sr-only">More pages</span>
</span>
);
PaginationEllipsis.displayName = "PaginationEllipsis";

export {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
};
2 changes: 1 addition & 1 deletion ui/src/pages/DashboardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export default function Dashboard() {
href="https://github.com/usual2970/certimate/releases"
target="_blank"
>
Certimate v0.0.13
Certimate v0.0.14
</a>
</div>
</div>
Expand Down
25 changes: 24 additions & 1 deletion ui/src/pages/access/Access.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import { AccessEdit } from "@/components/certimate/AccessEdit";
import XPagination from "@/components/certimate/XPagination";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { Access as AccessType, accessTypeMap } from "@/domain/access";
import { convertZulu2Beijing } from "@/lib/time";
import { useConfig } from "@/providers/config";
import { remove } from "@/repository/access";
import { Key } from "lucide-react";
import { useLocation, useNavigate } from "react-router-dom";

const Access = () => {
const { config, deleteAccess } = useConfig();
const { accesses } = config;

const perPage = 10;

const totalPages = Math.ceil(accesses.length / perPage);

const navigate = useNavigate();
const location = useLocation();
const query = new URLSearchParams(location.search);
const page = query.get("page");
const pageNumber = page ? Number(page) : 1;

const startIndex = (pageNumber - 1) * perPage;
const endIndex = startIndex + perPage;

const handleDelete = async (data: AccessType) => {
const rs = await remove(data);
deleteAccess(rs.id);
Expand Down Expand Up @@ -50,7 +65,7 @@ const Access = () => {
<div className="sm:hidden flex text-sm text-muted-foreground">
授权列表
</div>
{accesses.map((access) => (
{accesses.slice(startIndex, endIndex).map((access) => (
<div
className="flex flex-col sm:flex-row text-secondary-foreground border-b dark:border-stone-500 sm:p-2 hover:bg-muted/50 text-sm"
key={access.id}
Expand Down Expand Up @@ -95,6 +110,14 @@ const Access = () => {
</div>
</div>
))}
<XPagination
totalPages={totalPages}
currentPage={pageNumber}
onPageChange={(page) => {
query.set("page", page.toString());
navigate({ search: query.toString() });
}}
/>
</>
)}
</div>
Expand Down
34 changes: 30 additions & 4 deletions ui/src/pages/domains/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DeployProgress from "@/components/certimate/DeployProgress";
import XPagination from "@/components/certimate/XPagination";
import Show from "@/components/Show";
import {
AlertDialogAction,
Expand Down Expand Up @@ -32,16 +33,28 @@ import {
import { TooltipContent, TooltipProvider } from "@radix-ui/react-tooltip";
import { CircleCheck, CircleX, Earth } from "lucide-react";
import { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { Link, useLocation, useNavigate } from "react-router-dom";

const Home = () => {
const toast = useToast();

const navigate = useNavigate();

const location = useLocation();
const query = new URLSearchParams(location.search);
const page = query.get("page");

const [totalPage, setTotalPage] = useState(0);

const handleCreateClick = () => {
navigate("/edit");
};

const setPage = (newPage: number) => {
query.set("page", newPage.toString());
navigate(`?${query.toString()}`);
};

const handleEditClick = (id: string) => {
navigate(`/edit?id=${id}`);
};
Expand All @@ -63,11 +76,16 @@ const Home = () => {

useEffect(() => {
const fetchData = async () => {
const data = await list();
setDomains(data);
const data = await list({
page: page ? Number(page) : 1,
perPage: 10,
});

setDomains(data.items);
setTotalPage(data.totalPages);
};
fetchData();
}, []);
}, [page]);

const handelCheckedChange = async (id: string) => {
const checkedDomains = domains.filter((domain) => domain.id === id);
Expand Down Expand Up @@ -323,6 +341,14 @@ const Home = () => {
</div>
</div>
))}

<XPagination
totalPages={totalPage}
currentPage={page ? Number(page) : 1}
onPageChange={(page) => {
setPage(page);
}}
/>
</>
)}
</div>
Expand Down
Loading

0 comments on commit 6967107

Please sign in to comment.