chat primera face

This commit is contained in:
Juan Felipe Duarte
2023-05-03 17:07:26 -05:00
parent f1571e6374
commit 1a0e33328e
16 changed files with 785 additions and 95 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

+4 -1
View File
@@ -8,10 +8,11 @@ import 'package:prosappco/src/screens/city.dart';
import 'package:prosappco/src/screens/login.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:prosappco/src/screens/login_email.dart';
import 'package:prosappco/src/screens/my_services.dart';
import 'package:prosappco/src/screens/my_services_pro.dart';
import 'package:prosappco/src/screens/new_number.dart';
import 'package:prosappco/src/screens/new_password.dart';
import 'package:prosappco/src/screens/profession.dart';
import 'package:prosappco/src/screens/professional.dart';
import 'package:prosappco/src/screens/professional_profile.dart';
import 'package:prosappco/src/screens/professional_revision.dart';
import 'package:prosappco/src/screens/profile.dart';
@@ -63,6 +64,8 @@ class MyApp extends StatelessWidget {
'/profilePro': (context) => const ProfilePro(),
'/calendar': (context) => const CalendarScreen(),
'/solicitud': (context) => SolicitudScreen(),
'/misserviciospro': (context) => MyServicesProScreen(),
'/misservicios': (context) => MyServicesScreen(),
},
onGenerateRoute: (settings) {
throw Exception('Ruta desconocida: ${settings.name}');
+8 -2
View File
@@ -7,7 +7,6 @@ import 'package:prosappco/src/components/photo_view.dart';
import 'package:prosappco/src/models/scores_model.dart';
import 'package:prosappco/src/models/user_model.dart';
import 'package:prosappco/src/screens/profile.dart';
import 'package:prosappco/src/screens/solicitudes.dart';
class DrawerMenu extends StatefulWidget {
@override
@@ -106,7 +105,14 @@ class _DrawerMenuState extends State<DrawerMenu> {
child: Column(
children: [
ListTile(
onTap: () {},
onTap: () {
if (ModalRoute.of(context)?.settings.name !=
'/misservicios') {
Navigator.pushNamed(context, '/misservicios');
} else {
Scaffold.of(context).openEndDrawer();
}
},
leading: const Icon(
Icons.history,
color: Colors.black,
+8 -1
View File
@@ -112,7 +112,14 @@ class _DrawerProfessionalState extends State<DrawerProfessional> {
child: Column(
children: [
ListTile(
onTap: () {},
onTap: () {
if (ModalRoute.of(context)?.settings.name !=
'/misserviciospro') {
Navigator.pushNamed(context, '/misserviciospro');
} else {
Scaffold.of(context).openEndDrawer();
}
},
leading: const Icon(
Icons.history,
color: Colors.black,
+37
View File
@@ -0,0 +1,37 @@
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatModel {
List<MessageModel> messages;
ChatModel({required this.messages});
static ChatModel fromDocumentSnapshot(
DocumentSnapshot<Map<String, dynamic>> snapshot) {
try {
List<MessageModel> messages = [];
List<dynamic> messagesData = snapshot.get('message') ?? [];
for (var data in messagesData) {
messages.add(MessageModel(
user: data['user'] ?? '',
content: data['content'] ?? '',
timestamp: (data['timestamp'] as Timestamp).toDate(),
));
}
return ChatModel(messages: messages);
} catch (e) {
print('error $e');
return ChatModel(messages: []);
}
}
}
class MessageModel {
String user;
String content;
DateTime timestamp;
MessageModel(
{required this.user, required this.content, required this.timestamp});
}
+32 -2
View File
@@ -16,6 +16,7 @@ class EventoService {
String address,
double latitude,
double longitude,
String status,
) async {
try {
DateTime ahora = DateTime.now();
@@ -33,6 +34,7 @@ class EventoService {
'address': address,
'latitude': latitude,
'longitude': longitude,
'status': status,
'Timestamp': ahora
}).then((value) {
FirebaseFirestore.instance.collection('users').doc(uid).update({
@@ -72,17 +74,18 @@ Future<List<Event>> getByProId(String day) async {
}
}
Future<List<Event>> getByProIdAll() async {
Future<List<Event>> getByProIdAll(String state1, String state2) async {
try {
var snapshot = await FirebaseFirestore.instance
.collection('services')
.where('professional_id', isEqualTo: uid)
.get();
.where('status', whereIn: [state1, state2]).get();
List<Event> eventos = [];
for (var element in snapshot.docs) {
final event = Event.fromJson(element.data());
event.scoresModel = await ScoresModel.scoreTo(event.userId, false, false);
event.id = element.id;
eventos.add(event);
}
print('eventos $eventos');
@@ -94,6 +97,7 @@ Future<List<Event>> getByProIdAll() async {
}
class Event {
String? id;
String title;
String? description;
String day;
@@ -105,9 +109,11 @@ class Event {
String? address;
double? longitud;
double? latitud;
String status;
ScoresModel? scoresModel;
Event({
this.id,
required this.title,
this.description,
required this.day,
@@ -119,10 +125,12 @@ class Event {
this.address,
this.longitud,
this.latitud,
this.status = 'pendiente',
});
factory Event.fromJson(Map<String, dynamic> json) {
return Event(
id: json['id'] ?? '',
title: json['title'],
description: json['description'],
day: json['day'],
@@ -134,6 +142,7 @@ class Event {
address: json['address'] ?? '',
longitud: json['longitude'] ?? 0,
latitud: json['latitude'] ?? 0,
status: json['status'],
);
}
@@ -170,4 +179,25 @@ class Event {
return [];
}
}
static Future<List<Event>> getEventsAllByIdStatus(
String uid, String state) async {
try {
var snapshot = await FirebaseFirestore.instance
.collection('services')
.where('professional_id', isEqualTo: uid)
.where('status', isEqualTo: state)
.get();
List<Event> eventos = [];
for (var element in snapshot.docs) {
eventos.add(Event.fromJson(element.data()));
}
print('eventos $eventos');
return eventos;
} catch (e) {
print('Error getByProId $e');
return [];
}
}
}
+33
View File
@@ -0,0 +1,33 @@
import 'package:cloud_firestore/cloud_firestore.dart';
class SettingModel {
final bool domicilios;
SettingModel(this.domicilios);
static Future<SettingModel> fromJson(Map<String, dynamic> json) async {
try {
if (json == null) return SettingModel(false);
return SettingModel(json['habilitado']);
} catch (e) {
print('Error settings: $e');
return SettingModel(false);
}
}
static Future<SettingModel> getDomiciliosSettings() async {
try {
final DocumentSnapshot<Map<String, dynamic>> snapshot =
await FirebaseFirestore.instance
.collection('settings')
.doc('domicilios')
.get();
final Map<String, dynamic>? data = snapshot.data();
return fromJson(data!);
} catch (e) {
print('Error getting settings: $e');
return SettingModel(false);
}
}
}
+8 -5
View File
@@ -61,9 +61,10 @@ class _CalendarScreenState extends State<CalendarScreen> {
super.initState();
if (_events == null) {
Event.getEventsAllById(uid ?? "").then((value) => setState(() {
_events = value;
}));
Event.getEventsAllByIdStatus(uid ?? "", 'aprobado')
.then((value) => setState(() {
_events = value;
}));
}
}
@@ -293,14 +294,16 @@ class _CalendarScreenState extends State<CalendarScreen> {
'',
'',
0,
0)
0,
'aprobado')
.then((value) {
Navigator.pop(context);
_titleController.text = '';
_descriptionController.text = '';
});
Event.getEventsAllById(uid ?? "").then(
Event.getEventsAllByIdStatus(uid ?? "", 'aprobado')
.then(
(value) => setState(() {
_events = value;
}),
+109
View File
@@ -0,0 +1,109 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/chat_model.dart';
class ChatScreen extends StatefulWidget {
final String eventoId;
const ChatScreen({super.key, required this.eventoId});
@override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final _textController = TextEditingController();
final uid = AuthenticationRepository.instance.getCurrentUserUid();
@override
Widget build(BuildContext context) {
String textoIngresado = _textController.text;
return Scaffold(
appBar: PopAppbar(
onPressed: () {
Navigator.pop(context);
},
label: 'Mensajes'),
body: Column(
children: [
StreamBuilder(
stream: FirebaseFirestore.instance
.collection('chats')
.doc(widget.eventoId)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
final data = snapshot.data!;
final chat = ChatModel.fromDocumentSnapshot(data);
print('messages ${chat.messages}');
return Column(children: [
...chat.messages.map(
(e) => ListTile(
title: RichText(
text: TextSpan(
children: [
TextSpan(
text: '${e.content}, ',
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,
// ),
// ),
],
),
),
),
)
]);
// ListTile(
// title: Text('${}'),
// );
},
),
TextFormField(
controller: _textController,
),
IconButton(
onPressed: () async {
final nuevoMensaje = MessageModel(
user: uid!,
content: _textController.text,
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();
},
icon: const Icon(Icons.send))
],
),
);
}
}
+108 -23
View File
@@ -1,5 +1,7 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:intl/intl.dart';
@@ -8,6 +10,7 @@ import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/models/scores_model.dart';
import 'package:prosappco/src/models/user_model.dart';
import 'package:prosappco/src/screens/chat.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:community_material_icon/community_material_icon.dart';
@@ -213,6 +216,44 @@ class _CitaScreenState extends State<CitaScreen> {
),
),
const SizedBox(width: 20),
ElevatedButton(
onPressed: () async {
await FirebaseFirestore.instance
.collection('chats')
.doc(widget.evento.id)
.set({});
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return ChatScreen(eventoId: widget.evento.id!);
},
),
);
},
style: ElevatedButton.styleFrom(
foregroundColor: const Color(0xFF2BA4EC),
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
side: const BorderSide(
color: Color(0xFF2BA4EC),
width: 2,
),
),
),
child: const Padding(
padding:
EdgeInsets.symmetric(vertical: 18, horizontal: 0),
child: Icon(
Icons.message,
size: 30,
color: Color(0xFF2BA4EC),
),
),
),
const SizedBox(width: 20),
ElevatedButton(
onPressed: () {
_sendWhatsapp();
@@ -280,32 +321,76 @@ class _CitaScreenState extends State<CitaScreen> {
child: Text('${widget.evento.address}'))
],
),
)
),
],
),
),
Padding(
padding: const EdgeInsets.only(bottom: 30),
child: ElevatedButton(
onPressed: () {},
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,
),
),
),
),
widget.evento.status == 'pendiendo'
? 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": "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,
),
),
),
),
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(),
],
),
);
+151
View File
@@ -0,0 +1,151 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:intl/intl.dart';
import 'package:prosappco/src/components/drawer_professional.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/screens/cita.dart';
class MyServicesScreen extends StatefulWidget {
MyServicesScreen({super.key});
@override
State<MyServicesScreen> createState() => _MyServicesScreenState();
}
class _MyServicesScreenState extends State<MyServicesScreen> {
DateTime today = DateTime.now();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PopAppbar(
onPressed: () {
Navigator.pop(context);
},
label: 'Mis servicios'),
drawer: DrawerProfessional(),
body: SingleChildScrollView(
child: Column(
children: [
_eventList(),
],
),
),
),
);
}
Widget _eventList() {
return FutureBuilder(
future: getByProIdAll('aprobado', 'denegado'),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
List<Event> eventos = [];
try {
eventos.addAll(snapshot.data!);
} catch (e) {
print("Error" + e.toString());
}
if (eventos.isEmpty) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 50),
child: Center(child: Text('No tienes citas')),
);
}
return Column(
children: [
...eventos.map(
(event) => ListTile(
tileColor: event.status == 'aprobado'
? Colors.green[100]
: Colors.red[100],
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
},
leading: Text(event.range1Hour1),
title: RichText(
text: TextSpan(
children: [
TextSpan(
text: '${event.title}, ',
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
TextSpan(
text: DateFormat('dd MMM', 'es')
.format(DateTime.parse(event.day)),
style: const TextStyle(
color: Colors.grey,
fontSize: 16,
),
),
],
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
RatingBar.builder(
initialRating: event.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),
Text(
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
],
),
Text(
'" ${event.description}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],
),
trailing: const Icon(Icons.keyboard_arrow_right),
),
),
],
);
},
);
}
}
+161
View File
@@ -0,0 +1,161 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:intl/intl.dart';
import 'package:prosappco/src/components/drawer_professional.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/screens/cita.dart';
class MyServicesProScreen extends StatefulWidget {
MyServicesProScreen({super.key});
@override
State<MyServicesProScreen> createState() => _MyServicesProScreenState();
}
class _MyServicesProScreenState extends State<MyServicesProScreen> {
DateTime today = DateTime.now();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PopAppbar(
onPressed: () {
Navigator.pop(context);
},
label: 'Mis servicios'),
drawer: DrawerProfessional(),
body: SingleChildScrollView(
child: Column(
children: [
_eventList(),
],
),
),
),
);
}
Widget _eventList() {
return FutureBuilder(
future: getByProIdAll('aprobado', 'denegado'),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
List<Event> eventos = [];
try {
eventos.addAll(snapshot.data!);
} catch (e) {
print("Error" + e.toString());
}
if (eventos.isEmpty) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 50),
child: Center(child: Text('No tienes citas')),
);
}
return Column(
children: [
...eventos.map(
(event) => ListTile(
tileColor: event.status == 'aprobado'
? Colors.blue[100]
: Colors.red[100],
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
},
leading: event.status == 'aprobado'
? const Icon(
Icons.check,
color: Colors.blue,
size: 40,
)
: const Icon(
Icons.close,
color: Colors.red,
size: 40,
),
title: RichText(
text: TextSpan(
children: [
TextSpan(
text: '${event.title}, ',
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
TextSpan(
text:
'${DateFormat('dd MMM', 'es').format(DateTime.parse(event.day))} - ${event.range1Hour1}',
style: const TextStyle(
color: Colors.grey,
fontSize: 16,
),
),
],
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
RatingBar.builder(
initialRating: event.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),
Text(
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
],
),
Text(
'" ${event.description}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],
),
trailing: const Icon(Icons.keyboard_arrow_right),
),
),
],
);
},
);
}
}
+30 -26
View File
@@ -3,7 +3,6 @@ import 'package:diacritic/diacritic.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/photo_view.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
@@ -171,28 +170,30 @@ class _ProfessionalScreenState extends State<ProfessionalScreen> {
_photo = await AuthenticationRepository.instance.getPhoto(user.id);
if (data['estado'] == 'activo') {
List<String> especializaciones;
if (user.id != uid) {
List<String> especializaciones;
especializaciones = (data['especializaciones'] as List<dynamic>)
.map((e) => e.toString())
.toList();
especializaciones = (data['especializaciones'] as List<dynamic>)
.map((e) => e.toString())
.toList();
if (widget.profession == data['profesion'] ||
widget.profession == '') {
Professional professional = Professional(
id: user.id,
name: data['name'],
professionName: data['profesion'],
cityName: data['city'],
professionalRef: storage.ref().child(_photo),
professionalEspecializado: especializaciones,
ubicacion: data['ubicacion'] ?? '',
realAddress: data['address'] ?? '',
latitude: data['latitude'] ?? 0,
longitude: data['longitude'] ?? 0,
scores: await ScoresModel.scoreTo(user.id, true, true),
);
professionals.add(professional);
if (widget.profession == data['profesion'] ||
widget.profession == '') {
Professional professional = Professional(
id: user.id,
name: data['name'],
professionName: data['profesion'],
cityName: data['city'],
professionalRef: storage.ref().child(_photo),
professionalEspecializado: especializaciones,
ubicacion: data['ubicacion'] ?? '',
realAddress: data['address'] ?? '',
latitude: data['latitude'] ?? 0,
longitude: data['longitude'] ?? 0,
scores: await ScoresModel.scoreTo(user.id, true, true),
);
professionals.add(professional);
}
}
}
}
@@ -211,13 +212,16 @@ class _ProfessionalScreenState extends State<ProfessionalScreen> {
setState(() {
if (_professionals != null) {
if (searchController.text.isEmpty) {
filteredProfessionals = _professionals!;
filteredProfessionals = _professionals!
.where((professional) => professional.id != uid)
.toList();
} else {
filteredProfessionals = _professionals!
.where((professional) => removeDiacritics(professional.name)
.toLowerCase()
.contains(
removeDiacritics(searchController.text.toLowerCase())))
.where((professional) =>
removeDiacritics(professional.name).toLowerCase().contains(
removeDiacritics(
searchController.text.toLowerCase())) &&
professional.id != uid)
.toList();
}
}
+20 -13
View File
@@ -1,7 +1,6 @@
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
@@ -9,10 +8,10 @@ import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/banner_photo.dart';
import 'package:prosappco/src/components/drawer_professional.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/components/primary_btn.dart';
import 'package:prosappco/src/components/schedule_picker.dart';
import 'package:prosappco/src/models/setting_model.dart';
import 'package:prosappco/src/screens/horario.dart';
import 'package:prosappco/src/screens/professional.dart';
import 'package:prosappco/src/screens/professional_direccion.dart';
@@ -41,12 +40,18 @@ class _ProfileProState extends State<ProfilePro> {
var _direccion = '...';
var _ubicacion = '...';
var _opcionalAddress = '...';
SettingModel? setting_domicilio;
Map<String, Schedule>? _horarios;
@override
void initState() {
super.initState();
if (setting_domicilio == null) {
SettingModel.getDomiciliosSettings().then(
(SettingModel value) => setState(() => setting_domicilio = value),
);
}
final uid = AuthenticationRepository.instance.getCurrentUserUid();
@@ -283,17 +288,19 @@ class _ProfileProState extends State<ProfilePro> {
),
),
),
const Divider(
color: Colors.white,
height: 12,
),
customSwitch(
'Servicio a domicilio',
domicilioValue,
(value) {
domicilioValue = value;
},
),
if (setting_domicilio?.domicilios == true)
const Divider(
color: Colors.white,
height: 12,
),
if (setting_domicilio?.domicilios == true)
customSwitch(
'Servicio a domicilio',
domicilioValue,
(value) {
domicilioValue = value;
},
),
const Divider(),
customSwitch(
'Servicio en sitio',
+73 -18
View File
@@ -1,4 +1,5 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:community_material_icon/community_material_icon.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
@@ -88,7 +89,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: now,
firstDate: DateTime(now.year),
firstDate: now,
lastDate: DateTime(now.year + 1),
// builder: (context, child) {
// return Theme(data: ThemeData.dark(), child: child!);
@@ -130,10 +131,19 @@ class _ServiceScreenState extends State<ServiceScreen> {
final FirebaseStorage storage = FirebaseStorage.instance;
final uid = AuthenticationRepository.instance.getCurrentUserUid();
BitmapDescriptor? _markerIcon;
@override
void initState() {
super.initState();
BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(48, 48)), 'images/pro_marke.png')
.then((icon) {
setState(() {
_markerIcon = icon;
});
});
try {
getUsersWithActiveStatus().then((value) {
for (var doc in value) {
@@ -142,6 +152,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
if (element['latitude'] != null && element['longitude'] != null) {
markers.add(
Marker(
icon: _markerIcon!,
markerId: MarkerId(doc.id),
position: LatLng(
element['latitude'],
@@ -448,7 +459,29 @@ class _ServiceScreenState extends State<ServiceScreen> {
width: 180,
child: TextFormField(
onTap: () {
_selectDate(context);
if (_profesionalController
.text.isNotEmpty) {
_selectDate(context);
} else {
final snackBar = SnackBar(
backgroundColor: Colors.blue,
content: const Text(
'Selecciona un profesional',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
elevation: 8.0,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
),
);
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
}
},
readOnly: true,
decoration: InputDecoration(
@@ -469,7 +502,29 @@ class _ServiceScreenState extends State<ServiceScreen> {
width: 140,
child: TextFormField(
onTap: () {
_selectTime(context);
if (_profesionalController
.text.isNotEmpty) {
_selectTime(context);
} else {
final snackBar = SnackBar(
backgroundColor: Colors.blue,
content: const Text(
'Selecciona un profesional',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
elevation: 8.0,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
),
);
ScaffoldMessenger.of(context)
.showSnackBar(snackBar);
}
},
readOnly: true,
decoration: const InputDecoration(
@@ -508,21 +563,21 @@ class _ServiceScreenState extends State<ServiceScreen> {
UserModel.getUser(uid.toString()).then((value) {
eventoService
.createEvent(
value.name,
_observacionController.text,
'${_selectedDate}Z',
_selectedTime!.format(context),
time2.format(context),
professionalId,
ubicacion,
_locationController.text,
ubicacion != 'sitio'
? coordinates.latitude
: professionalLatitude,
ubicacion != 'sitio'
? coordinates.longitude
: professionalLongitude,
)
value.name,
_observacionController.text,
'${_selectedDate}Z',
_selectedTime!.format(context),
time2.format(context),
professionalId,
ubicacion,
_locationController.text,
ubicacion != 'sitio'
? coordinates.latitude
: professionalLatitude,
ubicacion != 'sitio'
? coordinates.longitude
: professionalLongitude,
'pendiente')
.then((value) {
Navigator.push(
context,
+3 -4
View File
@@ -4,7 +4,6 @@ import 'package:flutter_rating_bar/flutter_rating_bar.dart';
import 'package:intl/intl.dart';
import 'package:prosappco/src/components/drawer_professional.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/models/scores_model.dart';
import 'package:prosappco/src/screens/cita.dart';
class SolicitudScreen extends StatefulWidget {
@@ -52,7 +51,7 @@ class _SolicitudScreenState extends State<SolicitudScreen> {
Widget _eventList() {
return FutureBuilder(
future: getByProIdAll(),
future: getByProIdAll('pendiente', ''),
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
if (!snapshot.hasData) {
return const Center(
@@ -135,11 +134,11 @@ class _SolicitudScreenState extends State<SolicitudScreen> {
),
const SizedBox(width: 5),
Text(
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
],
),
Text(
'" ${event.description} "',
'" ${event.description}"',
style: const TextStyle(fontStyle: FontStyle.italic),
),
],