import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:provider/provider.dart'; import '../../models/schedule_model.dart'; import '../../providers/pet_provider.dart'; import '../../services/firestore_service.dart'; import '../../theme/app_colors.dart'; class ScheduleFormSheet extends StatefulWidget { final DateTime selectedDate; const ScheduleFormSheet({super.key, required this.selectedDate}); @override State createState() => _ScheduleFormSheetState(); } class _ScheduleFormSheetState extends State { final TextEditingController _titleController = TextEditingController(); final TextEditingController _noteController = TextEditingController(); String _selectedType = 'general'; // 'general' or 'important' bool _isSubstituting = false; // "저장 중" 상태 표시 @override void dispose() { _titleController.dispose(); _noteController.dispose(); super.dispose(); } Future _saveSchedule() async { final title = _titleController.text.trim(); if (title.isEmpty) return; final petProvider = context.read(); final selectedPet = petProvider.selectedPet; if (selectedPet == null) { ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('반려동물을 먼저 선택해주세요.'))); return; } setState(() { _isSubstituting = true; }); try { final firestoreService = FirestoreService(); final newSchedule = Schedule( id: firestoreService.generateScheduleId(), petId: selectedPet.id, date: widget.selectedDate, type: _selectedType, isCompleted: false, title: title, note: _noteController.text.trim().isEmpty ? null : _noteController.text.trim(), createdAt: DateTime.now(), ); await firestoreService.addSchedule(newSchedule); if (mounted) { Navigator.pop(context, true); // 성공 시 true 반환 } } catch (e) { debugPrint('Error saving schedule: $e'); if (mounted) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('일정 저장 실패: $e'))); } } finally { if (mounted) { setState(() { _isSubstituting = false; }); } } } @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.only( left: 20.w, right: 20.w, top: 20.h, bottom: MediaQuery.of(context).viewInsets.bottom + 20.h, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(24.r)), ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( '일정 추가', style: TextStyle( fontFamily: 'SCDream', fontSize: 18.sp, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), SizedBox(height: 10.h), Divider(color: const Color(0xFFEEEEEE), thickness: 1.h), SizedBox(height: 10.h), SizedBox(height: 20.h), // 제목 입력 TextField( controller: _titleController, decoration: InputDecoration( labelText: '일정 제목', floatingLabelStyle: const TextStyle(color: AppColors.highlight), hintText: '예: 산책하기, 병원 방문', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), borderSide: const BorderSide(color: AppColors.highlight), ), filled: true, fillColor: Colors.grey[50], ), ), SizedBox(height: 16.h), // 중요도 선택 Row( children: [ Expanded( child: _buildTypeButton( '일반', 'general', AppColors.subHighlight, ), ), SizedBox(width: 12.w), Expanded( child: _buildTypeButton('중요', 'important', AppColors.highlight), ), ], ), SizedBox(height: 16.h), // 메모 입력 TextField( controller: _noteController, maxLines: 3, decoration: InputDecoration( labelText: '메모 (선택)', floatingLabelStyle: const TextStyle(color: AppColors.highlight), hintText: '추가적인 내용을 입력하세요', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12.r), borderSide: const BorderSide(color: AppColors.highlight), ), filled: true, fillColor: Colors.grey[50], ), ), SizedBox(height: 24.h), // 저장 버튼 ElevatedButton( onPressed: _isSubstituting ? null : _saveSchedule, style: ElevatedButton.styleFrom( backgroundColor: AppColors.highlight, padding: EdgeInsets.symmetric(vertical: 16.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), elevation: 0, ), child: _isSubstituting ? SizedBox( width: 24.w, height: 24.w, child: const CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) : Text( '저장하기', style: TextStyle( fontFamily: 'SCDream', fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ], ), ); } Widget _buildTypeButton(String label, String value, Color color) { final isSelected = _selectedType == value; return InkWell( onTap: () { setState(() { _selectedType = value; }); }, borderRadius: BorderRadius.circular(12.r), child: Container( padding: EdgeInsets.symmetric(vertical: 12.h), decoration: BoxDecoration( color: isSelected ? color.withOpacity(0.1) : Colors.transparent, border: Border.all( color: isSelected ? color : Colors.grey[300]!, width: isSelected ? 2 : 1, ), borderRadius: BorderRadius.circular(12.r), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 12.w, height: 12.w, decoration: BoxDecoration(color: color, shape: BoxShape.circle), ), SizedBox(width: 8.w), Text( label, style: TextStyle( fontFamily: 'SCDream', fontSize: 14.sp, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, color: isSelected ? color : Colors.grey[600], ), ), ], ), ), ); } }