import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/components/primary_btn.dart'; import 'package:prosappco/src/models/event_model.dart'; import 'package:prosappco/src/presentation/screens/cita.dart'; import 'package:prosappco/src/presentation/widgets/shared/loading_item_list.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:intl/intl.dart'; class CalendarScreen extends StatefulWidget { const CalendarScreen({super.key}); @override State createState() => _CalendarScreenState(); } class _CalendarScreenState extends State { final uid = AuthenticationRepository.instance.getCurrentUserUid(); List? _events; final _titleController = TextEditingController(); final _descriptionController = TextEditingController(); EventoService eventoService = EventoService(); CalendarFormat _calendarFormat = CalendarFormat.month; DateTime today = DateTime.now(); DateTime now = DateTime.now(); TimeOfDay? _selectedTime1; TimeOfDay? _selectedTime2; Future _selectTime1(BuildContext context) async { final TimeOfDay? pickedTime1 = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (pickedTime1 != null) { setState(() { _selectedTime1 = pickedTime1; }); } return pickedTime1; } Future _selectTime2(BuildContext context) async { final TimeOfDay? pickedTime2 = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (pickedTime2 != null) { setState(() { _selectedTime2 = pickedTime2; }); } return pickedTime2; } @override void initState() { super.initState(); today = DateTime.utc(today.year, today.month, today.day); if (_events == null) { Event.getEventsAllByIdStatus(uid ?? "", 'aprobado') .then((value) => setState(() { _events = value; })); } } void _onDaySelected(DateTime day, DateTime focusedDay) { setState(() { today = day; }); } void _onFormatChange(CalendarFormat format) { setState(() { _calendarFormat = format; }); } @override Widget build(BuildContext context) { if (_events == null) { return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } var events = _events!; // DateTime firstDay = today.subtract(Duration(days: 365)); DateTime lastDay = today.add(const Duration(days: 365)); return Scaffold( floatingActionButtonLocation: kIsWeb ? FloatingActionButtonLocation.startFloat : FloatingActionButtonLocation.endFloat, resizeToAvoidBottomInset: false, appBar: PopAppbar( onPressed: () { Navigator.pop(context); }, label: 'Calendario', ), body: Column( children: [ Container( color: const Color.fromARGB(255, 224, 247, 255), child: TableCalendar( locale: 'es_MX', firstDay: DateTime.utc(2010, 10, 16), lastDay: lastDay, focusedDay: today, availableGestures: AvailableGestures.all, onDaySelected: _onDaySelected, selectedDayPredicate: (day) => isSameDay(day, today), calendarFormat: _calendarFormat, onFormatChanged: _onFormatChange, eventLoader: (date) { return events .where((element) { DateTime day = DateTime.parse(element.day); return (date.year == day.year && date.month == day.month && date.day == day.day); }) .map((e) => e.description) .toList(); }, availableCalendarFormats: const { CalendarFormat.month: 'Mes', CalendarFormat.week: 'Semana', CalendarFormat.twoWeeks: '2 Semanas', }, ), ), SizedBox( width: double.infinity, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: Text(DateFormat('dd MMMM yyyy', 'es').format(today), style: const TextStyle( color: Colors.black, fontSize: 16, fontWeight: FontWeight.w600, )), ), ), const Divider( height: 0, ), Expanded(child: SingleChildScrollView(child: _eventList())) ], ), floatingActionButton: FloatingActionButton( onPressed: _showDialog, child: const Icon(Icons.add), ), ); } void _showDialog() { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), content: StatefulBuilder( builder: (BuildContext context, StateSetter setStateDialog) { return SizedBox( height: 800, child: Column( children: [ Padding( padding: const EdgeInsets.symmetric( horizontal: 0, vertical: 15), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ Text( _selectedTime1 == null ? '' : _selectedTime1!.format(context), style: TextStyle( color: Colors.grey[500], fontSize: 12, ), ), _selectedTime2 != null && _selectedTime1 != null ? Text( ' - ', style: TextStyle( color: Colors.grey[500], fontSize: 12, ), ) : const SizedBox(), Text( _selectedTime2 == null ? '' : _selectedTime2!.format(context), style: TextStyle( color: Colors.grey[500], fontSize: 12, ), ), Text( ' | ', style: TextStyle( color: Colors.grey[500], ), ), Text( DateFormat('dd MMMM yyyy', 'es').format(today), style: const TextStyle( fontSize: 13, ), ) ], ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: TextFormField( controller: _titleController, decoration: const InputDecoration(hintText: 'Titulo'), ), ), Padding( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 20), child: TextFormField( controller: _descriptionController, decoration: const InputDecoration(hintText: 'Descripción'), ), ), Padding( padding: const EdgeInsets.only(bottom: 40), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 80, child: TextFormField( textAlign: TextAlign.center, onTap: () async { var value = await _selectTime1(context); setStateDialog(() { _selectedTime1 = value; }); }, readOnly: true, decoration: const InputDecoration( hintText: 'Hora', ), controller: TextEditingController( text: _selectedTime1 == null ? '' : ' ${_selectedTime1!.format(context)}'), style: const TextStyle(fontSize: 15), ), ), const Text(' - '), SizedBox( width: 80, child: TextFormField( textAlign: TextAlign.center, onTap: () async { var value = await _selectTime2(context); setStateDialog(() { _selectedTime2 = value; }); }, readOnly: true, decoration: const InputDecoration( hintText: 'Hora', ), controller: TextEditingController( text: _selectedTime2 == null ? '' : ' ${_selectedTime2!.format(context)}'), style: const TextStyle(fontSize: 15), ), ), ], ), ), PrimaryButtom( onPressed: () async { final DateTime combinedDate1 = DateTime( today.year, today.month, today.day, _selectedTime1!.hour, _selectedTime1!.minute, ); final DateTime combinedDate2 = DateTime( today.year, today.month, today.day, _selectedTime2!.hour, _selectedTime2!.minute, ); await eventoService .createEvent( _titleController.text, _descriptionController.text, DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(today), '$combinedDate1', '$combinedDate2', uid.toString(), 'sitio', '', 0, 0, 'aprobado', 0, false, false, ) .then((value) { Navigator.pop(context); _titleController.text = ''; _descriptionController.text = ''; }); Event.getEventsAllByIdStatus(uid ?? "", 'aprobado') .then( (value) => setState(() { _events = value; }), ); }, label: 'Añadir evento', ), ], ), ); }, ), ); }, ); } Widget _eventList() { return FutureBuilder( future: getByProId(DateFormat("yyyy-MM-dd 00:00:00.000").format(today)), builder: (BuildContext context, AsyncSnapshot> snapshot) { List eventos = []; if (snapshot.connectionState == ConnectionState.waiting) { return const Column( children: [ LoadingItemList(useCircleAvatar: false), LoadingItemList(useCircleAvatar: false), LoadingItemList(useCircleAvatar: false), LoadingItemList(useCircleAvatar: false), LoadingItemList(useCircleAvatar: false), ], ); } try { snapshot.data!.sort((a, b) { String? range1Hour1A = a.range1Hour1; String? range1Hour1B = b.range1Hour1; DateTime dateTimeA = DateTime.parse(range1Hour1A); DateTime dateTimeB = DateTime.parse(range1Hour1B); return dateTimeB.compareTo(dateTimeA); }); eventos.addAll(snapshot.data!); } catch (e) { print("Error al cargar eventos: inflar $e"); } if (eventos.isEmpty) { return const Padding( padding: EdgeInsets.only(top: 30), child: Center( child: Text( 'No tienes citas', style: TextStyle( color: Colors.black, fontSize: 18, // Tamaño de fuente ajustado según tus preferencias fontWeight: FontWeight.w500, // Puedes ajustar el peso de la fuente fontStyle: FontStyle.italic, // Puedes agregar estilo italic // Otros estilos según tus preferencias ), ), ), ); } return Column( children: [ ...eventos.map( (e) => ListTile( onTap: () { Navigator.push( context, CupertinoPageRoute( builder: (BuildContext context) { return CitaScreen(evento: e); }, ), ); }, leading: Text( TimeOfDay.fromDateTime(DateTime.parse(e.range1Hour1)) .format(context)), title: RichText( text: TextSpan( children: [ TextSpan( text: '${e.title}, ', style: const TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16, ), ), TextSpan( text: DateFormat('dd MMM', 'es') .format(DateTime.parse(e.day)), style: const TextStyle( color: Colors.grey, fontSize: 16, ), ), ], ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ e.professionalId == e.userId ? const SizedBox() : RatingBar.builder( initialRating: e.scoresModel?.average ?? 0, minRating: 1, direction: Axis.horizontal, allowHalfRating: true, itemCount: 5, itemSize: 25, maxRating: 5, itemPadding: const EdgeInsets.symmetric(horizontal: 0), itemBuilder: (context, _) => const Icon( Icons.star, color: Color(0xFF2BA4EC), ), onRatingUpdate: (rating) {}, ignoreGestures: true, ), const SizedBox(width: 5), e.professionalId == e.userId ? const SizedBox() : Text( '(${e.scoresModel?.total.toString()}) ${e.scoresModel?.average.toStringAsFixed(1)}'), ], ), Text( '" ${e.description} "', style: const TextStyle(fontStyle: FontStyle.italic), ), ], ), trailing: const Icon(Icons.keyboard_arrow_right), ), ), ], ); }, ); } }