This commit is contained in:
Juan Felipe Duarte
2023-06-20 11:21:14 -05:00
parent 05fa9438a1
commit a190833b53
10 changed files with 279 additions and 136 deletions
+54 -7
View File
@@ -1,4 +1,5 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
@@ -7,6 +8,8 @@ import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/chat_model.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/models/user_model.dart';
import 'package:prosappco/src/screens/professional.dart';
import 'package:prosappco/src/screens/professional_info.dart';
class ChatScreen extends StatefulWidget {
final String? eventoId;
@@ -20,6 +23,8 @@ class _ChatScreenState extends State<ChatScreen> {
final _textController = TextEditingController();
final uid = AuthenticationRepository.instance.getCurrentUserUid();
UserModel? user;
Professional? professional;
bool pro = false;
@override
void initState() {
@@ -31,8 +36,10 @@ class _ChatScreenState extends State<ChatScreen> {
(UserModel s) => setState(() => user = s),
);
} else {
Professional.getProfessional(event.professionalId)
.then((value) => {professional = value});
UserModel.getUser(event.professionalId).then(
(UserModel s) => setState(() => user = s),
(UserModel s) => setState(() => {user = s, pro = true}),
);
}
}
@@ -65,12 +72,27 @@ class _ChatScreenState extends State<ChatScreen> {
color: const Color(0xFFD6F4FF),
alignment: Alignment.topCenter,
child: ListTile(
leading: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: ReferencePhoto(
ref: user?.photo,
size: 55,
sizeCircle: 60,
leading: GestureDetector(
onTap: () {
if (pro) {
Navigator.of(context).push(
CupertinoPageRoute(
builder: (BuildContext context) {
return ProfessionalInfoScreen(
professional: professional!,
);
},
),
);
}
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: ReferencePhoto(
ref: user?.photo,
size: 55,
sizeCircle: 60,
),
),
),
title: Text(
@@ -119,6 +141,31 @@ class _ChatScreenState extends State<ChatScreen> {
filled: true,
fillColor: Colors.grey[200],
),
onFieldSubmitted: (value) {
String muestra = _textController.text.trim();
if (muestra.isNotEmpty) {
final nuevoMensaje = MessageModel(
user: uid!,
content:
_textController.text.trimLeft().trimRight(),
timestamp: DateTime.now());
final nuevoMensajeMap = {
'user': nuevoMensaje.user,
'content': nuevoMensaje.content,
'timestamp': nuevoMensaje.timestamp,
};
FirebaseFirestore.instance
.collection('chats')
.doc(widget.eventoId)
.update({
'message': FieldValue.arrayUnion([nuevoMensajeMap])
});
_textController.clear();
} else {}
},
),
),
const SizedBox(width: 12),
+146 -109
View File
@@ -359,20 +359,24 @@ class _CitaScreenState extends State<CitaScreen> {
ElevatedButton(
onPressed: () async {
if (widget.evento.status != 'pendiente') {
await FirebaseFirestore.instance
final chatDoc = FirebaseFirestore.instance
.collection('chats')
.doc(widget.evento.id)
.set(
{
.doc(widget.evento.id);
final chatSnapshot = await chatDoc.get();
if (!chatSnapshot.exists ||
chatSnapshot.data()!['message'] == null) {
await chatDoc.set(
{
'professional_id':
widget.evento.professionalId,
'user_id': widget.evento.userId,
'message': [],
},
SetOptions(
merge:
true)).catchError((error) => print(
'Error al crear el documento: $error'));
SetOptions(merge: true),
).catchError((error) => print(
'Error al crear el documento: $error'));
}
Navigator.push(
context,
@@ -383,7 +387,35 @@ class _CitaScreenState extends State<CitaScreen> {
},
),
);
} else {
}
// if (widget.evento.status != 'pendiente') {
// await FirebaseFirestore.instance
// .collection('chats')
// .doc(widget.evento.id)
// .set(
// {
// 'professional_id':
// widget.evento.professionalId,
// 'user_id': widget.evento.userId,
// 'message': [],
// },
// SetOptions(
// merge:
// true)).catchError((error) => print(
// 'Error al crear el documento: $error'));
// Navigator.push(
// context,
// CupertinoPageRoute(
// builder: (BuildContext context) {
// return ChatScreen(
// eventoId: widget.evento.id);
// },
// ),
// );
// }
else {
final snackBar = SnackBar(
backgroundColor: Colors.blue,
content: const Text(
@@ -497,84 +529,86 @@ class _CitaScreenState extends State<CitaScreen> {
),
),
widget.evento.status == 'aprobado'
? eventDate.year == today.year &&
eventDate.month == today.month &&
eventDate.day == today.day
? (DateTime.now()
.difference(
DateTime.parse(widget.evento.range1Hour1))
.abs() <=
const Duration(minutes: 30) &&
ver == true)
? Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "iniciado"}).then(
(value) {
setState(() {
ver = false;
? Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: eventDate.year == today.year &&
eventDate.month == today.month &&
eventDate.day == today.day
? (DateTime.now()
.difference(DateTime.parse(
widget.evento.range1Hour1))
.abs() <=
const Duration(minutes: 30) &&
ver == true)
? ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "iniciado"}).then(
(value) {
setState(() {
ver = false;
});
});
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
child: const Text(
'Iniciar servicio',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
child: const Text(
'Iniciar servicio',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
)
: const SizedBox()
: const SizedBox(),
),
widget.evento.professionalId == uid
? ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "denegado"}).then(
(value) {
Navigator.pushReplacementNamed(
context, '/solicitud');
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFEC2B2B),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
child: const Text(
'Cancelar servicio',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "denegado"}).then(
(value) {
Navigator.pushReplacementNamed(
context, '/solicitud');
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFEC2B2B),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
child: const Text(
'Cancelar servicio',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
],
),
)
: const SizedBox()
: const SizedBox()
)
: const SizedBox(),
],
),
)
: const SizedBox(),
widget.evento.status == 'pendiente'
? Padding(
@@ -583,33 +617,36 @@ class _CitaScreenState extends State<CitaScreen> {
children: [
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "aprobado"}).then((value) {
Navigator.pushReplacementNamed(
context, '/solicitud');
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
child: const Text(
'Aceptar',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
child: widget.evento.professionalId == uid
? ElevatedButton(
onPressed: () {
FirebaseFirestore.instance
.collection("services")
.doc('${widget.evento.id}')
.update({"status": "aprobado"}).then(
(value) {
Navigator.pushReplacementNamed(
context, '/solicitud');
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 60),
),
child: const Text(
'Aceptar',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
)
: const SizedBox(),
),
ElevatedButton(
onPressed: () {
+20 -9
View File
@@ -52,8 +52,13 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
stream: FirebaseFirestore.instance
.collection('services')
.where('user_id', isEqualTo: uid)
.where('status',
whereIn: ['aprobado', 'denegado', 'iniciado', 'terminado'])
.where('status', whereIn: [
'aprobado',
'denegado',
'iniciado',
'terminado',
'pendiente'
])
.snapshots()
.asyncMap((snapshot) async {
try {
@@ -123,17 +128,23 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
color: Colors.blue,
size: 40,
)
: event.status == 'terminado'
: event.status == 'pendiente'
? const Icon(
Icons.rocket_launch,
Icons.access_time_outlined,
color: Colors.blue,
size: 40,
)
: const Icon(
Icons.close,
color: Colors.red,
size: 40,
),
: event.status == 'terminado'
? const Icon(
Icons.rocket_launch,
color: Colors.blue,
size: 40,
)
: const Icon(
Icons.close,
color: Colors.red,
size: 40,
),
title: RichText(
text: TextSpan(
children: [
@@ -258,6 +258,9 @@ class _ProfessionalProfileWebScreenState
.child(random);
final metaData = SettableMetadata(contentType: 'image/jpeg');
// final metaDataImg = SettableMetadata(contentType: 'image/jpeg');
// final metaDataPdf = SettableMetadata(contentType: 'application/pdf');
// final metaDataWord = SettableMetadata(contentType: 'application/msword');
final UploadTask uploadTask = ref.putData(imageCedulaBytes!, metaData);
+6 -6
View File
@@ -445,10 +445,10 @@ class _ProfileProState extends State<ProfilePro> {
},
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Row(
children: const [
children: [
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 30),
@@ -482,11 +482,11 @@ class _ProfileProState extends State<ProfilePro> {
: const EdgeInsets.only(bottom: 70),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 30),
const Padding(
padding: EdgeInsets.only(left: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
children: [
Text('Lunes'),
Text('Martes'),
Text('Miércoles'),
+2 -2
View File
@@ -258,7 +258,7 @@ class _ProfileWebScreenState extends State<ProfileWebScreen> {
body: Center(
child: SizedBox(
width: 300,
height: 550,
height: 600,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
@@ -412,7 +412,7 @@ class _ProfileWebScreenState extends State<ProfileWebScreen> {
),
Container(
alignment: Alignment.bottomCenter,
margin: const EdgeInsets.only(top: 50),
margin: const EdgeInsets.only(top: 30),
padding: const EdgeInsets.only(bottom: 30),
child: ElevatedButton(
onPressed: () async {
+21 -3
View File
@@ -1,4 +1,5 @@
import 'package:community_material_icon/community_material_icon.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
@@ -14,6 +15,8 @@ class SupportScreen extends StatefulWidget {
class SsupportStateScreen extends State<SupportScreen> {
SettingModel? settings;
final String subject = 'Soporte Prosapp';
final String body = '';
Future<void> _sendWhatsapp(String? number) async {
final _whatsappUrl =
@@ -26,8 +29,8 @@ class SsupportStateScreen extends State<SupportScreen> {
Future<void> _sendEmail(String recipients) async {
final Email email = Email(
body: '',
subject: 'Soporte Prosapp',
body: body,
subject: subject,
recipients: [recipients],
isHTML: false,
);
@@ -35,6 +38,17 @@ class SsupportStateScreen extends State<SupportScreen> {
await FlutterEmailSender.send(email);
}
void _sendEmailWeb(String recipients) async {
final email =
'mailto:$recipients?subject=${Uri.encodeComponent(recipients)}&body=${Uri.encodeComponent(body)}';
if (await canLaunch(email)) {
await launch(email);
} else {
// No se pudo abrir el cliente de correo electrónico
// Puedes mostrar un diálogo o realizar otra acción en este caso
}
}
@override
void initState() {
super.initState();
@@ -98,7 +112,11 @@ class SsupportStateScreen extends State<SupportScreen> {
const SizedBox(width: 20),
ElevatedButton(
onPressed: () {
_sendEmail(settings?.email ?? '');
if (kIsWeb) {
_sendEmailWeb(settings?.email ?? '');
} else {
_sendEmail(settings?.email ?? '');
}
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
@@ -6,6 +6,7 @@ import FlutterMacOS
import Foundation
import cloud_firestore
import device_info_plus
import file_selector_macos
import firebase_auth
import firebase_core
@@ -17,6 +18,7 @@ import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
+24
View File
@@ -129,6 +129,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.8"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b"
url: "https://pub.dev"
source: hosted
version: "9.0.2"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
url: "https://pub.dev"
source: hosted
version: "7.0.0"
diacritic:
dependency: "direct main"
description:
@@ -1037,6 +1053,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.3"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9
url: "https://pub.dev"
source: hosted
version: "1.1.1"
xdg_directories:
dependency: transitive
description:
+1
View File
@@ -66,6 +66,7 @@ dependencies:
flutter_local_notifications: ^14.1.1
http: ^0.13.5
flutter_dialogs: ^3.0.0
device_info_plus: ^9.0.2
dev_dependencies:
flutter_test: