style: update better visibility pagination
This commit is contained in:
parent
67f2fccd33
commit
8204b15b4b
|
|
@ -20,7 +20,7 @@ export function BrandFilter() {
|
|||
<button
|
||||
onClick={() => handleSelect(null)}
|
||||
className={cn(
|
||||
"rounded-lg border px-4 py-2 text-sm font-medium transition-all",
|
||||
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer",
|
||||
selectedBrand === null
|
||||
? "border-primary bg-primary text-primary-foreground"
|
||||
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
|
||||
|
|
@ -40,7 +40,7 @@ export function BrandFilter() {
|
|||
key={brand.name}
|
||||
onClick={() => handleSelect(brand.name)}
|
||||
className={cn(
|
||||
"rounded-lg border px-4 py-2 text-sm font-medium transition-all",
|
||||
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer",
|
||||
isActive
|
||||
? "border-primary bg-primary text-primary-foreground"
|
||||
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
|
||||
|
|
|
|||
|
|
@ -9,24 +9,20 @@ import {
|
|||
TableRow,
|
||||
} from "../../components/ui/table";
|
||||
import { Badge } from "../../components/ui/badge";
|
||||
import { EllipsisVertical, Inbox, Loader2, Pencil, Trash } from "lucide-react";
|
||||
import { Inbox, Loader2 } from "lucide-react";
|
||||
import getSentimentBadge from "./SentimentBadge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "../ui/dropdown-menu";
|
||||
import { useReviewTable } from "@/src/hooks/useReviewTable";
|
||||
import {
|
||||
Pagination,
|
||||
PaginationContent,
|
||||
PaginationEllipsis,
|
||||
PaginationItem,
|
||||
PaginationLink,
|
||||
PaginationNext,
|
||||
PaginationPrevious,
|
||||
} from "../ui/pagination";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { getVisiblePages } from "@/src/utils/datas";
|
||||
|
||||
export function ReviewTable() {
|
||||
const searchParams = useSearchParams();
|
||||
|
|
@ -36,6 +32,7 @@ export function ReviewTable() {
|
|||
selectedBrand,
|
||||
);
|
||||
const { currentPage, totalPages, nextPage, prevPage, goToPage } = pagination;
|
||||
const visiblePage = getVisiblePages({ totalPages, currentPage });
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
|
|
@ -171,7 +168,7 @@ export function ReviewTable() {
|
|||
</TableBody>
|
||||
</Table>
|
||||
|
||||
{totalPages > 1 && (
|
||||
{/* {totalPages > 1 && (
|
||||
<div className="border-t bg-muted/20 px-6 py-4">
|
||||
<Pagination className="justify-center sm:justify-end">
|
||||
<PaginationContent>
|
||||
|
|
@ -222,6 +219,63 @@ export function ReviewTable() {
|
|||
</PaginationContent>
|
||||
</Pagination>
|
||||
</div>
|
||||
)} */}
|
||||
|
||||
{totalPages > 1 && (
|
||||
<div className="border-t bg-muted/20 px-6 py-4">
|
||||
<Pagination className="justify-center sm:justify-end">
|
||||
<PaginationContent>
|
||||
<PaginationItem>
|
||||
<PaginationPrevious
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
prevPage();
|
||||
}}
|
||||
className={
|
||||
currentPage === 1
|
||||
? "pointer-events-none opacity-50"
|
||||
: "cursor-pointer hover:bg-[#F8FBFF] hover:text-primary"
|
||||
}
|
||||
/>
|
||||
</PaginationItem>
|
||||
|
||||
{visiblePage.map((page, index) => (
|
||||
<PaginationItem key={index}>
|
||||
{page === "..." ? (
|
||||
<PaginationEllipsis />
|
||||
) : (
|
||||
<PaginationLink
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
goToPage(page as number);
|
||||
}}
|
||||
isActive={currentPage === page}
|
||||
>
|
||||
{page}
|
||||
</PaginationLink>
|
||||
)}
|
||||
</PaginationItem>
|
||||
))}
|
||||
|
||||
<PaginationItem>
|
||||
<PaginationNext
|
||||
href="#"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
nextPage();
|
||||
}}
|
||||
className={
|
||||
currentPage === totalPages
|
||||
? "pointer-events-none opacity-50"
|
||||
: "cursor-pointer hover:bg-primary hover:text-card"
|
||||
}
|
||||
/>
|
||||
</PaginationItem>
|
||||
</PaginationContent>
|
||||
</Pagination>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const buttonVariants = cva(
|
|||
ghost:
|
||||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
primary: "bg-primary text-card"
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ function PaginationLink({
|
|||
data-active={isActive}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? "outline" : "ghost",
|
||||
variant: isActive ? "primary" : "ghost",
|
||||
size,
|
||||
}),
|
||||
className,
|
||||
|
|
|
|||
|
|
@ -285,3 +285,8 @@ export type AnalysisData = {
|
|||
};
|
||||
|
||||
export type BodyData = (req: Request, body: any) => Promise<NextResponse>;
|
||||
|
||||
export interface VisiblePageProps {
|
||||
totalPages: number;
|
||||
currentPage: number;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
import { ScrapeResult, WordCloudConfig, WordItem } from "../types";
|
||||
import { useReviewTable } from "../hooks/useReviewTable";
|
||||
import {
|
||||
ScrapeResult,
|
||||
VisiblePageProps,
|
||||
WordCloudConfig,
|
||||
WordItem,
|
||||
} from "../types";
|
||||
import { Brand } from "@prisma/client";
|
||||
|
||||
export const setWordCloud = ({ maxValue, minValue }: WordCloudConfig) => {
|
||||
|
|
@ -24,7 +30,7 @@ export const setWordCloud = ({ maxValue, minValue }: WordCloudConfig) => {
|
|||
return { getSize, getColor };
|
||||
};
|
||||
|
||||
export function getFallbackData(url: string): ScrapeResult {
|
||||
export const getFallbackData = (url: string): ScrapeResult => {
|
||||
return {
|
||||
name: "Produk (Data Sampel)",
|
||||
url: url,
|
||||
|
|
@ -39,7 +45,7 @@ export function getFallbackData(url: string): ScrapeResult {
|
|||
"Pengiriman cepat dan packing kayu sangat aman.",
|
||||
],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const formatRupiah = (value: number | string) => {
|
||||
if (!value) return "Rp 0";
|
||||
|
|
@ -63,10 +69,42 @@ export const brandFormat = ({
|
|||
return { brands };
|
||||
};
|
||||
|
||||
export function toTitleCase(str: string) {
|
||||
export const toTitleCase = (str: string) => {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.split(/[\s-_]+/)
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" ");
|
||||
}
|
||||
};
|
||||
|
||||
export const getVisiblePages = (data: VisiblePageProps) => {
|
||||
if (data.totalPages <= 6) {
|
||||
return Array.from({ length: data.totalPages }, (_, i) => i + 1);
|
||||
}
|
||||
|
||||
if (data.currentPage <= 3) {
|
||||
return [1, 2, 3, 4, 5, "...", data.totalPages];
|
||||
}
|
||||
|
||||
if (data.currentPage >= data.totalPages - 2) {
|
||||
return [
|
||||
1,
|
||||
"...",
|
||||
data.totalPages - 4,
|
||||
data.totalPages - 3,
|
||||
data.totalPages - 2,
|
||||
data.totalPages - 1,
|
||||
data.totalPages,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
1,
|
||||
"...",
|
||||
data.currentPage - 1,
|
||||
data.currentPage,
|
||||
data.currentPage + 1,
|
||||
"...",
|
||||
data.totalPages,
|
||||
];
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue