import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:superport/models/company_model.dart'; import 'package:superport/models/address_model.dart'; import 'package:superport/screens/common/templates/form_layout_template.dart'; import 'package:superport/screens/company/controllers/company_form_controller.dart'; import 'package:superport/utils/validators.dart'; import 'package:superport/utils/formatters/korean_phone_formatter.dart'; /// 회사 등록/수정 화면 /// User/Warehouse Location 화면과 동일한 FormFieldWrapper 패턴 사용 class CompanyFormScreen extends StatefulWidget { final Map? args; const CompanyFormScreen({super.key, this.args}); @override State createState() => _CompanyFormScreenState(); } class _CompanyFormScreenState extends State { late CompanyFormController _controller; final TextEditingController _addressController = TextEditingController(); final TextEditingController _phoneNumberController = TextEditingController(); int? companyId; bool isBranch = false; @override void initState() { super.initState(); // arguments 처리 final args = widget.args; if (args != null) { companyId = args['companyId']; isBranch = args['isBranch'] ?? false; } _controller = CompanyFormController( companyId: companyId, useApi: true, ); // 수정 모드일 때 데이터 로드 if (companyId != null && !isBranch) { WidgetsBinding.instance.addPostFrameCallback((_) { _controller.loadCompanyData().then((_) { if (mounted) { // 주소 필드 초기화 _addressController.text = _controller.companyAddress.toString(); // 전화번호 분리 초기화 final fullPhone = _controller.contactPhoneController.text; if (fullPhone.isNotEmpty) { _phoneNumberController.text = fullPhone; // 통합 필드로 그대로 사용 } setState(() {}); } }); }); } } @override void dispose() { _addressController.dispose(); _phoneNumberController.dispose(); _controller.dispose(); super.dispose(); } /// 회사 저장 Future _saveCompany() async { if (!_controller.formKey.currentState!.validate()) { return; } // 주소 업데이트 _controller.updateCompanyAddress( Address.fromFullAddress(_addressController.text) ); // 전화번호는 이미 포맷팅되어 있으므로 그대로 사용 _controller.contactPhoneController.text = _phoneNumberController.text; // 로딩 표시 showShadDialog( context: context, barrierDismissible: false, builder: (context) => ShadDialog( child: Container( padding: const EdgeInsets.all(20), child: const Row( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(width: 20), Text('저장 중...'), ], ), ), ), ); try { final success = await _controller.saveCompany(); if (mounted) { Navigator.pop(context); // 로딩 다이얼로그 닫기 if (success) { ShadToaster.of(context).show( ShadToast( title: const Text('성공'), description: Text(companyId != null ? '회사 정보가 수정되었습니다.' : '회사가 등록되었습니다.'), ), ); Navigator.pop(context, true); } else { ShadToaster.of(context).show( ShadToast.destructive( title: const Text('오류'), description: const Text('회사 저장에 실패했습니다.'), ), ); } } } catch (e) { if (mounted) { Navigator.pop(context); // 로딩 다이얼로그 닫기 ShadToaster.of(context).show( ShadToast.destructive( title: const Text('오류'), description: Text('오류가 발생했습니다: $e'), ), ); } } } @override Widget build(BuildContext context) { final isEditMode = companyId != null; final title = isEditMode ? '회사 정보 수정' : '회사 등록'; return Scaffold( appBar: AppBar(title: Text(title)), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _controller.formKey, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 회사 유형 선택 FormFieldWrapper( label: "회사 유형", child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ ShadCheckbox( value: _controller.selectedCompanyTypes.contains(CompanyType.customer), onChanged: (checked) { setState(() { _controller.toggleCompanyType(CompanyType.customer, checked); }); }, ), const SizedBox(width: 8), const Text('고객사'), ], ), const SizedBox(height: 8), Row( children: [ ShadCheckbox( value: _controller.selectedCompanyTypes.contains(CompanyType.partner), onChanged: (checked) { setState(() { _controller.toggleCompanyType(CompanyType.partner, checked); }); }, ), const SizedBox(width: 8), const Text('파트너사'), ], ), ], ), ), const SizedBox(height: 16), // 부모 회사 선택 (선택사항) FormFieldWrapper( label: "부모 회사", child: ShadSelect( placeholder: const Text('부모 회사를 선택하세요 (선택사항)'), selectedOptionBuilder: (context, value) { if (value == null) { return const Text('없음 (본사)'); } final company = _controller.availableParentCompanies.firstWhere( (c) => c.id == value, orElse: () => Company(id: 0, name: '알 수 없음'), ); return Text(company.name); }, options: [ const ShadOption( value: null, child: Text('없음 (본사)'), ), ..._controller.availableParentCompanies.map((company) { return ShadOption( value: company.id, child: Text(company.name), ); }), ], onChanged: (value) { setState(() { _controller.selectedParentCompanyId = value; }); }, ), ), const SizedBox(height: 16), // 회사명 (필수) FormFieldWrapper( label: "회사명 *", child: ShadInputFormField( controller: _controller.nameController, placeholder: const Text('회사명을 입력하세요'), validator: (value) { if (value.trim().isEmpty) { return '회사명을 입력하세요'; } if (value.trim().length < 2) { return '회사명은 2자 이상 입력하세요'; } return null; }, ), ), const SizedBox(height: 16), // 주소 (선택) FormFieldWrapper( label: "주소", child: ShadInputFormField( controller: _addressController, placeholder: const Text('회사 주소를 입력하세요'), maxLines: 2, ), ), const SizedBox(height: 16), // 담당자명 (필수) FormFieldWrapper( label: "담당자명 *", child: ShadInputFormField( controller: _controller.contactNameController, placeholder: const Text('담당자명을 입력하세요'), validator: (value) { if (value.trim().isEmpty) { return '담당자명을 입력하세요'; } return null; }, ), ), const SizedBox(height: 16), // 담당자 직급 (선택) FormFieldWrapper( label: "담당자 직급", child: ShadInputFormField( controller: _controller.contactPositionController, placeholder: const Text('담당자 직급을 입력하세요'), ), ), const SizedBox(height: 16), // 담당자 연락처 (필수) - 사용자 폼과 동일한 패턴 FormFieldWrapper( label: "담당자 연락처 *", child: ShadInputFormField( controller: _phoneNumberController, placeholder: const Text('010-1234-5678'), keyboardType: TextInputType.phone, inputFormatters: [ KoreanPhoneFormatter(), // 한국식 전화번호 자동 포맷팅 ], validator: PhoneValidator.validate, // 전화번호 유효성 검증 ), ), const SizedBox(height: 16), // 담당자 이메일 (필수) FormFieldWrapper( label: "담당자 이메일 *", child: ShadInputFormField( controller: _controller.contactEmailController, placeholder: const Text('example@company.com'), keyboardType: TextInputType.emailAddress, validator: (value) { if (value.trim().isEmpty) { return '담당자 이메일을 입력하세요'; } return validateEmail(value); }, ), ), const SizedBox(height: 16), // 비고 (선택) FormFieldWrapper( label: "비고", child: ShadInputFormField( controller: _controller.remarkController, placeholder: const Text('추가 정보나 메모를 입력하세요'), maxLines: 3, ), ), const SizedBox(height: 32), // 저장 버튼 ShadButton( onPressed: _saveCompany, size: ShadButtonSize.lg, width: double.infinity, child: Text( isEditMode ? '수정 완료' : '등록 완료', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), const SizedBox(height: 16), ], ), ), ), ), ); } }