scored true

This commit is contained in:
Felipe
2024-04-18 08:37:09 -05:00
parent 73159cdd57
commit 2facd1b1d8
7 changed files with 289 additions and 138 deletions
+13
View File
@@ -33,6 +33,7 @@ class ServiceBloc extends Bloc<ServiceEvent, ServiceState> {
on<LoadServicesHistoryForUser>(_onLoadServicesHistoryForUser); on<LoadServicesHistoryForUser>(_onLoadServicesHistoryForUser);
on<LoadServicesHistoryForProfessional>( on<LoadServicesHistoryForProfessional>(
_onLoadServicesHistoryForProfessional); _onLoadServicesHistoryForProfessional);
on<UpdateProfessionalScored>(_onUpdateProfessionalScored);
} }
void _onCreateService(CreateService event, Emitter<ServiceState> emit) async { void _onCreateService(CreateService event, Emitter<ServiceState> emit) async {
@@ -235,6 +236,18 @@ class ServiceBloc extends Bloc<ServiceEvent, ServiceState> {
emit(CreateServiceFailure()); emit(CreateServiceFailure());
} }
} }
void _onUpdateProfessionalScored(
UpdateProfessionalScored event, Emitter<ServiceState> emit) async {
try {
emit(CreateServiceLoading());
await _serviceRepository.setProfessionalScored(event.serviceId);
emit(ProfessionalScoredUpdated());
} catch (e) {
log(e.toString());
emit(CreateServiceFailure());
}
}
} }
class ServiceInfoUI { class ServiceInfoUI {
+18
View File
@@ -62,6 +62,24 @@ class LoadServicesHistoryForUser extends ServiceEvent {
List<Object> get props => [userId]; List<Object> get props => [userId];
} }
class LoadServicesByDay extends ServiceEvent {
final String day;
const LoadServicesByDay(this.day);
@override
List<Object> get props => [day];
}
class UpdateProfessionalScored extends ServiceEvent {
final String serviceId;
const UpdateProfessionalScored(this.serviceId);
@override
List<Object> get props => [serviceId];
}
class CreateService extends ServiceEvent { class CreateService extends ServiceEvent {
final String professionalId; final String professionalId;
final bool? professionalScored; final bool? professionalScored;
+2 -1
View File
@@ -16,7 +16,6 @@ class ServiceLoaded extends ServiceState {
List<Object> get props => [service]; List<Object> get props => [service];
} }
class ServicesForUserLoaded extends ServiceState { class ServicesForUserLoaded extends ServiceState {
final List<ServiceInfoUI> services; final List<ServiceInfoUI> services;
@@ -49,3 +48,5 @@ class ServiceStatusUpdated extends ServiceState {
@override @override
List<Object> get props => [newStatus]; List<Object> get props => [newStatus];
} }
class ProfessionalScoredUpdated extends ServiceState {}
+63 -48
View File
@@ -4,7 +4,9 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:injector/injector.dart';
import 'package:prosappco/blocs/score_bloc/score_bloc.dart'; import 'package:prosappco/blocs/score_bloc/score_bloc.dart';
import 'package:prosappco/blocs/service_bloc/service_bloc.dart';
import 'package:score_repository/score_repository.dart'; import 'package:score_repository/score_repository.dart';
import 'package:service_repository/service_repository.dart'; import 'package:service_repository/service_repository.dart';
import 'package:user_repository/user_repository.dart'; import 'package:user_repository/user_repository.dart';
@@ -102,7 +104,7 @@ class _ScoreScreenState extends State<ScoreScreen> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
const Text( const Text(
'Calificación', 'Califica el servicio',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600), style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
@@ -155,54 +157,67 @@ class _ScoreScreenState extends State<ScoreScreen> {
height: 1, height: 1,
thickness: 0.5, thickness: 0.5,
), ),
Padding( BlocProvider<ServiceBloc>(
padding: const EdgeInsets.symmetric( create: (context) => Injector.appInstance.get<ServiceBloc>(),
vertical: 10, child: Padding(
horizontal: 15, padding: const EdgeInsets.symmetric(
), vertical: 10,
child: FilledButton( horizontal: 15,
onPressed: () {
final CommentEntity comment = widget.service.userId ==
FirebaseAuth.instance.currentUser!.uid
? CommentEntity(
serviceId: widget.service.id!,
authorId: FirebaseAuth.instance.currentUser!.uid,
isFromUser: true,
score: _rating,
destinationId: widget.service.professionalId,
content: commentController.text,
createdAt: Timestamp.now(),
)
: CommentEntity(
serviceId: widget.service.id!,
authorId: FirebaseAuth.instance.currentUser!.uid,
isFromUser: false,
score: _rating,
destinationId: widget.service.userId,
content: commentController.text,
createdAt: Timestamp.now(),
);
BlocProvider.of<ScoreBloc>(context)
.add(SendScoreEvent(comment: comment));
},
style: FilledButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary,
padding: const EdgeInsets.symmetric(vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
), ),
child: Container( child: BlocBuilder<ServiceBloc, ServiceState>(
alignment: Alignment.center, builder: (context, state) {
width: double.infinity, return FilledButton(
child: const Text( onPressed: () {
'Enviar calificación', final CommentEntity comment = widget.service.userId ==
style: TextStyle( FirebaseAuth.instance.currentUser!.uid
color: Colors.white, ? CommentEntity(
fontSize: 18, serviceId: widget.service.id!,
), authorId: FirebaseAuth.instance.currentUser!.uid,
), isFromUser: true,
score: _rating,
destinationId: widget.service.professionalId,
content: commentController.text.trim(),
createdAt: Timestamp.now(),
)
: CommentEntity(
serviceId: widget.service.id!,
authorId: FirebaseAuth.instance.currentUser!.uid,
isFromUser: false,
score: _rating,
destinationId: widget.service.userId,
content: commentController.text.trim(),
createdAt: Timestamp.now(),
);
BlocProvider.of<ScoreBloc>(context)
.add(SendScoreEvent(comment: comment));
context
.read<ServiceBloc>()
.add(UpdateProfessionalScored(widget.service.id!));
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,
width: double.infinity,
child: const Text(
'Enviar calificación',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
),
);
},
), ),
), ),
), ),
@@ -517,96 +517,119 @@ class _ProfessionalServiceScreenState extends State<ProfessionalServiceScreen> {
); );
} }
if (service.status == ServiceStatus.completed) { if (service.status == ServiceStatus.completed &&
if (service.userScored) { service.userScored == false) {
return Stack( return Stack(
alignment: AlignmentDirectional.topCenter, alignment: AlignmentDirectional.topCenter,
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
Card( Card(
color: Colors.green.shade50, color: Colors.green.shade50,
child: const Padding( child: Padding(
padding: EdgeInsets.fromLTRB(32, 56, 32, 32), padding: const EdgeInsets.fromLTRB(32, 56, 32, 32),
child: Text( child: Column(
'Completado', children: [
style: TextStyle(fontSize: 32, color: Colors.green), const Text(
), 'Completado',
), style: TextStyle(fontSize: 32, color: Colors.green),
), ),
Positioned( const Text(
top: -40, 'Califica el servicio',
child: Container( style: TextStyle(fontSize: 20, color: Colors.green),
padding: const EdgeInsets.all(16), ),
decoration: BoxDecoration( const SizedBox(height: 15),
color: Colors.white, FilledButton(
border: Border.all(color: Colors.green.shade50, width: 4), onPressed: () {
shape: BoxShape.circle, Navigator.push(
), context,
child: const Icon( CupertinoPageRoute(
Icons.check_rounded, builder: (context) => ScoreScreen(
color: Colors.green, service: service,
size: 48,
),
),
)
],
);
} else {
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 SizedBox(height: 16),
const Text(
'Califica el servicio',
style: TextStyle(fontSize: 28, color: Colors.green),
),
FilledButton(
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ScoreScreen(
service: service,
),
), ),
); ),
}, );
child: const Text('Calificar'), },
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,
width: MediaQuery.of(context).size.width * 0.4,
child: const Text(
'Calificar',
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
),
),
],
), ),
), ),
Positioned( ),
top: -40, Positioned(
child: Container( top: -40,
padding: const EdgeInsets.all(16), child: Container(
decoration: BoxDecoration( padding: const EdgeInsets.all(16),
color: Colors.white, decoration: BoxDecoration(
border: Border.all(color: Colors.green.shade50, width: 4), color: Colors.white,
shape: BoxShape.circle, border: Border.all(color: Colors.green.shade50, width: 4),
), shape: BoxShape.circle,
child: const Icon(
Icons.star,
color: Colors.green,
size: 48,
),
), ),
) 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(); return const SizedBox();
+62 -4
View File
@@ -647,7 +647,8 @@ class _UserServiceScreenState extends State<UserServiceScreen> {
// ], // ],
// ); // );
// } // }
if (service.status == ServiceStatus.completed) { if (service.status == ServiceStatus.completed &&
service.professionalScored == false) {
return Stack( return Stack(
alignment: AlignmentDirectional.topCenter, alignment: AlignmentDirectional.topCenter,
clipBehavior: Clip.none, clipBehavior: Clip.none,
@@ -662,11 +663,11 @@ class _UserServiceScreenState extends State<UserServiceScreen> {
'Completado', 'Completado',
style: TextStyle(fontSize: 32, color: Colors.green), style: TextStyle(fontSize: 32, color: Colors.green),
), ),
const SizedBox(height: 16),
const Text( const Text(
'Califica el servicio', 'Califica el servicio',
style: TextStyle(fontSize: 28, color: Colors.green), style: TextStyle(fontSize: 20, color: Colors.green),
), ),
const SizedBox(height: 15),
FilledButton( FilledButton(
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
@@ -678,7 +679,64 @@ class _UserServiceScreenState extends State<UserServiceScreen> {
), ),
); );
}, },
child: const Text('Calificar'), 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,
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(
children: [
Text(
'Completado',
style: TextStyle(fontSize: 32, color: Colors.green),
), ),
], ],
), ),
@@ -68,6 +68,29 @@ class FirebaseServiceRepository {
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id)) .map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
.toList()); .toList());
} }
// actualizar professionalScored a true
Future<void> setProfessionalScored(String serviceId) {
return serviceCollection
.doc(serviceId)
.update({'professional_scored': true});
}
Future<void> setUserScored(String serviceId) {
return serviceCollection.doc(serviceId).update({'user_scored': true});
}
// TODO: NEW
Stream<List<ServiceEntity>> getServicesByDay(String day) {
return serviceCollection
.where('day', isEqualTo: day)
.where('status', whereIn: [0, 1, 2, 3])
.snapshots()
.map((querySnapshot) => querySnapshot.docs
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
.toList());
}
} }