refactor: UI 화면 통합 및 불필요한 파일 정리
- 모든 *_redesign.dart 파일을 기본 화면 파일로 통합 - 백업용 컨트롤러 파일들 제거 (*_controller.backup.dart) - 사용하지 않는 예제 및 테스트 파일 제거 - Clean Architecture 적용 후 남은 정리 작업 완료 - 테스트 코드 정리 및 구조 개선 준비 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ import 'package:flutter/material.dart';
|
||||
// import 'package:superport/models/address_model.dart'; // 사용되지 않는 import
|
||||
import 'package:superport/models/company_model.dart';
|
||||
// import 'package:superport/screens/common/custom_widgets.dart'; // 사용되지 않는 import
|
||||
import 'package:superport/screens/common/theme_tailwind.dart';
|
||||
import 'package:superport/screens/common/theme_shadcn.dart';
|
||||
import 'package:superport/screens/company/controllers/company_form_controller.dart';
|
||||
// import 'package:superport/screens/company/widgets/branch_card.dart'; // 사용되지 않는 import
|
||||
import 'package:superport/screens/company/widgets/company_form_header.dart';
|
||||
@@ -48,7 +48,7 @@ class CompanyTypeSelector extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('회사 유형', style: AppThemeTailwind.formLabelStyle),
|
||||
Text('회사 유형', style: ShadcnTheme.labelMedium),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
@@ -357,7 +357,7 @@ class _CompanyFormScreenState extends State<CompanyFormScreen> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _saveCompany,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppThemeTailwind.primary,
|
||||
backgroundColor: ShadcnTheme.primary,
|
||||
minimumSize: const Size.fromHeight(48),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
@@ -463,7 +463,7 @@ class _CompanyFormScreenState extends State<CompanyFormScreen> {
|
||||
padding: const EdgeInsets.only(top: 16.0, bottom: 8.0),
|
||||
child: Text(
|
||||
'지점 정보',
|
||||
style: AppThemeTailwind.subheadingStyle,
|
||||
style: ShadcnTheme.headingH6,
|
||||
),
|
||||
),
|
||||
if (_controller.branchControllers.isNotEmpty)
|
||||
@@ -507,7 +507,7 @@ class _CompanyFormScreenState extends State<CompanyFormScreen> {
|
||||
child: ElevatedButton(
|
||||
onPressed: _saveCompany,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppThemeTailwind.primary,
|
||||
backgroundColor: ShadcnTheme.primary,
|
||||
minimumSize: const Size.fromHeight(48),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -17,25 +17,23 @@ import 'package:superport/screens/company/widgets/company_branch_dialog.dart';
|
||||
import 'package:superport/screens/company/controllers/company_list_controller.dart';
|
||||
|
||||
/// shadcn/ui 스타일로 재설계된 회사 관리 화면 (통일된 UI 컴포넌트 사용)
|
||||
class CompanyListRedesign extends StatefulWidget {
|
||||
const CompanyListRedesign({super.key});
|
||||
class CompanyList extends StatefulWidget {
|
||||
const CompanyList({super.key});
|
||||
|
||||
@override
|
||||
State<CompanyListRedesign> createState() => _CompanyListRedesignState();
|
||||
State<CompanyList> createState() => _CompanyListState();
|
||||
}
|
||||
|
||||
class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
class _CompanyListState extends State<CompanyList> {
|
||||
late CompanyListController _controller;
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
Timer? _debounceTimer;
|
||||
int _currentPage = 1;
|
||||
final int _pageSize = 10;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = CompanyListController();
|
||||
_controller.initializeWithPageSize(_pageSize);
|
||||
_controller.initializeWithPageSize(10); // 페이지 크기 설정
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -50,10 +48,7 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
void _onSearchChanged(String value) {
|
||||
_debounceTimer?.cancel();
|
||||
_debounceTimer = Timer(AppConstants.searchDebounce, () {
|
||||
setState(() {
|
||||
_currentPage = 1;
|
||||
});
|
||||
_controller.search(value);
|
||||
_controller.search(value); // Controller가 페이지 리셋 처리
|
||||
});
|
||||
}
|
||||
|
||||
@@ -228,37 +223,15 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
}
|
||||
}
|
||||
|
||||
final int totalCount = displayCompanies.length;
|
||||
|
||||
// 페이지네이션을 위한 데이터 처리
|
||||
final int startIndex = (_currentPage - 1) * _pageSize;
|
||||
final int endIndex = startIndex + _pageSize;
|
||||
// Controller가 이미 페이지크된 데이터를 제공
|
||||
final List<Map<String, dynamic>> pagedCompanies = displayCompanies;
|
||||
final int totalCount = controller.total; // 실제 전체 개수 사용
|
||||
|
||||
// 디버그 로그 추가
|
||||
print('🔍 [VIEW DEBUG] 화면 페이지네이션 상태');
|
||||
print(' • filteredCompanies 수: ${controller.filteredCompanies.length}개');
|
||||
print(' • displayCompanies 수: ${displayCompanies.length}개 (지점 포함)');
|
||||
print(' • 현재 페이지: $_currentPage');
|
||||
print(' • 페이지 크기: $_pageSize');
|
||||
print(' • startIndex: $startIndex, endIndex: $endIndex');
|
||||
|
||||
// startIndex가 displayCompanies.length보다 크거나 같으면 첫 페이지로 리셋
|
||||
if (startIndex >= displayCompanies.length && displayCompanies.isNotEmpty) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
_currentPage = 1;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
final List<Map<String, dynamic>> pagedCompanies = displayCompanies.isEmpty
|
||||
? []
|
||||
: displayCompanies.sublist(
|
||||
startIndex.clamp(0, displayCompanies.length),
|
||||
endIndex.clamp(0, displayCompanies.length),
|
||||
);
|
||||
|
||||
print(' • 화면에 표시될 항목 수: ${pagedCompanies.length}개');
|
||||
print('🔍 [VIEW DEBUG] 페이지네이션 상태');
|
||||
print(' • Controller items: ${controller.companies.length}개');
|
||||
print(' • 전체 개수: ${controller.total}개');
|
||||
print(' • 현재 페이지: ${controller.currentPage}');
|
||||
print(' • 페이지 크기: ${controller.pageSize}');
|
||||
|
||||
// 로딩 상태
|
||||
if (controller.isLoading && controller.companies.isEmpty) {
|
||||
@@ -344,7 +317,7 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
],
|
||||
rows: [
|
||||
...pagedCompanies.asMap().entries.map((entry) {
|
||||
final int index = startIndex + entry.key;
|
||||
final int index = ((controller.currentPage - 1) * controller.pageSize) + entry.key;
|
||||
final companyData = entry.value;
|
||||
final bool isBranch = companyData['isBranch'] as bool;
|
||||
final Company company =
|
||||
@@ -457,15 +430,18 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
],
|
||||
),
|
||||
|
||||
// 페이지네이션 (항상 표시)
|
||||
// 페이지네이션 (Controller 상태 사용)
|
||||
pagination: Pagination(
|
||||
totalCount: totalCount,
|
||||
currentPage: _currentPage,
|
||||
pageSize: _pageSize,
|
||||
totalCount: controller.total,
|
||||
currentPage: controller.currentPage,
|
||||
pageSize: controller.pageSize,
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
_currentPage = page;
|
||||
});
|
||||
// 다음 페이지 로드
|
||||
if (page > controller.currentPage) {
|
||||
controller.loadNextPage();
|
||||
} else if (page == 1) {
|
||||
controller.refresh();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -473,4 +449,4 @@ class _CompanyListRedesignState extends State<CompanyListRedesign> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,8 +96,9 @@ class CompanyFormController {
|
||||
try {
|
||||
List<Company> companies;
|
||||
|
||||
// API만 사용
|
||||
companies = await _companyService.getCompanies();
|
||||
// API만 사용 (PaginatedResponse에서 items 추출)
|
||||
final response = await _companyService.getCompanies();
|
||||
companies = response.items;
|
||||
|
||||
companyNames = companies.map((c) => c.name).toList();
|
||||
filteredCompanyNames = companyNames;
|
||||
@@ -347,9 +348,9 @@ class CompanyFormController {
|
||||
if (_useApi) {
|
||||
try {
|
||||
// 회사명 목록을 조회하여 중복 확인
|
||||
final companies = await _companyService.getCompanies(search: name);
|
||||
final response = await _companyService.getCompanies(search: name);
|
||||
// 정확히 일치하는 회사명이 있는지 확인
|
||||
for (final company in companies) {
|
||||
for (final company in response.items) {
|
||||
if (company.name.toLowerCase() == name.toLowerCase()) {
|
||||
return company;
|
||||
}
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:superport/models/company_model.dart';
|
||||
import 'package:superport/services/company_service.dart';
|
||||
import 'package:superport/core/errors/failures.dart';
|
||||
|
||||
// 회사 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러
|
||||
class CompanyListController extends ChangeNotifier {
|
||||
final CompanyService _companyService = GetIt.instance<CompanyService>();
|
||||
|
||||
List<Company> companies = [];
|
||||
List<Company> filteredCompanies = [];
|
||||
String searchKeyword = '';
|
||||
final Set<int> selectedCompanyIds = {};
|
||||
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
// API만 사용
|
||||
|
||||
// 페이지네이션
|
||||
int _currentPage = 1;
|
||||
int _perPage = 20;
|
||||
bool _hasMore = true;
|
||||
|
||||
// 필터
|
||||
bool? _isActiveFilter;
|
||||
|
||||
// Getters
|
||||
bool get isLoading => _isLoading;
|
||||
String? get error => _error;
|
||||
bool get hasMore => _hasMore;
|
||||
int get currentPage => _currentPage;
|
||||
bool? get isActiveFilter => _isActiveFilter;
|
||||
|
||||
CompanyListController();
|
||||
|
||||
// 초기 데이터 로드
|
||||
Future<void> initialize() async {
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 🚀 회사 목록 초기화 시작');
|
||||
print('║ • 페이지 크기: $_perPage개');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
await loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
// 페이지 크기를 지정하여 초기화
|
||||
Future<void> initializeWithPageSize(int pageSize) async {
|
||||
_perPage = pageSize;
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 🚀 회사 목록 초기화 시작 (커스텀 페이지 크기)');
|
||||
print('║ • 페이지 크기: $_perPage개');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
await loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
// 데이터 로드 및 필터 적용
|
||||
Future<void> loadData({bool isRefresh = false}) async {
|
||||
print('🔍 [DEBUG] loadData 시작 - currentPage: $_currentPage, hasMore: $_hasMore, companies.length: ${companies.length}');
|
||||
print('[CompanyListController] loadData called - isRefresh: $isRefresh');
|
||||
|
||||
if (isRefresh) {
|
||||
_currentPage = 1;
|
||||
_hasMore = true;
|
||||
companies.clear();
|
||||
filteredCompanies.clear();
|
||||
}
|
||||
|
||||
if (_isLoading || (!_hasMore && !isRefresh)) return;
|
||||
|
||||
_isLoading = true;
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
// API 호출 - 지점 정보 포함
|
||||
print('[CompanyListController] Using API to fetch companies with branches');
|
||||
|
||||
// 지점 정보를 포함한 전체 회사 목록 가져오기
|
||||
final apiCompaniesWithBranches = await _companyService.getCompaniesWithBranchesFlat();
|
||||
|
||||
// 상세한 회사 정보 로그 출력
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 📊 회사 목록 로드 완료');
|
||||
print('║ ▶ 총 회사 수: ${apiCompaniesWithBranches.length}개');
|
||||
print('╟──────────────────────────────────────────────────────────');
|
||||
|
||||
// 지점이 있는 회사와 없는 회사 구분
|
||||
int companiesWithBranches = 0;
|
||||
int totalBranches = 0;
|
||||
|
||||
for (final company in apiCompaniesWithBranches) {
|
||||
if (company.branches?.isNotEmpty ?? false) {
|
||||
companiesWithBranches++;
|
||||
totalBranches += company.branches!.length;
|
||||
print('║ • ${company.name}: ${company.branches!.length}개 지점');
|
||||
}
|
||||
}
|
||||
|
||||
final companiesWithoutBranches = apiCompaniesWithBranches.length - companiesWithBranches;
|
||||
|
||||
print('╟──────────────────────────────────────────────────────────');
|
||||
print('║ 📈 통계');
|
||||
print('║ • 지점이 있는 회사: ${companiesWithBranches}개');
|
||||
print('║ • 지점이 없는 회사: ${companiesWithoutBranches}개');
|
||||
print('║ • 총 지점 수: ${totalBranches}개');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
|
||||
// 검색어 필터 적용 (서버에서 필터링이 안 되므로 클라이언트에서 처리)
|
||||
List<Company> filteredApiCompanies = apiCompaniesWithBranches;
|
||||
if (searchKeyword.isNotEmpty) {
|
||||
final keyword = searchKeyword.toLowerCase();
|
||||
filteredApiCompanies = apiCompaniesWithBranches.where((company) {
|
||||
return company.name.toLowerCase().contains(keyword) ||
|
||||
(company.contactName?.toLowerCase().contains(keyword) ?? false) ||
|
||||
(company.contactPhone?.toLowerCase().contains(keyword) ?? false);
|
||||
}).toList();
|
||||
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 🔍 검색 필터 적용');
|
||||
print('║ • 검색어: "$searchKeyword"');
|
||||
print('║ • 필터 전: ${apiCompaniesWithBranches.length}개');
|
||||
print('║ • 필터 후: ${filteredApiCompanies.length}개');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
}
|
||||
|
||||
// 활성 상태 필터 적용 (현재 API에서 지원하지 않으므로 주석 처리)
|
||||
// if (_isActiveFilter != null) {
|
||||
// filteredApiCompanies = filteredApiCompanies.where((c) => c.isActive == _isActiveFilter).toList();
|
||||
// }
|
||||
|
||||
// 전체 데이터를 한 번에 로드 (View에서 페이지네이션 처리)
|
||||
companies = filteredApiCompanies;
|
||||
_hasMore = false; // 전체 데이터를 로드했으므로 더 이상 로드할 필요 없음
|
||||
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 📑 전체 데이터 로드 완료');
|
||||
print('║ • 로드된 회사 수: ${companies.length}개');
|
||||
print('║ • 필터링된 회사 수: ${filteredApiCompanies.length}개');
|
||||
print('║ • View에서 페이지네이션 처리 예정');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
|
||||
// 필터 적용
|
||||
applyFilters();
|
||||
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ ✅ 최종 화면 표시');
|
||||
print('║ • 화면에 표시될 회사 수: ${filteredCompanies.length}개');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
|
||||
selectedCompanyIds.clear();
|
||||
} on Failure catch (e) {
|
||||
print('[CompanyListController] Failure loading companies: ${e.message}');
|
||||
_error = e.message;
|
||||
} catch (e, stackTrace) {
|
||||
print('[CompanyListController] Error loading companies: $e');
|
||||
print('[CompanyListController] Error type: ${e.runtimeType}');
|
||||
print('[CompanyListController] Stack trace: $stackTrace');
|
||||
_error = '회사 목록을 불러오는 중 오류가 발생했습니다: $e';
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// 검색 및 필터 적용
|
||||
void applyFilters() {
|
||||
filteredCompanies = companies.where((company) {
|
||||
// 검색어 필터
|
||||
if (searchKeyword.isNotEmpty) {
|
||||
final keyword = searchKeyword.toLowerCase();
|
||||
final matchesName = company.name.toLowerCase().contains(keyword);
|
||||
final matchesContact = company.contactName?.toLowerCase().contains(keyword) ?? false;
|
||||
final matchesPhone = company.contactPhone?.toLowerCase().contains(keyword) ?? false;
|
||||
|
||||
if (!matchesName && !matchesContact && !matchesPhone) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 활성 상태 필터 (현재 API에서 지원안함)
|
||||
// if (_isActiveFilter != null) {
|
||||
// 추후 API 지원 시 구현
|
||||
// }
|
||||
|
||||
return true;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// 검색어 변경
|
||||
Future<void> updateSearchKeyword(String keyword) async {
|
||||
searchKeyword = keyword;
|
||||
|
||||
if (keyword.isNotEmpty) {
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 🔍 검색어 변경: "$keyword"');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
} else {
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ ❌ 검색어 초기화');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
}
|
||||
|
||||
// API 사용 시 새로 조회
|
||||
await loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
// 활성 상태 필터 변경
|
||||
Future<void> changeActiveFilter(bool? isActive) async {
|
||||
_isActiveFilter = isActive;
|
||||
await loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
// 회사 선택/해제
|
||||
void toggleCompanySelection(int? companyId) {
|
||||
if (companyId == null) return;
|
||||
|
||||
if (selectedCompanyIds.contains(companyId)) {
|
||||
selectedCompanyIds.remove(companyId);
|
||||
} else {
|
||||
selectedCompanyIds.add(companyId);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// 전체 선택/해제
|
||||
void toggleSelectAll() {
|
||||
if (selectedCompanyIds.length == filteredCompanies.length) {
|
||||
selectedCompanyIds.clear();
|
||||
} else {
|
||||
selectedCompanyIds.clear();
|
||||
for (final company in filteredCompanies) {
|
||||
if (company.id != null) {
|
||||
selectedCompanyIds.add(company.id!);
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// 선택된 회사 수 반환
|
||||
int getSelectedCount() {
|
||||
return selectedCompanyIds.length;
|
||||
}
|
||||
|
||||
// 회사 삭제
|
||||
Future<bool> deleteCompany(int companyId) async {
|
||||
try {
|
||||
// API를 통한 삭제
|
||||
await _companyService.deleteCompany(companyId);
|
||||
|
||||
// 로컬 리스트에서도 제거
|
||||
companies.removeWhere((c) => c.id == companyId);
|
||||
filteredCompanies.removeWhere((c) => c.id == companyId);
|
||||
selectedCompanyIds.remove(companyId);
|
||||
notifyListeners();
|
||||
|
||||
return true;
|
||||
} on Failure catch (e) {
|
||||
_error = e.message;
|
||||
notifyListeners();
|
||||
return false;
|
||||
} catch (e) {
|
||||
_error = '회사 삭제 중 오류가 발생했습니다: $e';
|
||||
notifyListeners();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 선택된 회사들 삭제
|
||||
Future<bool> deleteSelectedCompanies() async {
|
||||
final selectedIds = selectedCompanyIds.toList();
|
||||
int successCount = 0;
|
||||
|
||||
for (final companyId in selectedIds) {
|
||||
if (await deleteCompany(companyId)) {
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return successCount == selectedIds.length;
|
||||
}
|
||||
|
||||
// 회사 정보 업데이트 (로컬)
|
||||
void updateCompanyLocally(Company updatedCompany) {
|
||||
final index = companies.indexWhere((c) => c.id == updatedCompany.id);
|
||||
if (index != -1) {
|
||||
companies[index] = updatedCompany;
|
||||
applyFilters();
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
// 회사 추가 (로컬)
|
||||
void addCompanyLocally(Company newCompany) {
|
||||
companies.insert(0, newCompany);
|
||||
applyFilters();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// 더 많은 데이터 로드
|
||||
Future<void> loadMore() async {
|
||||
print('🔍 [DEBUG] loadMore 호출됨 - hasMore: $_hasMore, isLoading: $_isLoading');
|
||||
if (!_hasMore || _isLoading) {
|
||||
print('🔍 [DEBUG] loadMore 조건 미충족으로 종료 (hasMore: $_hasMore, isLoading: $_isLoading)');
|
||||
return;
|
||||
}
|
||||
print('🔍 [DEBUG] loadMore 실행 - 추가 데이터 로드 시작');
|
||||
await loadData();
|
||||
}
|
||||
|
||||
// API만 사용하므로 토글 기능 제거
|
||||
|
||||
// 에러 처리
|
||||
void clearError() {
|
||||
_error = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// 리프레시
|
||||
Future<void> refresh() async {
|
||||
print('╔══════════════════════════════════════════════════════════');
|
||||
print('║ 🔄 회사 목록 새로고침 시작');
|
||||
print('╚══════════════════════════════════════════════════════════');
|
||||
await loadData(isRefresh: true);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,8 @@ class CompanyListController extends BaseListController<Company> {
|
||||
required PaginationParams params,
|
||||
Map<String, dynamic>? additionalFilters,
|
||||
}) async {
|
||||
// API 호출 - 회사 목록 조회
|
||||
final apiCompanies = await ErrorHandler.handleApiCall<List<Company>>(
|
||||
// API 호출 - 회사 목록 조회 (이제 PaginatedResponse 반환)
|
||||
final response = await ErrorHandler.handleApiCall<dynamic>(
|
||||
() => _companyService.getCompanies(
|
||||
page: params.page,
|
||||
perPage: params.perPage,
|
||||
@@ -61,21 +61,17 @@ class CompanyListController extends BaseListController<Company> {
|
||||
},
|
||||
);
|
||||
|
||||
final items = apiCompanies ?? [];
|
||||
|
||||
// 임시로 메타데이터 생성 (추후 API에서 실제 메타데이터 반환 시 수정)
|
||||
// PaginatedResponse를 PagedResult로 변환
|
||||
final meta = PaginationMeta(
|
||||
currentPage: params.page,
|
||||
perPage: params.perPage,
|
||||
total: items.length < params.perPage ?
|
||||
(params.page - 1) * params.perPage + items.length :
|
||||
params.page * params.perPage + 1,
|
||||
totalPages: items.length < params.perPage ? params.page : params.page + 1,
|
||||
hasNext: items.length >= params.perPage,
|
||||
hasPrevious: params.page > 1,
|
||||
currentPage: response.page,
|
||||
perPage: response.size,
|
||||
total: response.totalElements,
|
||||
totalPages: response.totalPages,
|
||||
hasNext: !response.last,
|
||||
hasPrevious: !response.first,
|
||||
);
|
||||
|
||||
return PagedResult(items: items, meta: meta);
|
||||
return PagedResult(items: response.items, meta: meta);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:superport/models/address_model.dart';
|
||||
import 'package:superport/models/company_model.dart';
|
||||
import 'package:superport/screens/common/custom_widgets.dart';
|
||||
import 'package:superport/screens/common/theme_tailwind.dart';
|
||||
import 'package:superport/screens/common/theme_shadcn.dart';
|
||||
import 'package:superport/screens/common/widgets/address_input.dart';
|
||||
import 'package:superport/screens/company/widgets/contact_info_widget.dart';
|
||||
import 'package:superport/utils/validators.dart';
|
||||
@@ -81,7 +81,7 @@ class _BranchCardState extends State<BranchCard> {
|
||||
children: [
|
||||
Text(
|
||||
'지점 #${widget.index + 1}',
|
||||
style: AppThemeTailwind.subheadingStyle,
|
||||
style: ShadcnTheme.headingH6,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete, color: Colors.red),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:superport/models/address_model.dart';
|
||||
import 'package:superport/screens/common/custom_widgets.dart';
|
||||
import 'package:superport/screens/common/theme_tailwind.dart';
|
||||
import 'package:superport/screens/common/theme_shadcn.dart';
|
||||
import 'package:superport/screens/common/widgets/address_input.dart';
|
||||
import 'package:superport/utils/validators.dart';
|
||||
import 'package:superport/screens/company/widgets/company_name_autocomplete.dart';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:superport/screens/common/theme_tailwind.dart';
|
||||
import 'package:superport/screens/common/theme_shadcn.dart';
|
||||
|
||||
/// 주소에 대한 지도 대화상자를 표시합니다.
|
||||
class MapDialog extends StatelessWidget {
|
||||
@@ -68,7 +68,7 @@ class MapDialog extends StatelessWidget {
|
||||
Icon(
|
||||
Icons.map,
|
||||
size: 64,
|
||||
color: AppThemeTailwind.primary,
|
||||
color: ShadcnTheme.primary,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
|
||||
Reference in New Issue
Block a user