Files
sam-manage/resources/views/partials/pagination.blade.php
hskwon 43af1a5779 페이지네이션 기능 개선 및 공통화
- 페이지네이션 로직을 별도 JS 파일로 분리 (public/js/pagination.js)
  * 쿠키 기반 per_page 값 저장 및 유지
  * 페이지네이션 이벤트 핸들러 통합
  * 중복 코드 제거

- 페이지네이션 UI 개선
  * 처음으로/끝으로 이동 버튼 추가
  * selectbox 너비 조정 (90px)
  * 서버사이드 selected 속성으로 옵션 매칭 개선

- 초기 페이지당 항목 수를 10개로 변경
  * TenantController, UserController, DepartmentController, RoleController 기본값 수정

- layouts/app.blade.php
  * pagination.js 로드 추가
  * 기존 인라인 스크립트 제거

변경 파일:
- public/js/pagination.js (신규)
- resources/views/layouts/app.blade.php
- resources/views/partials/pagination.blade.php
- app/Http/Controllers/Api/Admin/{Tenant,User,Department,Role}Controller.php
2025-11-24 21:21:22 +09:00

159 lines
9.3 KiB
PHP

{{--
공통 페이지네이션 컴포넌트 (HTMX 호환)
사용법:
@include('partials.pagination', [
'paginator' => $tenants,
'target' => '#tenant-table',
'includeForm' => '#filterForm'
])
--}}
<div class="bg-white px-4 py-3 border-t border-gray-200 sm:px-6">
<div class="flex items-center justify-between">
<!-- 모바일 네비게이션 -->
<div class="flex-1 flex justify-between sm:hidden">
@if($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-400 bg-gray-100 cursor-not-allowed">
이전
</span>
@else
<button type="button"
onclick="handlePageChange({{ $paginator->currentPage() - 1 }})"
class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
이전
</button>
@endif
@if($paginator->hasMorePages())
<button type="button"
onclick="handlePageChange({{ $paginator->currentPage() + 1 }})"
class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
다음
</button>
@else
<span class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-400 bg-gray-100 cursor-not-allowed">
다음
</span>
@endif
</div>
<!-- 데스크톱 네비게이션 -->
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div class="flex items-center gap-4">
<p class="text-sm text-gray-700">
전체 <span class="font-medium">{{ $paginator->total() }}</span>
<span class="font-medium">{{ $paginator->firstItem() }}</span>
~
<span class="font-medium">{{ $paginator->lastItem() }}</span>
</p>
<!-- 페이지당 항목 선택 -->
<select name="per_page" id="perPageSelect"
style="min-width: 90px;"
class="px-3 py-1 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
onchange="handlePerPageChange(this.value)">
<option value="10" {{ $paginator->perPage() == 10 ? 'selected' : '' }}>10개씩</option>
<option value="20" {{ $paginator->perPage() == 20 ? 'selected' : '' }}>20개씩</option>
<option value="30" {{ $paginator->perPage() == 30 ? 'selected' : '' }}>30개씩</option>
<option value="50" {{ $paginator->perPage() == 50 ? 'selected' : '' }}>50개씩</option>
<option value="100" {{ $paginator->perPage() == 100 ? 'selected' : '' }}>100개씩</option>
<option value="200" {{ $paginator->perPage() == 200 ? 'selected' : '' }}>200개씩</option>
<option value="500" {{ $paginator->perPage() == 500 ? 'selected' : '' }}>500개씩</option>
</select>
</div>
<div>
<nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
<!-- 처음으로 버튼 -->
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-3 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-300 cursor-not-allowed">
처음
</span>
@else
<button type="button"
onclick="handlePageChange(1)"
class="relative inline-flex items-center px-3 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
처음
</button>
@endif
<!-- 이전 버튼 -->
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-300 cursor-not-allowed">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</span>
@else
<button type="button"
onclick="handlePageChange({{ $paginator->currentPage() - 1 }})"
class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</button>
@endif
<!-- 페이지 번호 -->
@php
$currentPage = $paginator->currentPage();
$lastPage = $paginator->lastPage();
$maxPages = 10;
// 시작 페이지 계산
$startPage = max(1, $currentPage - floor($maxPages / 2));
$endPage = min($lastPage, $startPage + $maxPages - 1);
// 끝에서 10개를 채우지 못하면 시작 페이지 조정
if ($endPage - $startPage + 1 < $maxPages) {
$startPage = max(1, $endPage - $maxPages + 1);
}
@endphp
@foreach ($paginator->getUrlRange($startPage, $endPage) as $page => $url)
@if ($page == $paginator->currentPage())
<span class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-blue-50 text-sm font-medium text-blue-600">
{{ $page }}
</span>
@else
<button type="button"
onclick="handlePageChange({{ $page }})"
class="relative inline-flex items-center px-4 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50">
{{ $page }}
</button>
@endif
@endforeach
<!-- 다음 버튼 -->
@if ($paginator->hasMorePages())
<button type="button"
onclick="handlePageChange({{ $paginator->currentPage() + 1 }})"
class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
</svg>
</button>
@else
<span class="relative inline-flex items-center px-2 py-2 border border-gray-300 bg-white text-sm font-medium text-gray-300 cursor-not-allowed">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
</svg>
</span>
@endif
<!-- 끝으로 버튼 -->
@if ($paginator->hasMorePages())
<button type="button"
onclick="handlePageChange({{ $paginator->lastPage() }})"
class="relative inline-flex items-center px-3 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
</button>
@else
<span class="relative inline-flex items-center px-3 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-300 cursor-not-allowed">
</span>
@endif
</nav>
</div>
</div>
</div>
</div>