import 'package:flutter/material.dart'; import 'package:superport/screens/common/theme_shadcn.dart'; /// 페이지네이션 위젯 (<< < 1 2 3 ... 10 > >>) /// - totalCount: 전체 아이템 수 /// - currentPage: 현재 페이지 (1부터 시작) /// - pageSize: 페이지당 아이템 수 /// - onPageChanged: 페이지 변경 콜백 class Pagination extends StatelessWidget { final int totalCount; final int currentPage; final int pageSize; final ValueChanged onPageChanged; const Pagination({ super.key, required this.totalCount, required this.currentPage, required this.pageSize, required this.onPageChanged, }); @override Widget build(BuildContext context) { // 방어적 계산: pageSize, currentPage, totalPages 모두 안전 범위로 보정 final int safePageSize = pageSize <= 0 ? 1 : pageSize; final int computedTotalPages = (totalCount / safePageSize).ceil(); final int totalPages = computedTotalPages < 1 ? 1 : computedTotalPages; final int current = currentPage < 1 ? 1 : (currentPage > totalPages ? totalPages : currentPage); // 페이지네이션 버튼 최대 10개 const int maxButtons = 10; // 시작/끝 페이지 계산 int startPage = ((current - 1) ~/ maxButtons) * maxButtons + 1; int endPage = startPage + maxButtons - 1; if (endPage > totalPages) endPage = totalPages; List pageButtons = []; for (int i = startPage; i <= endPage; i++) { pageButtons.add( Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: InkWell( onTap: i == current ? null : () => onPageChanged(i), borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd), child: Container( height: 32, constraints: const BoxConstraints(minWidth: 32), padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( color: i == current ? ShadcnTheme.primary : Colors.transparent, borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd), border: Border.all( color: i == currentPage ? ShadcnTheme.primary : ShadcnTheme.border, ), ), alignment: Alignment.center, child: Text( '$i', style: ShadcnTheme.labelMedium.copyWith( color: i == current ? ShadcnTheme.primaryForeground : ShadcnTheme.foreground, ), ), ), ), ), ); } return Container( padding: const EdgeInsets.symmetric(vertical: ShadcnTheme.spacing4), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // 가장 처음 페이지로 이동 _buildNavigationButton( icon: Icons.first_page, tooltip: '처음', onPressed: current > 1 ? () => onPageChanged(1) : null, ), const SizedBox(width: 4), // 이전 페이지로 이동 _buildNavigationButton( icon: Icons.chevron_left, tooltip: '이전', onPressed: current > 1 ? () => onPageChanged(current - 1) : null, ), const SizedBox(width: 8), // 페이지 번호 버튼들 ...pageButtons, const SizedBox(width: 8), // 다음 페이지로 이동 _buildNavigationButton( icon: Icons.chevron_right, tooltip: '다음', onPressed: current < totalPages ? () => onPageChanged(current + 1) : null, ), const SizedBox(width: 4), // 마짉 페이지로 이동 _buildNavigationButton( icon: Icons.last_page, tooltip: '마짉', onPressed: current < totalPages ? () => onPageChanged(totalPages) : null, ), ], ), ); } Widget _buildNavigationButton({ required IconData icon, required String tooltip, VoidCallback? onPressed, }) { final isDisabled = onPressed == null; return Tooltip( message: tooltip, child: InkWell( onTap: onPressed, borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd), child: Container( height: 32, width: 32, decoration: BoxDecoration( borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd), border: Border.all( color: isDisabled ? ShadcnTheme.muted : ShadcnTheme.border, ), ), child: Icon( icon, size: 18, color: isDisabled ? ShadcnTheme.mutedForeground : ShadcnTheme.foreground, ), ), ), ); } }