import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:superport/screens/common/theme_shadcn.dart'; import 'package:superport/screens/common/templates/form_layout_template.dart'; import 'package:superport/screens/company/controllers/branch_edit_form_controller.dart'; import 'package:superport/utils/validators.dart'; /// 지점 정보 관리 화면 (등록/수정) /// User/Warehouse Location 화면과 동일한 패턴으로 구현 class BranchFormScreen extends StatefulWidget { final Map arguments; const BranchFormScreen({Key? key, required this.arguments}) : super(key: key); @override State createState() => _BranchFormScreenState(); } class _BranchFormScreenState extends State { late final BranchEditFormController _controller; @override void initState() { super.initState(); // arguments에서 정보 추출 final companyId = widget.arguments['companyId'] as int; final branchId = widget.arguments['branchId'] as int; final parentCompanyName = widget.arguments['parentCompanyName'] as String; _controller = BranchEditFormController( companyId: companyId, branchId: branchId, parentCompanyName: parentCompanyName, ); // 데이터 로드 WidgetsBinding.instance.addPostFrameCallback((_) { _controller.loadBranchData(); }); } @override void dispose() { _controller.dispose(); super.dispose(); } /// 저장 처리 Future _onSave() async { if (_controller.isLoading) return; final success = await _controller.saveBranch(); if (success && mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('지점 정보가 수정되었습니다.'), backgroundColor: Colors.green, ), ); Navigator.pop(context, true); } else if (_controller.error != null && mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(_controller.error!), backgroundColor: Colors.red, ), ); } } /// 취소 처리 (변경사항 확인) void _onCancel() { if (_controller.hasChanges()) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('변경사항 확인'), content: const Text('변경된 내용이 있습니다. 저장하지 않고 나가시겠습니까?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('계속 수정'), ), TextButton( onPressed: () { Navigator.pop(context); // 다이얼로그 닫기 Navigator.pop(context); // 화면 닫기 }, child: const Text('나가기'), ), ], ), ); } else { Navigator.pop(context); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('${_controller.parentCompanyName} 지점 수정'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: _onCancel, ), ), body: ListenableBuilder( listenable: _controller, builder: (context, child) { // 로딩 상태 if (_controller.isLoading && _controller.originalBranch == null) { return const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('지점 정보를 불러오는 중...'), ], ), ); } // 에러 상태 if (_controller.error != null && _controller.originalBranch == null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.error_outline, size: 64, color: Colors.red, ), const SizedBox(height: 16), Text(_controller.error!), const SizedBox(height: 16), ElevatedButton( onPressed: _controller.loadBranchData, child: const Text('다시 시도'), ), ], ), ); } // 폼 화면 return Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _controller.formKey, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 지점명 (필수) FormFieldWrapper( label: "지점명 *", child: TextFormField( controller: _controller.nameController, decoration: const InputDecoration( hintText: '지점명을 입력하세요', border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.trim().isEmpty) { return '지점명을 입력하세요'; } if (value.trim().length < 2) { return '지점명은 2자 이상 입력하세요'; } return null; }, textInputAction: TextInputAction.next, ), ), const SizedBox(height: 16), // 주소 (선택) FormFieldWrapper( label: "주소", child: TextFormField( controller: _controller.addressController, decoration: const InputDecoration( hintText: '지점 주소를 입력하세요', border: OutlineInputBorder(), ), maxLines: 2, textInputAction: TextInputAction.next, ), ), const SizedBox(height: 16), // 담당자명 (선택) FormFieldWrapper( label: "담당자명", child: TextFormField( controller: _controller.managerNameController, decoration: const InputDecoration( hintText: '담당자명을 입력하세요', border: OutlineInputBorder(), ), textInputAction: TextInputAction.next, ), ), const SizedBox(height: 16), // 담당자 연락처 (선택) FormFieldWrapper( label: "담당자 연락처", child: TextFormField( controller: _controller.managerPhoneController, decoration: const InputDecoration( hintText: '010-0000-0000', border: OutlineInputBorder(), ), keyboardType: TextInputType.phone, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'[0-9-]')), ], validator: (value) { if (value != null && value.trim().isNotEmpty) { return validatePhoneNumber(value); } return null; }, textInputAction: TextInputAction.next, ), ), const SizedBox(height: 16), // 비고 (선택) FormFieldWrapper( label: "비고", child: TextFormField( controller: _controller.remarkController, decoration: const InputDecoration( hintText: '추가 정보나 메모를 입력하세요', border: OutlineInputBorder(), ), maxLines: 3, textInputAction: TextInputAction.done, ), ), const SizedBox(height: 32), // 버튼들 Row( children: [ // 리셋 버튼 Expanded( flex: 1, child: OutlinedButton( onPressed: _controller.hasChanges() ? _controller.resetForm : null, child: const Text('초기화'), ), ), const SizedBox(width: 12), // 취소 버튼 Expanded( flex: 1, child: OutlinedButton( onPressed: _onCancel, child: const Text('취소'), ), ), const SizedBox(width: 12), // 저장 버튼 Expanded( flex: 2, child: ElevatedButton( onPressed: _controller.isLoading ? null : _onSave, style: ElevatedButton.styleFrom( backgroundColor: ShadcnTheme.primary, foregroundColor: Colors.white, minimumSize: const Size.fromHeight(48), ), child: _controller.isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : const Text( '수정 완료', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), const SizedBox(height: 16), ], ), ), ), ); }, ), ); } }