This commit is contained in:
ct
2025-07-16 22:10:59 +08:00
parent fe32ffda42
commit a1f17325f1
2 changed files with 42 additions and 38 deletions

View File

@@ -25,7 +25,7 @@ private function getMemes(?string $search = null): Response
{ {
$query = MemeMedia::query() $query = MemeMedia::query()
->where('is_enabled', true) ->where('is_enabled', true)
->orderBy('created_at', 'desc'); ->orderBy('id', 'desc');
// Search functionality // Search functionality
if ($search) { if ($search) {
@@ -39,7 +39,7 @@ private function getMemes(?string $search = null): Response
}); });
} }
$memes = $query->paginate(12); $memes = $query->cursorPaginate(24);
// Get available types for filter // Get available types for filter
$types = MemeMedia::where('is_enabled', true) $types = MemeMedia::where('is_enabled', true)

View File

@@ -25,23 +25,18 @@ interface MemeMedia {
slug: string; slug: string;
} }
interface PaginationLinks { interface CursorPaginatedMemes {
url: string | null;
label: string;
active: boolean;
}
interface PaginatedMemes {
data: MemeMedia[]; data: MemeMedia[];
current_page: number; next_cursor: string | null;
last_page: number; prev_cursor: string | null;
next_page_url: string | null;
prev_page_url: string | null;
per_page: number; per_page: number;
total: number; path: string;
links: PaginationLinks[];
} }
interface Props { interface Props {
memes: PaginatedMemes; memes: CursorPaginatedMemes;
types: string[]; types: string[];
popularKeywords: string[]; popularKeywords: string[];
filters: { filters: {
@@ -75,10 +70,6 @@ export default function MemesIndex({ memes, popularKeywords, filters }: Props) {
router.get(route('memes.search', urlSegment)); router.get(route('memes.search', urlSegment));
}; };
const handlePageChange = (url: string) => {
router.get(url);
};
return ( return (
<> <>
<div className="min-h-screen bg-neutral-50 pb-10 dark:bg-black"> <div className="min-h-screen bg-neutral-50 pb-10 dark:bg-black">
@@ -148,13 +139,6 @@ export default function MemesIndex({ memes, popularKeywords, filters }: Props) {
</CardContent> </CardContent>
</Card> </Card>
{/* Results Count */}
<div className="mb-6 flex items-center justify-between">
<p className="text-muted-foreground">
Showing {memes.data.length} of {memes.total} memes
</p>
</div>
{/* Memes Grid */} {/* Memes Grid */}
<div className="xs:grid-cols-2 mb-8 grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6"> <div className="xs:grid-cols-2 mb-8 grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6">
{memes.data.map((meme) => ( {memes.data.map((meme) => (
@@ -197,19 +181,39 @@ export default function MemesIndex({ memes, popularKeywords, filters }: Props) {
))} ))}
</div> </div>
{/* Pagination */} {/* Cursor Pagination */}
{memes.last_page > 1 && ( {(memes.next_page_url || memes.prev_page_url) && (
<div className="flex items-center justify-center gap-2"> <div className="flex flex-col items-center gap-4">
{memes.links.map((link, index) => ( <div className="flex items-center justify-center gap-4">
<Button <div>
key={index} {memes.prev_page_url && (
variant={link.active ? 'default' : 'outline'} <Link
size="sm" href={memes.prev_page_url}
onClick={() => link.url && handlePageChange(link.url)} className="text-muted-foreground border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex w-32 items-center justify-center gap-2 rounded-md border px-4 py-2 text-sm font-medium transition-colors"
disabled={!link.url} >
dangerouslySetInnerHTML={{ __html: link.label }} Previous
/> </Link>
))} )}
</div>
<div>
{memes.next_page_url && (
<Link
href={memes.next_page_url}
className="text-muted-foreground border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex w-32 items-center justify-center gap-2 rounded-md border px-4 py-2 text-sm font-medium transition-colors"
>
Next
</Link>
)}
</div>
</div>
{memes.prev_page_url && (
<Link
href={route('memes.index', { ...(filters.search && { search: filters.search }) })}
className="text-muted-foreground hover:text-foreground text-sm transition-colors"
>
Back to first page
</Link>
)}
</div> </div>
)} )}
</div> </div>