Skip to content

Commit b8708bc

Browse files
committed
refactor: extract pagination into reusable SearchPagination component and improve results display
1 parent 3326e5f commit b8708bc

File tree

2 files changed

+86
-37
lines changed

2 files changed

+86
-37
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<script lang="ts">
2+
let {
3+
currentPage,
4+
totalPages,
5+
hasPrevious,
6+
hasNext,
7+
onPageChange,
8+
maxPagesToShow = 10,
9+
} = $props<{
10+
currentPage: number;
11+
totalPages: number;
12+
hasPrevious: boolean;
13+
hasNext: boolean;
14+
onPageChange: (page: number) => void;
15+
maxPagesToShow?: number;
16+
}>();
17+
18+
function handlePageChange(targetPage: number) {
19+
if (
20+
targetPage !== currentPage &&
21+
targetPage >= 1 &&
22+
targetPage <= totalPages
23+
) {
24+
onPageChange?.(targetPage);
25+
}
26+
}
27+
</script>
28+
29+
{#if totalPages > 1}
30+
<div class="flex justify-center mt-8 space-x-2">
31+
<button
32+
class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
33+
disabled={!hasPrevious}
34+
onclick={() => handlePageChange(currentPage - 1)}
35+
>
36+
Previous
37+
</button>
38+
39+
<div class="flex space-x-1">
40+
{#each Array(Math.min(totalPages, maxPagesToShow)) as _, i}
41+
{@const pageNum = i + 1}
42+
<button
43+
class="px-4 py-2 border rounded-md shadow-sm text-sm font-medium {pageNum ===
44+
currentPage
45+
? 'bg-amber-600 text-white border-amber-600'
46+
: 'border-gray-300 text-gray-700 bg-white hover:bg-gray-50'}"
47+
onclick={() => handlePageChange(pageNum)}
48+
>
49+
{pageNum}
50+
</button>
51+
{/each}
52+
</div>
53+
54+
<button
55+
class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
56+
disabled={!hasNext}
57+
onclick={() => handlePageChange(currentPage + 1)}
58+
>
59+
Next
60+
</button>
61+
</div>
62+
{/if}

src/routes/breweries/+page.svelte

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
import BreweriesTable from '$lib/components/BreweriesTable.svelte';
33
import BreweryCard from '$lib/components/BreweryCard.svelte';
44
import BrewerySearchForm from '$lib/components/BrewerySearchForm.svelte';
5+
import SearchPagination from '$lib/components/SearchPagination.svelte';
56
import { goto } from '$app/navigation';
67
import {
78
getBreweries,
89
getLoading,
910
getError,
1011
resetSearch,
1112
initializeStore,
12-
getHasBreweries,
1313
getHasNextPage,
1414
getHasPreviousPage,
1515
getCurrentPage,
16+
getItemsPerPage,
17+
getTotalBreweries,
1618
getTotalPages,
1719
getSearchQuery,
1820
} from '$lib/stores/breweries.svelte';
@@ -76,11 +78,24 @@
7678
{#if getSearchQuery()}
7779
<div class="mb-6">
7880
<p class="text-gray-600">
79-
Found {getBreweries().length} breweries matching "{getSearchQuery()}"
81+
{(getCurrentPage() - 1) * getItemsPerPage() + 1}
82+
- {Math.min(
83+
getCurrentPage() * getItemsPerPage(),
84+
getTotalBreweries()
85+
)}
86+
of {getTotalBreweries()} breweries (page {getCurrentPage()} of {getTotalPages()})
8087
</p>
8188
</div>
8289
{/if}
8390

91+
<SearchPagination
92+
currentPage={getCurrentPage()}
93+
totalPages={getTotalPages()}
94+
hasPrevious={getHasPreviousPage()}
95+
hasNext={getHasNextPage()}
96+
onPageChange={handlePageChange}
97+
/>
98+
8499
<!-- Mobile view: Card layout -->
85100
<div class="grid grid-cols-1 gap-6 mt-6 md:hidden">
86101
{#each getBreweries() as brewery}
@@ -103,41 +118,13 @@
103118
</div>
104119
</div>
105120

106-
<!-- Pagination Controls -->
107-
{#if getTotalPages() > 1}
108-
<div class="flex justify-center mt-8 space-x-2">
109-
<button
110-
class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
111-
disabled={!getHasPreviousPage()}
112-
onclick={() => handlePageChange(getCurrentPage() - 1)}
113-
>
114-
Previous
115-
</button>
116-
117-
<div class="flex space-x-1">
118-
{#each Array(Math.min(getTotalPages(), 10)) as _, i}
119-
{@const pageNum = i + 1}
120-
<button
121-
class="px-4 py-2 border rounded-md shadow-sm text-sm font-medium {pageNum ===
122-
getCurrentPage()
123-
? 'bg-amber-600 text-white border-amber-600'
124-
: 'border-gray-300 text-gray-700 bg-white hover:bg-gray-50'}"
125-
onclick={() => handlePageChange(pageNum)}
126-
>
127-
{pageNum}
128-
</button>
129-
{/each}
130-
</div>
131-
132-
<button
133-
class="px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
134-
disabled={!getHasNextPage()}
135-
onclick={() => handlePageChange(getCurrentPage() + 1)}
136-
>
137-
Next
138-
</button>
139-
</div>
140-
{/if}
121+
<SearchPagination
122+
currentPage={getCurrentPage()}
123+
totalPages={getTotalPages()}
124+
hasPrevious={getHasPreviousPage()}
125+
hasNext={getHasNextPage()}
126+
onPageChange={handlePageChange}
127+
/>
141128
{:else if getSearchQuery()}
142129
<div class="text-center py-12">
143130
<p class="text-gray-500">

0 commit comments

Comments
 (0)