From a678167bc5e53c086108927d2bd9050c6fd5fe5a Mon Sep 17 00:00:00 2001 From: Felipe Date: Mon, 27 May 2024 10:47:41 -0500 Subject: [PATCH] botones etc --- .../service/professional_service_screen.dart | 117 +-- lib/screens/service/service_screen.dart | 145 ++-- lib/screens/service/user_service_screen.dart | 703 ++++++++++-------- lib/screens/user/user_service_screen.dart | 405 +++++++--- 4 files changed, 840 insertions(+), 530 deletions(-) diff --git a/lib/screens/service/professional_service_screen.dart b/lib/screens/service/professional_service_screen.dart index cbe6443..8630204 100644 --- a/lib/screens/service/professional_service_screen.dart +++ b/lib/screens/service/professional_service_screen.dart @@ -329,7 +329,8 @@ class _ProfessionalServiceScreenState extends State { service.range1Hour2.minute, ); - if (service.status == ServiceStatus.acepted || service.status == ServiceStatus.active) { + if (service.status == ServiceStatus.acepted || + service.status == ServiceStatus.active) { if (now.isAfter(serviceDateTime)) { return const SizedBox(); } else { @@ -754,35 +755,6 @@ class _ProfessionalServiceScreenState extends State { service.range1Hour2.minute, ); - if (service.status == ServiceStatus.pending) { - return Column( - children: [ - GeneralSecondaryButton( - label: 'Rechazar servicio', - color: Theme.of(context).colorScheme.error, - onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add(UpdateServiceStatus( - widget.serviceId, ServiceStatus.denied)); - } - }, - ), - const SizedBox(height: 10), - GeneralSecondaryButton( - label: 'Aceptar servicio', - onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add(UpdateServiceStatus( - widget.serviceId, ServiceStatus.acepted)); - } - }, - ), - ], - ); - } - if (now.isAfter(serviceDateTime)) { return GeneralSecondaryButton( label: 'Volver', @@ -791,30 +763,73 @@ class _ProfessionalServiceScreenState extends State { }, ); } else { - if (service.status == ServiceStatus.acepted) { - return GeneralSecondaryButton( - label: 'Iniciar servicio', - onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add( - UpdateServiceStatus(widget.serviceId, ServiceStatus.active)); - } - }, + if (service.status == ServiceStatus.pending) { + return Column( + children: [ + GeneralSecondaryButton( + label: 'Rechazar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.denied)); + } + }, + ), + const SizedBox(height: 10), + GeneralSecondaryButton( + label: 'Aceptar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.acepted)); + } + }, + ), + ], ); } - } - if (service.status == ServiceStatus.active) { - return GeneralSecondaryButton( - label: 'Terminar servicio', - onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add(UpdateServiceStatus( - widget.serviceId, ServiceStatus.completed)); - } - }); + if (service.status == ServiceStatus.acepted) { + if (serviceDateTime.difference(now).inHours > 1) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } + }, + ); + } else { + return GeneralSecondaryButton( + label: 'Iniciar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.active)); + } + }, + ); + } + } + + if (service.status == ServiceStatus.active) { + return GeneralSecondaryButton( + label: 'Terminar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.completed)); + } + }); + } } return GeneralSecondaryButton( diff --git a/lib/screens/service/service_screen.dart b/lib/screens/service/service_screen.dart index 3378961..05e1d5f 100644 --- a/lib/screens/service/service_screen.dart +++ b/lib/screens/service/service_screen.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -6,6 +8,7 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/components/general_secondary_button.dart'; import 'package:prosappco/local_notifications/local_notifications.dart'; import 'package:service_repository/service_repository.dart'; import 'package:setting_repository/setting_repository.dart'; @@ -22,12 +25,20 @@ class ServiceScreen extends StatefulWidget { class _ServiceScreenState extends State { final settingRepository = Injector.appInstance.get(); SettingEntity? settings; + Timer? _timer; @override void initState() { super.initState(); _loadSettings(); + _startTimer(); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); } void _loadSettings() { @@ -38,6 +49,12 @@ class _ServiceScreenState extends State { ); } + void _startTimer() { + _timer = Timer.periodic(const Duration(minutes: 5), (timer) { + setState(() {}); + }); + } + @override Widget build(BuildContext context) { return BlocProvider( @@ -373,19 +390,36 @@ class _ServiceScreenState extends State { ); } - ElevatedButton customButton( + Widget customButton( ServiceEntity service, BuildContext context, MyUser userInfo) { - if (service.status == ServiceStatus.pending) { - return ElevatedButton( + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, + ); + + if (now.isAfter(serviceDateTime)) { + return GeneralSecondaryButton( + label: 'Volver', onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add( - UpdateServiceStatus( - widget.serviceId, - ServiceStatus.cancelled, - ), - ); + Navigator.pop(context); + }, + ); + } else { + if (service.status == ServiceStatus.pending) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } if (userInfo.token != null) { LocalNotifications.sendPushNotification( @@ -394,57 +428,52 @@ class _ServiceScreenState extends State { 'Servicio cancelado por ${userInfo.name}', ); } - } - }, - style: FilledButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.error, - padding: const EdgeInsets.symmetric(vertical: 15), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Container( - alignment: Alignment.center, - child: const Text( - 'Cancelar servicio', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), - ), - ), - ); + }, + ); + } + + if (service.status == ServiceStatus.acepted) { + if (serviceDateTime.difference(now).inDays > 1) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } + + if (userInfo.token != null) { + LocalNotifications.sendPushNotification( + userInfo.token!, + 'Servicio cancelado', + 'Servicio cancelado por ${userInfo.name}', + ); + } + }, + ); + } + } + + if (service.status == ServiceStatus.active) { + return GeneralSecondaryButton( + label: 'Terminar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.completed)); + } + }); + } } - return ElevatedButton( + return GeneralSecondaryButton( + label: 'Volver', onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add( - UpdateServiceStatus( - widget.serviceId, - ServiceStatus.cancelled, - ), - ); - } + Navigator.pop(context); }, - style: FilledButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, - padding: const EdgeInsets.symmetric(vertical: 15), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Container( - alignment: Alignment.center, - child: const Text( - 'Volver', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), - ), - ), ); } diff --git a/lib/screens/service/user_service_screen.dart b/lib/screens/service/user_service_screen.dart index 5e4bdad..3ca5a76 100644 --- a/lib/screens/service/user_service_screen.dart +++ b/lib/screens/service/user_service_screen.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:community_material_icon/community_material_icon.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; @@ -7,7 +8,6 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; -import 'package:prosappco/components/drawer_reputation.dart'; import 'package:prosappco/components/general_reputation.dart'; import 'package:prosappco/local_notifications/local_notifications.dart'; import 'package:prosappco/screens/chat/chat_screen.dart'; @@ -30,12 +30,20 @@ class UserServiceScreen extends StatefulWidget { class _UserServiceScreenState extends State { final settingRepository = Injector.appInstance.get(); SettingEntity? settings; + Timer? _timer; @override void initState() { super.initState(); _loadSettings(); + _startTimer(); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); } void _loadSettings() { @@ -46,6 +54,12 @@ class _UserServiceScreenState extends State { ); } + void _startTimer() { + _timer = Timer.periodic(const Duration(minutes: 5), (timer) { + setState(() {}); + }); + } + @override Widget build(BuildContext context) { return BlocProvider( @@ -521,72 +535,58 @@ class _UserServiceScreenState extends State { } Widget customActionButtons(ServiceEntity service, MyUser user) { + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, + ); + if (service.status == ServiceStatus.acepted || service.status == ServiceStatus.active) { - return Wrap( - alignment: WrapAlignment.center, - spacing: 15, - children: [ - Visibility( - visible: user.phone == null ? false : true, - child: ElevatedButton( - onPressed: () => launch("tel:${user.phone}"), - style: ElevatedButton.styleFrom( - foregroundColor: const Color(0xFF2BA4EC), - backgroundColor: Colors.white, - shape: const CircleBorder( - side: BorderSide( + if (now.isAfter(serviceDateTime)) { + return const SizedBox(); + } else { + return Wrap( + alignment: WrapAlignment.center, + spacing: 15, + children: [ + Visibility( + visible: user.phone == null ? false : true, + child: ElevatedButton( + onPressed: () => launch("tel:${user.phone}"), + style: ElevatedButton.styleFrom( + foregroundColor: const Color(0xFF2BA4EC), + backgroundColor: Colors.white, + shape: const CircleBorder( + side: BorderSide( + color: Color(0xFF2BA4EC), + width: 2, + ), + ), + ), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 20, horizontal: 0), + child: Icon( + Icons.phone_android, + size: 30, color: Color(0xFF2BA4EC), - width: 2, ), ), ), - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 20, horizontal: 0), - child: Icon( - Icons.phone_android, - size: 30, - color: Color(0xFF2BA4EC), - ), - ), ), - ), - ElevatedButton( - onPressed: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ChatScreen(service: service), - ), - ); - }, - style: ElevatedButton.styleFrom( - foregroundColor: const Color(0xFF2BA4EC), - backgroundColor: Colors.white, - shape: const CircleBorder( - side: BorderSide( - color: Color(0xFF2BA4EC), - width: 2, - ), - ), - ), - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 20, horizontal: 0), - child: Icon( - Icons.message, - size: 30, - color: Color(0xFF2BA4EC), - ), - ), - ), - Visibility( - visible: user.phone == null ? false : true, - child: ElevatedButton( - onPressed: () async { - final whatsappUrl = - 'https://wa.me/${user.phone}?text=${Uri.parse('Hola! me contactaste por Prossapp')}'; - if (!await launch(whatsappUrl)) { - throw Exception('Could not launch $whatsappUrl'); + ElevatedButton( + onPressed: () { + if (service.id != null) { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => ChatScreen(service: service), + ), + ); } }, style: ElevatedButton.styleFrom( @@ -602,269 +602,81 @@ class _UserServiceScreenState extends State { child: const Padding( padding: EdgeInsets.symmetric(vertical: 20, horizontal: 0), child: Icon( - CommunityMaterialIcons.whatsapp, + Icons.message, size: 30, color: Color(0xFF2BA4EC), ), ), ), - ), - ], - ); + Visibility( + visible: user.phone == null ? false : true, + child: ElevatedButton( + onPressed: () async { + final whatsappUrl = + 'https://wa.me/${user.phone}?text=${Uri.parse('Hola! me contactaste por Prossapp')}'; + if (!await launch(whatsappUrl)) { + throw Exception('Could not launch $whatsappUrl'); + } + }, + style: ElevatedButton.styleFrom( + foregroundColor: const Color(0xFF2BA4EC), + backgroundColor: Colors.white, + shape: const CircleBorder( + side: BorderSide( + color: Color(0xFF2BA4EC), + width: 2, + ), + ), + ), + child: const Padding( + padding: EdgeInsets.symmetric(vertical: 20, horizontal: 0), + child: Icon( + CommunityMaterialIcons.whatsapp, + size: 30, + color: Color(0xFF2BA4EC), + ), + ), + ), + ), + ], + ); + } } return const SizedBox(); } Widget customMessageStatus(ServiceEntity service) { - if (service.status == ServiceStatus.pending) { - return Stack( - alignment: AlignmentDirectional.topCenter, - clipBehavior: Clip.none, - children: [ - Card( - color: Colors.green.shade50, - child: const Padding( - padding: EdgeInsets.fromLTRB(32, 56, 32, 32), - child: Text( - 'Servicio enviado', - style: TextStyle(fontSize: 32, color: Colors.green), - ), - ), - ), - Positioned( - top: -40, - child: Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.green.shade50, width: 4), - shape: BoxShape.circle, - ), - child: const Icon(Icons.mark_email_read_rounded, - color: Colors.green, size: 48), - ), - ) - ], - ); - } - // if (service.status == ServiceStatus.acepted) { - // return Stack( - // alignment: AlignmentDirectional.topCenter, - // clipBehavior: Clip.none, - // children: [ - // Card( - // color: Colors.green.shade50, - // child: const Padding( - // padding: EdgeInsets.fromLTRB(32, 56, 32, 32), - // child: Text( - // 'Aceptado', - // style: TextStyle(fontSize: 32, color: Colors.green), - // ), - // ), - // ), - // Positioned( - // top: -40, - // child: Container( - // padding: const EdgeInsets.all(16), - // decoration: BoxDecoration( - // color: Colors.white, - // border: Border.all(color: Colors.green.shade50, width: 4), - // shape: BoxShape.circle, - // ), - // child: const Icon(Icons.check, color: Colors.green, size: 48), - // ), - // ) - // ], - // ); - // } - if (service.status == ServiceStatus.cancelled) { + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, + ); + + if (now.isAfter(serviceDateTime)) { return Stack( alignment: AlignmentDirectional.topCenter, clipBehavior: Clip.none, children: [ Card( color: Colors.red.shade100, - child: const Padding( - padding: EdgeInsets.fromLTRB(32, 56, 32, 32), - child: Text( - 'Cancelado', - style: TextStyle(fontSize: 32, color: Colors.red), - ), - ), - ), - Positioned( - top: -40, - child: Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.red.shade100, width: 4), - shape: BoxShape.circle, - ), - child: - const Icon(Icons.close_rounded, color: Colors.red, size: 48), - ), - ) - ], - ); - } - if (service.status == ServiceStatus.denied) { - return Stack( - alignment: AlignmentDirectional.topCenter, - clipBehavior: Clip.none, - children: [ - Card( - color: Colors.red.shade100, - child: const Padding( - padding: EdgeInsets.fromLTRB(32, 56, 32, 32), - child: Text( - 'Rechazado', - style: TextStyle(fontSize: 32, color: Colors.red), - ), - ), - ), - Positioned( - top: -40, - child: Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.red.shade100, width: 4), - shape: BoxShape.circle, - ), - child: - const Icon(Icons.close_rounded, color: Colors.red, size: 48), - ), - ) - ], - ); - } - - // if (service.status == ServiceStatus.active) { - // return Stack( - // alignment: AlignmentDirectional.topCenter, - // clipBehavior: Clip.none, - // children: [ - // Card( - // color: Colors.green.shade50, - // child: const Padding( - // padding: EdgeInsets.fromLTRB(32, 56, 32, 32), - // child: Text( - // 'En proceso...', - // style: TextStyle(fontSize: 32, color: Colors.green), - // ), - // ), - // ), - // Positioned( - // top: -40, - // child: Container( - // padding: const EdgeInsets.all(16), - // decoration: BoxDecoration( - // color: Colors.white, - // border: Border.all(color: Colors.green.shade50, width: 4), - // shape: BoxShape.circle, - // ), - // child: const Icon( - // Icons.access_time_rounded, - // color: Colors.green, - // size: 48, - // ), - // ), - // ) - // ], - // ); - // } - if (service.status == ServiceStatus.completed && - service.professionalScored == false) { - return Stack( - alignment: AlignmentDirectional.topCenter, - clipBehavior: Clip.none, - children: [ - Card( - color: Colors.green.shade50, - child: Padding( - padding: const EdgeInsets.fromLTRB(32, 56, 32, 32), - child: Column( - children: [ - const Text( - 'Completado', - style: TextStyle(fontSize: 32, color: Colors.green), - ), - const Text( - 'Califica el servicio', - style: TextStyle(fontSize: 20, color: Colors.green), - ), - const SizedBox(height: 15), - FilledButton( - onPressed: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ScoreScreen( - service: service, - ), - ), - ); - }, - style: FilledButton.styleFrom( - backgroundColor: Colors.green, - padding: const EdgeInsets.symmetric(vertical: 15), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - ), - child: Container( - alignment: Alignment.center, - width: MediaQuery.of(context).size.width * 0.4, - child: const Text( - 'Calificar', - style: TextStyle( - color: Colors.white, - fontSize: 18, - ), - ), - ), - ), - ], - ), - ), - ), - Positioned( - top: -40, - child: Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: Colors.green.shade50, width: 4), - shape: BoxShape.circle, - ), - child: const Icon( - Icons.star, - color: Colors.green, - size: 48, - ), - ), - ) - ], - ); - } - - if (service.status == ServiceStatus.completed && - service.professionalScored == true) { - return Stack( - alignment: AlignmentDirectional.topCenter, - clipBehavior: Clip.none, - children: [ - Card( - color: Colors.green.shade50, child: const Padding( padding: EdgeInsets.fromLTRB(32, 56, 32, 32), child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - 'Completado', - style: TextStyle(fontSize: 32, color: Colors.green), + 'Caducado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + Text( + 'Tu servicio ha excedido \n el tiempo de espera', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18, color: Colors.red), ), ], ), @@ -876,18 +688,193 @@ class _UserServiceScreenState extends State { padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, - border: Border.all(color: Colors.green.shade50, width: 4), + border: Border.all(color: Colors.red.shade100, width: 4), shape: BoxShape.circle, ), - child: const Icon( - Icons.star, - color: Colors.green, - size: 48, - ), + child: + const Icon(Icons.close_rounded, color: Colors.red, size: 48), ), ) ], ); + } else { + if (service.status == ServiceStatus.cancelled) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.red.shade100, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Text( + 'Cancelado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.red.shade100, width: 4), + shape: BoxShape.circle, + ), + child: const Icon(Icons.close_rounded, + color: Colors.red, size: 48), + ), + ) + ], + ); + } + if (service.status == ServiceStatus.denied) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.red.shade100, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Text( + 'Rechazado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.red.shade100, width: 4), + shape: BoxShape.circle, + ), + child: const Icon(Icons.close_rounded, + color: Colors.red, size: 48), + ), + ) + ], + ); + } + + if (service.status == ServiceStatus.completed && + service.userScored == false) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.green.shade50, + child: Padding( + padding: const EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Column( + children: [ + const Text( + 'Completado', + style: TextStyle(fontSize: 32, color: Colors.green), + ), + const Text( + 'Califica el servicio', + style: TextStyle(fontSize: 20, color: Colors.green), + ), + const SizedBox(height: 15), + FilledButton( + onPressed: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => ScoreScreen( + service: service, + ), + ), + ); + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.green, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Container( + alignment: Alignment.center, + width: MediaQuery.of(context).size.width * 0.4, + child: const Text( + 'Calificar', + style: TextStyle( + color: Colors.white, + fontSize: 18, + ), + ), + ), + ), + ], + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.green.shade50, width: 4), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.star, + color: Colors.green, + size: 48, + ), + ), + ) + ], + ); + } + + if (service.status == ServiceStatus.completed && + service.userScored == true) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.green.shade50, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Column( + children: [ + Text( + 'Completado', + style: TextStyle(fontSize: 32, color: Colors.green), + ), + ], + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.green.shade50, width: 4), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.star, + color: Colors.green, + size: 48, + ), + ), + ) + ], + ); + } } return const SizedBox(); @@ -895,33 +882,89 @@ class _UserServiceScreenState extends State { Widget customButton( ServiceEntity service, BuildContext context, MyUser userInfo) { - if (service.status == ServiceStatus.pending) { + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, + ); + + if (now.isAfter(serviceDateTime)) { return GeneralSecondaryButton( - label: 'Cancelar servicio', - color: Theme.of(context).colorScheme.error, - onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add( - UpdateServiceStatus(widget.serviceId, ServiceStatus.cancelled)); - } - - if (userInfo.token != null) { - LocalNotifications.sendPushNotification( - userInfo.token!, - 'Servicio cancelado', - 'Servicio cancelado por ${userInfo.name}', - ); - } - }, - ); - } - - return GeneralSecondaryButton( label: 'Volver', onPressed: () { Navigator.pop(context); - }); + }, + ); + } else { + if (service.status == ServiceStatus.pending) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } + + if (userInfo.token != null) { + LocalNotifications.sendPushNotification( + userInfo.token!, + 'Servicio cancelado', + 'Servicio cancelado por ${userInfo.name}', + ); + } + }, + ); + } + + if (service.status == ServiceStatus.acepted) { + if (serviceDateTime.difference(now).inDays > 1) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } + + if (userInfo.token != null) { + LocalNotifications.sendPushNotification( + userInfo.token!, + 'Servicio cancelado', + 'Servicio cancelado por ${userInfo.name}', + ); + } + }, + ); + } + } + + if (service.status == ServiceStatus.active) { + return GeneralSecondaryButton( + label: 'Terminar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.completed)); + } + }); + } + } + + return GeneralSecondaryButton( + label: 'Volver', + onPressed: () { + Navigator.pop(context); + }, + ); } String formatCurrency(int number) { diff --git a/lib/screens/user/user_service_screen.dart b/lib/screens/user/user_service_screen.dart index d7fad96..256ba2e 100644 --- a/lib/screens/user/user_service_screen.dart +++ b/lib/screens/user/user_service_screen.dart @@ -1,5 +1,4 @@ -import 'dart:developer'; - +import 'dart:async'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -8,9 +7,9 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; -import 'package:prosappco/components/general_primary_button.dart'; import 'package:prosappco/components/general_secondary_button.dart'; import 'package:prosappco/local_notifications/local_notifications.dart'; +import 'package:prosappco/screens/score/score_screen.dart'; import 'package:service_repository/service_repository.dart'; import 'package:setting_repository/setting_repository.dart'; import 'package:user_repository/user_repository.dart'; @@ -27,12 +26,26 @@ class UserServiceScreen extends StatefulWidget { class _UserServiceScreenState extends State { final settingRepository = Injector.appInstance.get(); SettingEntity? settings; + Timer? _timer; @override void initState() { super.initState(); _loadSettings(); + _startTimer(); + } + + @override + void dispose() { + _timer?.cancel(); + super.dispose(); + } + + void _startTimer() { + _timer = Timer.periodic(const Duration(minutes: 5), (timer) { + setState(() {}); + }); } void _loadSettings() { @@ -277,94 +290,270 @@ class _UserServiceScreenState extends State { ); } - Center customMessageStatus(ServiceEntity service) { - if (service.status == ServiceStatus.cancelled) { - return const Center( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: Icon( - CupertinoIcons.xmark_circle, - color: Color(0xFF35A8ED), - size: 70, - ), - ), - Text( - 'Servicio cancelado exitosamente', - style: TextStyle( - color: Color(0xFF35A8ED), - fontSize: 17, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ); - } - - if (service.status == ServiceStatus.completed) { - return const Center( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: Icon( - Icons.favorite_outline_sharp, - color: Color(0xFF35A8ED), - size: 70, - ), - ), - Text( - 'Servicio terminado exitosamente', - style: TextStyle( - color: Color(0xFF35A8ED), - fontSize: 17, - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ); - } - - return const Center( - child: Column( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: Icon( - Icons.check_circle_outline_rounded, - color: Color(0xFF35A8ED), - size: 70, - ), - ), - Text( - 'Servicio solicitado exitosamente', - style: TextStyle( - color: Color(0xFF35A8ED), - fontSize: 17, - fontWeight: FontWeight.w600, - ), - ), - ], - ), + Widget customMessageStatus(ServiceEntity service) { + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, ); + + if (now.isAfter(serviceDateTime)) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.red.shade100, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Caducado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + Text( + 'Tu servicio ha excedido \n el tiempo de espera', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 18, color: Colors.red), + ), + ], + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.red.shade100, width: 4), + shape: BoxShape.circle, + ), + child: + const Icon(Icons.close_rounded, color: Colors.red, size: 48), + ), + ) + ], + ); + } else { + if (service.status == ServiceStatus.cancelled) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.red.shade100, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Text( + 'Cancelado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.red.shade100, width: 4), + shape: BoxShape.circle, + ), + child: const Icon(Icons.close_rounded, + color: Colors.red, size: 48), + ), + ) + ], + ); + } + if (service.status == ServiceStatus.denied) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.red.shade100, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Text( + 'Rechazado', + style: TextStyle(fontSize: 32, color: Colors.red), + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.red.shade100, width: 4), + shape: BoxShape.circle, + ), + child: const Icon(Icons.close_rounded, + color: Colors.red, size: 48), + ), + ) + ], + ); + } + + if (service.status == ServiceStatus.completed && + service.userScored == false) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.green.shade50, + child: Padding( + padding: const EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Column( + children: [ + const Text( + 'Completado', + style: TextStyle(fontSize: 32, color: Colors.green), + ), + const Text( + 'Califica el servicio', + style: TextStyle(fontSize: 20, color: Colors.green), + ), + const SizedBox(height: 15), + FilledButton( + onPressed: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => ScoreScreen( + service: service, + ), + ), + ); + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.green, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Container( + alignment: Alignment.center, + width: MediaQuery.of(context).size.width * 0.4, + child: const Text( + 'Calificar', + style: TextStyle( + color: Colors.white, + fontSize: 18, + ), + ), + ), + ), + ], + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.green.shade50, width: 4), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.star, + color: Colors.green, + size: 48, + ), + ), + ) + ], + ); + } + + if (service.status == ServiceStatus.completed && + service.userScored == true) { + return Stack( + alignment: AlignmentDirectional.topCenter, + clipBehavior: Clip.none, + children: [ + Card( + color: Colors.green.shade50, + child: const Padding( + padding: EdgeInsets.fromLTRB(32, 56, 32, 32), + child: Column( + children: [ + Text( + 'Completado', + style: TextStyle(fontSize: 32, color: Colors.green), + ), + ], + ), + ), + ), + Positioned( + top: -40, + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: Colors.green.shade50, width: 4), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.star, + color: Colors.green, + size: 48, + ), + ), + ) + ], + ); + } + } + + return const SizedBox(); } - GeneralSecondaryButton customButton( + Widget customButton( ServiceEntity service, BuildContext context, MyUser userInfo) { - if (service.status == ServiceStatus.pending) { + DateTime serviceDate = DateTime.parse(service.day); + DateTime now = DateTime.now(); + DateTime serviceDateTime = DateTime( + serviceDate.year, + serviceDate.month, + serviceDate.day, + service.range1Hour2.hour, + service.range1Hour2.minute, + ); + + if (now.isAfter(serviceDateTime)) { return GeneralSecondaryButton( + label: 'Volver', onPressed: () { - final currentState = context.read().state; - if (currentState is ServiceLoaded) { - context.read().add( - UpdateServiceStatus( - widget.serviceId, - ServiceStatus.cancelled, - ), - ); + Navigator.pop(context); + }, + ); + } else { + if (service.status == ServiceStatus.pending) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } if (userInfo.token != null) { LocalNotifications.sendPushNotification( @@ -373,18 +562,52 @@ class _UserServiceScreenState extends State { 'Servicio cancelado por ${userInfo.name}', ); } - } - }, - color: Colors.red, - label: 'Cancelar Servicio', - ); + }, + ); + } + + if (service.status == ServiceStatus.acepted) { + if (serviceDateTime.difference(now).inDays > 1) { + return GeneralSecondaryButton( + label: 'Cancelar servicio', + color: Theme.of(context).colorScheme.error, + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.cancelled)); + } + + if (userInfo.token != null) { + LocalNotifications.sendPushNotification( + userInfo.token!, + 'Servicio cancelado', + 'Servicio cancelado por ${userInfo.name}', + ); + } + }, + ); + } + } + + if (service.status == ServiceStatus.active) { + return GeneralSecondaryButton( + label: 'Terminar servicio', + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + context.read().add(UpdateServiceStatus( + widget.serviceId, ServiceStatus.completed)); + } + }); + } } return GeneralSecondaryButton( + label: 'Volver', onPressed: () { Navigator.pop(context); }, - label: 'Volver', ); }