import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; import '../../models/participant_model.dart'; import '../../services/event_service.dart'; import '../../widgets/loading_indicator.dart'; class ParticipantFormScreen extends StatefulWidget { final String eventId; final Participant? participant; // null이면 새 참가자 추가, 아니면 참가자 수정 const ParticipantFormScreen({ Key? key, required this.eventId, this.participant, }) : super(key: key); @override State createState() => _ParticipantFormScreenState(); } class _ParticipantFormScreenState extends State { final _formKey = GlobalKey(); bool _isLoading = false; // 폼 필드 컨트롤러 final _nameController = TextEditingController(); final _emailController = TextEditingController(); final _phoneNumberController = TextEditingController(); final _notesController = TextEditingController(); final _paidAmountController = TextEditingController(); // 참가자 데이터 String? _status; bool _isPaid = false; // 참가자 상태 옵션 final List _statusOptions = ['등록됨', '확인됨', '취소됨', '참석함']; @override void initState() { super.initState(); // 수정 모드인 경우 기존 데이터 로드 if (widget.participant != null) { _nameController.text = widget.participant!.name ?? ''; _emailController.text = widget.participant!.email ?? ''; _phoneNumberController.text = widget.participant!.phoneNumber ?? ''; _notesController.text = widget.participant!.notes ?? ''; _paidAmountController.text = widget.participant!.paidAmount?.toString() ?? ''; _status = widget.participant!.status; _isPaid = widget.participant!.isPaid; } else { // 새 참가자 추가 시 기본값 설정 _status = _statusOptions[0]; _isPaid = false; } } @override void dispose() { _nameController.dispose(); _emailController.dispose(); _phoneNumberController.dispose(); _notesController.dispose(); _paidAmountController.dispose(); super.dispose(); } // 참가자 저장 Future _saveParticipant() async { if (!_formKey.currentState!.validate()) { return; } setState(() { _isLoading = true; }); try { final eventService = Provider.of(context, listen: false); // 참가자 데이터 준비 final participantData = { 'eventId': widget.eventId, 'name': _nameController.text.trim(), 'email': _emailController.text.trim().isEmpty ? null : _emailController.text.trim(), 'phoneNumber': _phoneNumberController.text.trim().isEmpty ? null : _phoneNumberController.text.trim(), 'status': _status, 'isPaid': _isPaid, 'paidAmount': _paidAmountController.text.isEmpty ? null : double.parse(_paidAmountController.text), 'notes': _notesController.text.trim().isEmpty ? null : _notesController.text.trim(), }; if (widget.participant == null) { // 새 참가자 추가 await eventService.addParticipant(widget.eventId, participantData); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('참가자가 추가되었습니다')), ); } } else { // 기존 참가자 수정 await eventService.updateParticipant(widget.eventId, widget.participant!.id, participantData); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('참가자 정보가 수정되었습니다')), ); } } if (mounted) { Navigator.of(context).pop(true); // 성공 결과와 함께 이전 화면으로 돌아가기 } } catch (e) { if (mounted) { setState(() { _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('참가자 저장에 실패했습니다: $e')), ); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.participant == null ? '참가자 추가' : '참가자 수정'), actions: [ IconButton( icon: const Icon(Icons.save), onPressed: _saveParticipant, ), ], ), body: _isLoading ? const LoadingIndicator() : SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 기본 정보 섹션 _buildSectionTitle('기본 정보'), // 이름 TextFormField( controller: _nameController, decoration: const InputDecoration( labelText: '이름 *', hintText: '참가자 이름을 입력하세요', ), validator: (value) { if (value == null || value.trim().isEmpty) { return '참가자 이름을 입력해주세요'; } return null; }, ), const SizedBox(height: 16), // 이메일 TextFormField( controller: _emailController, decoration: const InputDecoration( labelText: '이메일', hintText: '참가자 이메일을 입력하세요', ), keyboardType: TextInputType.emailAddress, validator: (value) { if (value != null && value.isNotEmpty) { // 간단한 이메일 형식 검증 if (!value.contains('@') || !value.contains('.')) { return '유효한 이메일 주소를 입력해주세요'; } } return null; }, ), const SizedBox(height: 16), // 전화번호 TextFormField( controller: _phoneNumberController, decoration: const InputDecoration( labelText: '전화번호', hintText: '참가자 전화번호를 입력하세요', ), keyboardType: TextInputType.phone, ), const SizedBox(height: 24), // 상태 섹션 _buildSectionTitle('상태 정보'), // 참가자 상태 DropdownButtonFormField( value: _status, decoration: const InputDecoration( labelText: '참가자 상태', ), items: _statusOptions.map((status) { return DropdownMenuItem( value: status, child: Text(status), ); }).toList(), onChanged: (value) { setState(() { _status = value; }); }, ), const SizedBox(height: 16), // 결제 여부 SwitchListTile( title: const Text('결제 완료'), value: _isPaid, onChanged: (value) { setState(() { _isPaid = value; }); }, ), // 결제 금액 TextFormField( controller: _paidAmountController, decoration: const InputDecoration( labelText: '결제 금액', hintText: '결제 금액을 입력하세요', suffixText: '원', ), keyboardType: TextInputType.number, validator: (value) { if (value != null && value.isNotEmpty) { if (double.tryParse(value) == null) { return '숫자를 입력해주세요'; } } return null; }, ), const SizedBox(height: 24), // 메모 섹션 _buildSectionTitle('추가 정보'), // 메모 TextFormField( controller: _notesController, decoration: const InputDecoration( labelText: '메모', hintText: '참가자에 대한 메모를 입력하세요', ), maxLines: 3, ), const SizedBox(height: 32), // 저장 버튼 SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _saveParticipant, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), ), child: Text( widget.participant == null ? '참가자 추가' : '참가자 정보 수정', style: const TextStyle(fontSize: 16), ), ), ), ], ), ), ), ); } // 섹션 제목 위젯 Widget _buildSectionTitle(String title) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const Divider(), const SizedBox(height: 8), ], ); } }