import 'package:flutter/material.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/screens/common/theme_tailwind.dart'; import 'package:superport/screens/common/main_layout.dart'; import 'package:superport/screens/common/custom_widgets.dart'; import 'package:superport/services/mock_data_service.dart'; import 'package:superport/utils/constants.dart'; import 'package:superport/screens/common/widgets/pagination.dart'; import 'package:superport/screens/company/widgets/company_branch_dialog.dart'; class CompanyListScreen extends StatefulWidget { const CompanyListScreen({super.key}); @override State createState() => _CompanyListScreenState(); } class _CompanyListScreenState extends State { final MockDataService _dataService = MockDataService(); List _companies = []; // 페이지네이션 상태 추가 int _currentPage = 1; // 현재 페이지 (1부터 시작) final int _pageSize = 10; // 페이지당 개수 @override void initState() { super.initState(); _loadData(); } void _loadData() { setState(() { _companies = _dataService.getAllCompanies(); // 데이터가 변경되면 첫 페이지로 이동 _currentPage = 1; }); } void _navigateToAddScreen() async { final result = await Navigator.pushNamed(context, '/company/add'); if (result == true) { _loadData(); } } void _navigateToEditScreen(int id) async { final result = await Navigator.pushNamed( context, '/company/edit', arguments: id, ); if (result == true) { _loadData(); } } void _deleteCompany(int id) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('삭제 확인'), content: const Text('이 회사 정보를 삭제하시겠습니까?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('취소'), ), TextButton( onPressed: () { _dataService.deleteCompany(id); Navigator.pop(context); _loadData(); }, child: const Text('삭제'), ), ], ), ); } // 회사 유형에 따라 칩 위젯 생성 (복수) Widget _buildCompanyTypeChips(List types) { return Row( children: types.map((type) { final Color textColor = type == CompanyType.customer ? Colors.blue.shade800 : Colors.green.shade800; final String label = companyTypeToString(type); return Container( margin: const EdgeInsets.only(right: 4), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: textColor.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Text( label, style: TextStyle( color: textColor, fontWeight: FontWeight.bold, fontSize: 14, ), ), ); }).toList(), ); } // 본사/지점 구분 표시 위젯 Widget _buildCompanyTypeLabel(bool isBranch, {String? mainCompanyName}) { if (isBranch) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.account_tree, size: 16, color: Colors.blue.shade600), const SizedBox(width: 4), const Text('지점'), ], ); } else { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.business, size: 16, color: Colors.grey.shade700), const SizedBox(width: 4), const Text('본사'), ], ); } } // 회사 이름 표시 위젯 (지점인 경우 "본사명 > 지점명" 형식) Widget _buildCompanyNameText( Company company, bool isBranch, { String? mainCompanyName, }) { if (isBranch && mainCompanyName != null) { return Text.rich( TextSpan( children: [ TextSpan( text: isBranch ? '▶ ' : '', style: TextStyle(color: Colors.grey.shade600, fontSize: 14), ), TextSpan( text: isBranch ? '$mainCompanyName > ' : '', style: TextStyle( color: Colors.grey.shade700, fontWeight: FontWeight.normal, ), ), TextSpan( text: company.name, style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), ); } else { return Text( company.name, style: const TextStyle(fontWeight: FontWeight.bold), ); } } // 지점(본사+지점)만 보여주는 팝업 오픈 함수 void _showBranchDialog(Company mainCompany) { showDialog( context: context, builder: (context) => CompanyBranchDialog(mainCompany: mainCompany), ); } @override Widget build(BuildContext context) { // 대시보드 폭에 맞게 조정 final screenWidth = MediaQuery.of(context).size.width; final maxContentWidth = screenWidth > 1200 ? 1200.0 : screenWidth - 32; // 본사와 지점 구분하기 위한 데이터 준비 final List> displayCompanies = []; for (final company in _companies) { displayCompanies.add({ 'company': company, 'isBranch': false, 'mainCompanyName': null, }); if (company.branches != null) { for (final branch in company.branches!) { displayCompanies.add({ 'branch': branch, // 지점 객체 자체 저장 'companyId': company.id, // 본사 id 저장 'isBranch': true, 'mainCompanyName': company.name, }); } } } // 페이지네이션 데이터 슬라이싱 final int totalCount = displayCompanies.length; final int startIndex = (_currentPage - 1) * _pageSize; final int endIndex = (startIndex + _pageSize) > totalCount ? totalCount : (startIndex + _pageSize); final List> pagedCompanies = displayCompanies.sublist( startIndex, endIndex, ); return MainLayout( title: '회사 관리', currentRoute: Routes.company, actions: [ IconButton( icon: const Icon(Icons.refresh), onPressed: _loadData, color: Colors.grey, ), ], child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ PageTitle( title: '회사 목록', width: maxContentWidth - 32, rightWidget: ElevatedButton.icon( onPressed: _navigateToAddScreen, icon: const Icon(Icons.add), label: const Text('추가'), style: AppThemeTailwind.primaryButtonStyle, ), ), Expanded( child: DataTableCard( width: maxContentWidth - 32, child: pagedCompanies.isEmpty ? const Center(child: Text('등록된 회사 정보가 없습니다.')) : SingleChildScrollView( scrollDirection: Axis.horizontal, child: Container( width: maxContentWidth - 32, constraints: BoxConstraints( minWidth: maxContentWidth - 64, ), child: SingleChildScrollView( scrollDirection: Axis.vertical, child: DataTable( columns: const [ DataColumn(label: Text('번호')), DataColumn(label: Text('구분')), DataColumn(label: Text('회사명')), DataColumn(label: Text('유형')), DataColumn(label: Text('주소')), DataColumn(label: Text('지점 수 (본사만 표시)')), DataColumn(label: Text('관리')), ], rows: pagedCompanies.asMap().entries.map((entry) { final index = entry.key; final data = entry.value; final bool isBranch = data['isBranch'] as bool; final String? mainCompanyName = data['mainCompanyName'] as String?; if (isBranch) { final Branch branch = data['branch'] as Branch; final int companyId = data['companyId'] as int; return DataRow( cells: [ DataCell( Text('${startIndex + index + 1}'), ), DataCell( _buildCompanyTypeLabel( true, mainCompanyName: mainCompanyName, ), ), DataCell( _buildCompanyNameText( Company( id: branch.id, name: branch.name, address: branch.address, contactName: branch.contactName, contactPosition: branch.contactPosition, contactPhone: branch.contactPhone, contactEmail: branch.contactEmail, companyTypes: [], remark: branch.remark, ), true, mainCompanyName: mainCompanyName, ), ), DataCell( _buildCompanyTypeChips([]), ), DataCell( Text(branch.address.toString()), ), DataCell(const Text('')), DataCell( Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.edit, color: AppThemeTailwind .primary, ), onPressed: () { Navigator.pushNamed( context, '/company/edit', arguments: { 'companyId': companyId, 'isBranch': true, 'mainCompanyName': mainCompanyName, 'branchId': branch.id, }, ).then((result) { if (result == true) _loadData(); }); }, ), IconButton( icon: const Icon( Icons.delete, color: AppThemeTailwind .danger, ), onPressed: () { // 지점 삭제 로직 필요시 구현 }, ), ], ), ), ], ); } else { final Company company = data['company'] as Company; return DataRow( cells: [ DataCell( Text('${startIndex + index + 1}'), ), DataCell( _buildCompanyTypeLabel(false), ), DataCell( _buildCompanyNameText( company, false, ), ), DataCell( _buildCompanyTypeChips( company.companyTypes, ), ), DataCell( Text(company.address.toString()), ), DataCell( GestureDetector( onTap: () { if ((company .branches ?.isNotEmpty ?? false)) { _showBranchDialog(company); } }, child: MouseRegion( cursor: SystemMouseCursors.click, child: Text( '${(company.branches?.length ?? 0)}', style: TextStyle( color: (company .branches ?.isNotEmpty ?? false) ? Colors.blue : Colors.black, decoration: (company .branches ?.isNotEmpty ?? false) ? TextDecoration .underline : TextDecoration .none, ), ), ), ), ), DataCell( Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon( Icons.edit, color: AppThemeTailwind .primary, ), onPressed: () { Navigator.pushNamed( context, '/company/edit', arguments: { 'companyId': company.id, 'isBranch': false, }, ).then((result) { if (result == true) _loadData(); }); }, ), IconButton( icon: const Icon( Icons.delete, color: AppThemeTailwind .danger, ), onPressed: () { _deleteCompany( company.id!, ); }, ), ], ), ), ], ); } }).toList(), ), ), ), ), ), ), // 페이지네이션 위젯 추가 if (totalCount > _pageSize) Padding( padding: const EdgeInsets.symmetric(vertical: 12), child: Pagination( totalCount: totalCount, currentPage: _currentPage, pageSize: _pageSize, onPageChanged: (page) { setState(() { _currentPage = page; }); }, ), ), ], ), ), ); } }