import 'package:flutter/material.dart'; import 'package:superport/screens/common/theme_shadcn.dart'; import 'package:superport/screens/common/components/shadcn_components.dart'; /// 표준 액션바 위젯 /// /// 모든 리스트 화면에서 일관된 액션 버튼 배치와 상태 표시 제공 class StandardActionBar extends StatelessWidget { final List leftActions; // 왼쪽 액션 버튼들 final List rightActions; // 오른쪽 액션 버튼들 final int? selectedCount; // 선택된 항목 수 final int totalCount; // 전체 항목 수 final VoidCallback? onRefresh; // 새로고침 콜백 final String? statusMessage; // 추가 상태 메시지 const StandardActionBar({ super.key, this.leftActions = const [], this.rightActions = const [], this.selectedCount, required this.totalCount, this.onRefresh, this.statusMessage, }); @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // 왼쪽 액션 버튼들 Flexible( flex: 1, child: Wrap( spacing: ShadcnTheme.spacing2, runSpacing: 4, children: [ ...leftActions, ], ), ), // 오른쪽 상태 표시 및 액션들 - 오버플로우 방지 Flexible( flex: 2, child: Row( mainAxisSize: MainAxisSize.min, children: [ // 추가 상태 메시지 (작은 글자 크기로 통일) - 텍스트 오버플로우 방지 if (statusMessage != null) ...[ Flexible( child: Text( statusMessage!, style: ShadcnTheme.bodySmall, overflow: TextOverflow.ellipsis, maxLines: 1, ), ), const SizedBox(width: ShadcnTheme.spacing2), ], // 선택된 항목 수 표시 if (selectedCount != null && selectedCount! > 0) ...[ Container( padding: const EdgeInsets.symmetric( vertical: 6, horizontal: 12, ), decoration: BoxDecoration( color: ShadcnTheme.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(ShadcnTheme.radiusSm), border: Border.all(color: ShadcnTheme.primary.withValues(alpha: 0.3)), ), child: Text( '$selectedCount개', style: TextStyle( fontWeight: FontWeight.bold, color: ShadcnTheme.primary, fontSize: 12, ), ), ), const SizedBox(width: ShadcnTheme.spacing2), ], // 전체 항목 수 표시 (statusMessage에 "총 X개"가 없을 때만 표시) if (statusMessage == null || !statusMessage!.contains('총')) Container( padding: const EdgeInsets.symmetric( vertical: 4, horizontal: 8, ), decoration: BoxDecoration( color: ShadcnTheme.muted.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(ShadcnTheme.radiusSm), ), child: Text( '총 $totalCount개', style: ShadcnTheme.bodySmall.copyWith(fontSize: 11), ), ), // 새로고침 버튼 if (onRefresh != null) ...[ const SizedBox(width: ShadcnTheme.spacing2), IconButton( icon: const Icon(Icons.refresh), onPressed: onRefresh, tooltip: '새로고침', iconSize: 18, padding: const EdgeInsets.all(4), constraints: const BoxConstraints( minWidth: 32, minHeight: 32, ), ), ], // 오른쪽 액션 버튼들 ...rightActions.map((action) => Padding( padding: const EdgeInsets.only(left: ShadcnTheme.spacing1), child: action, )), ], ), ), ], ); } } /// 표준 액션 버튼 그룹 class StandardActionButtons { /// 추가 버튼 static Widget addButton({ required String text, required VoidCallback onPressed, IconData icon = Icons.add, }) { return ShadcnButton( text: text, onPressed: onPressed, variant: ShadcnButtonVariant.primary, textColor: ShadcnTheme.primaryForeground, icon: Icon(icon, size: 16), ); } /// 삭제 버튼 static Widget deleteButton({ required VoidCallback? onPressed, bool enabled = true, String text = '삭제', }) { return ShadcnButton( text: text, onPressed: enabled ? onPressed : null, variant: enabled ? ShadcnButtonVariant.destructive : ShadcnButtonVariant.secondary, icon: const Icon(Icons.delete, size: 16), ); } /// 엑셀 내보내기 버튼 static Widget exportButton({ required VoidCallback onPressed, String text = '엑셀 내보내기', }) { return ShadcnButton( text: text, onPressed: onPressed, variant: ShadcnButtonVariant.secondary, icon: const Icon(Icons.download, size: 16), ); } /// 엑셀 가져오기 버튼 static Widget importButton({ required VoidCallback onPressed, String text = '엑셀 가져오기', }) { return ShadcnButton( text: text, onPressed: onPressed, variant: ShadcnButtonVariant.secondary, icon: const Icon(Icons.upload, size: 16), ); } /// 새로고침 버튼 static Widget refreshButton({ required VoidCallback onPressed, String text = '새로고침', }) { return ShadcnButton( text: text, onPressed: onPressed, variant: ShadcnButtonVariant.secondary, icon: const Icon(Icons.refresh, size: 16), ); } /// 필터 초기화 버튼 static Widget clearFiltersButton({ required VoidCallback onPressed, String text = '필터 초기화', }) { return ShadcnButton( text: text, onPressed: onPressed, variant: ShadcnButtonVariant.ghost, icon: const Icon(Icons.clear_all, size: 16), ); } } /// 표준 필터 드롭다운 class StandardFilterDropdown extends StatelessWidget { final T value; final List> items; final ValueChanged onChanged; final String? hint; const StandardFilterDropdown({ super.key, required this.value, required this.items, required this.onChanged, this.hint, }); @override Widget build(BuildContext context) { return Container( height: 40, padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( color: ShadcnTheme.card, border: Border.all(color: ShadcnTheme.border), borderRadius: BorderRadius.circular(ShadcnTheme.radiusMd), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: value, items: items, onChanged: onChanged, hint: hint != null ? Text(hint!) : null, style: ShadcnTheme.bodySmall, icon: const Icon(Icons.arrow_drop_down, size: 20), ), ), ); } }