servicios
This commit is contained in:
@@ -19,7 +19,6 @@ import 'package:prosappco/src/screens/profile_pro.dart';
|
|||||||
import 'package:prosappco/src/screens/register.dart';
|
import 'package:prosappco/src/screens/register.dart';
|
||||||
import 'package:prosappco/src/screens/request_sent.dart';
|
import 'package:prosappco/src/screens/request_sent.dart';
|
||||||
import 'package:prosappco/src/screens/service.dart';
|
import 'package:prosappco/src/screens/service.dart';
|
||||||
|
|
||||||
import 'firebase_options.dart';
|
import 'firebase_options.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
@@ -60,7 +59,6 @@ class MyApp extends StatelessWidget {
|
|||||||
'/solicitudEnviada': (context) => const RequestSentScreen(),
|
'/solicitudEnviada': (context) => const RequestSentScreen(),
|
||||||
'/nuevaPassword': (context) => NewPasswordScreen(),
|
'/nuevaPassword': (context) => NewPasswordScreen(),
|
||||||
'/servicio': (context) => const ServiceScreen(),
|
'/servicio': (context) => const ServiceScreen(),
|
||||||
'/profesional': (context) => const ProfessionalScreen(),
|
|
||||||
'/profilePro': (context) => const ProfilePro(),
|
'/profilePro': (context) => const ProfilePro(),
|
||||||
'/calendar': (context) => const CalendarScreen(),
|
'/calendar': (context) => const CalendarScreen(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,13 +4,8 @@ import 'package:prosappco/src/authentication/authentication_repository.dart';
|
|||||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||||
|
|
||||||
class EventoService {
|
class EventoService {
|
||||||
Future<void> createEvent(
|
Future<void> createEvent(String title, String description, String day,
|
||||||
String title,
|
String range1Hour1, String range1Hour2, String professionalId) async {
|
||||||
String description,
|
|
||||||
String day,
|
|
||||||
String range1Hour1,
|
|
||||||
String range1Hour2,
|
|
||||||
) async {
|
|
||||||
try {
|
try {
|
||||||
await FirebaseFirestore.instance.collection('services').add({
|
await FirebaseFirestore.instance.collection('services').add({
|
||||||
'user_id': uid,
|
'user_id': uid,
|
||||||
@@ -18,7 +13,8 @@ class EventoService {
|
|||||||
'description': description,
|
'description': description,
|
||||||
'day': day,
|
'day': day,
|
||||||
'range1Hour1': range1Hour1,
|
'range1Hour1': range1Hour1,
|
||||||
'range1Hour2': range1Hour2
|
'range1Hour2': range1Hour2,
|
||||||
|
'professional_id': professionalId
|
||||||
}).then((value) {
|
}).then((value) {
|
||||||
FirebaseFirestore.instance.collection('users').doc(uid).update({
|
FirebaseFirestore.instance.collection('users').doc(uid).update({
|
||||||
'services': FieldValue.arrayUnion([value.id])
|
'services': FieldValue.arrayUnion([value.id])
|
||||||
@@ -34,7 +30,7 @@ Future<List<Event>> getByProId(String day) async {
|
|||||||
try {
|
try {
|
||||||
var snapshot = await FirebaseFirestore.instance
|
var snapshot = await FirebaseFirestore.instance
|
||||||
.collection('services')
|
.collection('services')
|
||||||
.where('user_id', isEqualTo: uid)
|
.where('professional_id', isEqualTo: uid)
|
||||||
.where('day', isEqualTo: day.toString())
|
.where('day', isEqualTo: day.toString())
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
@@ -57,6 +53,7 @@ class Event {
|
|||||||
String? range1Hour1;
|
String? range1Hour1;
|
||||||
String? range1Hour2;
|
String? range1Hour2;
|
||||||
String? userId;
|
String? userId;
|
||||||
|
String? professionalId;
|
||||||
|
|
||||||
Event({
|
Event({
|
||||||
this.title,
|
this.title,
|
||||||
@@ -65,6 +62,7 @@ class Event {
|
|||||||
this.range1Hour1,
|
this.range1Hour1,
|
||||||
this.range1Hour2,
|
this.range1Hour2,
|
||||||
this.userId,
|
this.userId,
|
||||||
|
this.professionalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Event.fromJson(Map<String, dynamic> json) {
|
factory Event.fromJson(Map<String, dynamic> json) {
|
||||||
@@ -75,6 +73,7 @@ class Event {
|
|||||||
range1Hour1: json['range1Hour1'],
|
range1Hour1: json['range1Hour1'],
|
||||||
range1Hour2: json['range1Hour2'],
|
range1Hour2: json['range1Hour2'],
|
||||||
userId: json['user_id'],
|
userId: json['user_id'],
|
||||||
|
professionalId: json['professional_id'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ class Event {
|
|||||||
try {
|
try {
|
||||||
var snapshot = await FirebaseFirestore.instance
|
var snapshot = await FirebaseFirestore.instance
|
||||||
.collection('services')
|
.collection('services')
|
||||||
.where('user_id', isEqualTo: uid)
|
.where('professional_id', isEqualTo: uid)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
List<Event> eventos = [];
|
List<Event> eventos = [];
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
import 'package:prosappco/src/models/event_model.dart';
|
import 'package:prosappco/src/models/event_model.dart';
|
||||||
|
import 'package:prosappco/src/models/scores_model.dart';
|
||||||
import 'package:prosappco/src/screens/cita.dart';
|
import 'package:prosappco/src/screens/cita.dart';
|
||||||
import 'package:table_calendar/table_calendar.dart';
|
import 'package:table_calendar/table_calendar.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -22,6 +24,8 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
|||||||
final _titleController = TextEditingController();
|
final _titleController = TextEditingController();
|
||||||
final _descriptionController = TextEditingController();
|
final _descriptionController = TextEditingController();
|
||||||
|
|
||||||
|
ScoresModel? scoresModel;
|
||||||
|
|
||||||
EventoService eventoService = EventoService();
|
EventoService eventoService = EventoService();
|
||||||
CalendarFormat _calendarFormat = CalendarFormat.month;
|
CalendarFormat _calendarFormat = CalendarFormat.month;
|
||||||
DateTime today = DateTime.now();
|
DateTime today = DateTime.now();
|
||||||
@@ -63,6 +67,12 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
|||||||
_events = value;
|
_events = value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scoresModel == null) {
|
||||||
|
ScoresModel.scoreFrom(uid.toString(), false).then(
|
||||||
|
(ScoresModel s) => setState(() => scoresModel = s),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onDaySelected(DateTime day, DateTime focusedDay) {
|
void _onDaySelected(DateTime day, DateTime focusedDay) {
|
||||||
@@ -287,6 +297,7 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
|||||||
today.toString(),
|
today.toString(),
|
||||||
_selectedTime1!.format(context).toString(),
|
_selectedTime1!.format(context).toString(),
|
||||||
_selectedTime2!.format(context).toString(),
|
_selectedTime2!.format(context).toString(),
|
||||||
|
uid.toString(),
|
||||||
)
|
)
|
||||||
.then((value) {
|
.then((value) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@@ -380,8 +391,34 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
|||||||
subtitle: Column(
|
subtitle: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('${e.description}'),
|
Row(
|
||||||
Text('${e.description}'),
|
children: [
|
||||||
|
RatingBar.builder(
|
||||||
|
initialRating: 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(
|
||||||
|
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toString()}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'" ${e.description} "',
|
||||||
|
style: const TextStyle(fontStyle: FontStyle.italic),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class _CitaScreenState extends State<CitaScreen> {
|
|||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
children: [
|
children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text: '${nombre}, ',
|
text: '$nombre, ',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -84,7 +84,7 @@ class _CitaScreenState extends State<CitaScreen> {
|
|||||||
TextSpan(
|
TextSpan(
|
||||||
text:
|
text:
|
||||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day!))} ${widget.evento.range1Hour1}',
|
'${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day!))} ${widget.evento.range1Hour1}',
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
@@ -119,7 +119,7 @@ class _CitaScreenState extends State<CitaScreen> {
|
|||||||
Text(
|
Text(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
'" ${widget.evento.description} "',
|
'" ${widget.evento.description} "',
|
||||||
style: TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.grey, fontStyle: FontStyle.italic),
|
color: Colors.grey, fontStyle: FontStyle.italic),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -120,14 +120,15 @@ class _HorarioScreenState extends State<HorarioScreen> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 30, bottom: 30),
|
padding: const EdgeInsets.only(top: 30, bottom: 30),
|
||||||
child: PrimaryButtom(
|
child: PrimaryButtom(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
updateHorario().then((value) => Navigator.pushReplacement(
|
updateHorario().then((value) => Navigator.pushReplacement(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => const ProfilePro()),
|
builder: (context) => const ProfilePro()),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
label: 'Guardar'),
|
label: 'Guardar',
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import 'package:prosappco/src/screens/professional_info.dart';
|
|||||||
import '../models/scores_model.dart';
|
import '../models/scores_model.dart';
|
||||||
|
|
||||||
class ProfessionalScreen extends StatefulWidget {
|
class ProfessionalScreen extends StatefulWidget {
|
||||||
const ProfessionalScreen({super.key});
|
final String profession;
|
||||||
|
const ProfessionalScreen({super.key, required this.profession});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ProfessionalScreen> createState() => _ProfessionalScreenState();
|
State<ProfessionalScreen> createState() => _ProfessionalScreenState();
|
||||||
@@ -24,6 +25,7 @@ final CollectionReference usersCollection =
|
|||||||
var _photo = '...';
|
var _photo = '...';
|
||||||
|
|
||||||
class Professional {
|
class Professional {
|
||||||
|
final String id;
|
||||||
final Reference professionalRef;
|
final Reference professionalRef;
|
||||||
final String name;
|
final String name;
|
||||||
final String professionName;
|
final String professionName;
|
||||||
@@ -33,6 +35,7 @@ class Professional {
|
|||||||
final ScoresModel scores;
|
final ScoresModel scores;
|
||||||
|
|
||||||
Professional({
|
Professional({
|
||||||
|
required this.id,
|
||||||
required this.professionalRef,
|
required this.professionalRef,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.professionName,
|
required this.professionName,
|
||||||
@@ -78,6 +81,7 @@ class Professional {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Professional professional = Professional(
|
Professional professional = Professional(
|
||||||
|
id: user.id,
|
||||||
name: data['name'],
|
name: data['name'],
|
||||||
professionName: data['profesion'],
|
professionName: data['profesion'],
|
||||||
cityName: data['city'],
|
cityName: data['city'],
|
||||||
@@ -95,44 +99,6 @@ class Professional {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Professional>> getProfessionals() async {
|
|
||||||
List<Professional> professionals = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
QuerySnapshot users = await usersCollection.get();
|
|
||||||
for (DocumentSnapshot user in users.docs) {
|
|
||||||
// Acceder a los datos de cada usuario
|
|
||||||
Map<String, dynamic> data = user.data() as Map<String, dynamic>;
|
|
||||||
|
|
||||||
// Crear un objeto Professional a partir de los datos del usuario
|
|
||||||
_photo = await AuthenticationRepository.instance.getPhoto(user.id);
|
|
||||||
|
|
||||||
if (data['estado'] == 'activo') {
|
|
||||||
List<String> especializaciones;
|
|
||||||
|
|
||||||
especializaciones = (data['especializaciones'] as List<dynamic>)
|
|
||||||
.map((e) => e.toString())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
Professional professional = Professional(
|
|
||||||
name: data['name'],
|
|
||||||
professionName: data['profesion'],
|
|
||||||
cityName: data['city'],
|
|
||||||
professionalRef: storage.ref().child(_photo),
|
|
||||||
professionalEspecializado: especializaciones,
|
|
||||||
ubicacion: data['ubicacion'] ?? '',
|
|
||||||
scores: await ScoresModel.scoreTo(user.id, true, true),
|
|
||||||
);
|
|
||||||
professionals.add(professional);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
print('Error al obtener profesionales: $e');
|
|
||||||
}
|
|
||||||
|
|
||||||
return professionals;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
||||||
List<Professional>? filteredProfessionals;
|
List<Professional>? filteredProfessionals;
|
||||||
|
|
||||||
@@ -141,9 +107,52 @@ class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
|||||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||||
List<Professional>? _professionals;
|
List<Professional>? _professionals;
|
||||||
|
|
||||||
|
Future<List<Professional>> getProfessionals() async {
|
||||||
|
List<Professional> professionals = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
QuerySnapshot users = await usersCollection.get();
|
||||||
|
for (DocumentSnapshot user in users.docs) {
|
||||||
|
// Acceder a los datos de cada usuario
|
||||||
|
Map<String, dynamic> data = user.data() as Map<String, dynamic>;
|
||||||
|
|
||||||
|
// Crear un objeto Professional a partir de los datos del usuario
|
||||||
|
_photo = await AuthenticationRepository.instance.getPhoto(user.id);
|
||||||
|
|
||||||
|
if (data['estado'] == 'activo') {
|
||||||
|
List<String> especializaciones;
|
||||||
|
|
||||||
|
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'] ?? '',
|
||||||
|
scores: await ScoresModel.scoreTo(user.id, true, true),
|
||||||
|
);
|
||||||
|
professionals.add(professional);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('Error al obtener profesionales: $e');
|
||||||
|
}
|
||||||
|
|
||||||
|
return professionals;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
searchController.addListener(() {
|
searchController.addListener(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_professionals != null) {
|
if (_professionals != null) {
|
||||||
@@ -257,7 +266,7 @@ class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// Navigator.pop(context, professionals[index]);
|
Navigator.pop(context, professionals[index]);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import 'package:firebase_storage/firebase_storage.dart';
|
import 'package:firebase_storage/firebase_storage.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@@ -10,8 +10,11 @@ import 'package:get/get.dart';
|
|||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/drawer_menu.dart';
|
import 'package:prosappco/src/components/drawer_menu.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.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:prosappco/src/screens/service_type.dart';
|
||||||
|
|
||||||
class ServiceScreen extends StatefulWidget {
|
class ServiceScreen extends StatefulWidget {
|
||||||
const ServiceScreen({super.key});
|
const ServiceScreen({super.key});
|
||||||
@@ -21,9 +24,16 @@ class ServiceScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ServiceScreenState extends State<ServiceScreen> {
|
class _ServiceScreenState extends State<ServiceScreen> {
|
||||||
|
EventoService eventoService = EventoService();
|
||||||
|
|
||||||
final TextEditingController _locationController = TextEditingController();
|
final TextEditingController _locationController = TextEditingController();
|
||||||
final String _locationPosition = '';
|
final String _locationPosition = '';
|
||||||
|
final _profesionalController = TextEditingController();
|
||||||
|
final _serviceTypeController = TextEditingController();
|
||||||
|
final _observacionController = TextEditingController();
|
||||||
|
var professionalId = '';
|
||||||
|
String _serviceType = 'Servicio';
|
||||||
|
String _professional = '';
|
||||||
final DateFormat formatter = DateFormat('dd/MM/yyyy');
|
final DateFormat formatter = DateFormat('dd/MM/yyyy');
|
||||||
final DateTime now = DateTime.now();
|
final DateTime now = DateTime.now();
|
||||||
|
|
||||||
@@ -32,7 +42,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
|
|
||||||
late GoogleMapController googleMapController;
|
late GoogleMapController googleMapController;
|
||||||
|
|
||||||
static const CameraPosition initialCameraPosition = CameraPosition(
|
static CameraPosition initialCameraPosition = const CameraPosition(
|
||||||
target: LatLng(7.8939100, -72.5078200),
|
target: LatLng(7.8939100, -72.5078200),
|
||||||
zoom: 14.4746,
|
zoom: 14.4746,
|
||||||
);
|
);
|
||||||
@@ -130,9 +140,6 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<String> opc = ["Servicio", "Opción 1", "Opción 2", "Opción 3"];
|
|
||||||
String defaultValue = opc[0];
|
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: const Color(0xFFD6F4FF),
|
backgroundColor: const Color(0xFFD6F4FF),
|
||||||
@@ -218,7 +225,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
// markers.clear();
|
// markers.clear();
|
||||||
|
|
||||||
// markers.add(Marker(
|
// markers.add(Marker(
|
||||||
// markerId: const MarkerId('currentLocation'),
|
// markerId: MarkerId('currentLocation'),
|
||||||
// position:
|
// position:
|
||||||
// LatLng(position.latitude, position.longitude)));
|
// LatLng(position.latitude, position.longitude)));
|
||||||
},
|
},
|
||||||
@@ -254,54 +261,56 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.only(top: 23, left: 100, right: 25),
|
const EdgeInsets.only(top: 22, left: 100, right: 25),
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(50),
|
borderRadius: BorderRadius.circular(50),
|
||||||
|
color: Colors.white,
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.withOpacity(0.4),
|
color: Colors.grey.withOpacity(0.4),
|
||||||
spreadRadius: 1,
|
spreadRadius: 1,
|
||||||
blurRadius: 2,
|
blurRadius: 2,
|
||||||
offset: const Offset(
|
offset: const Offset(1, 2),
|
||||||
1, 2), // changes position of shadow
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: DropdownButtonFormField(
|
child: Padding(
|
||||||
value: defaultValue,
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
elevation: 0,
|
child: TextFormField(
|
||||||
decoration: InputDecoration(
|
onTap: () async {
|
||||||
filled: true,
|
final String? serviceType = await Navigator.push(
|
||||||
fillColor: Colors.white,
|
context,
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
CupertinoPageRoute(
|
||||||
horizontal: 16, vertical: 8),
|
builder: (BuildContext context) {
|
||||||
border: OutlineInputBorder(
|
return const ServiceTypeScreen();
|
||||||
borderRadius: BorderRadius.circular(50),
|
},
|
||||||
borderSide: BorderSide.none,
|
),
|
||||||
|
) as String?;
|
||||||
|
|
||||||
|
if (serviceType != null) {
|
||||||
|
setState(() {
|
||||||
|
_serviceType = serviceType;
|
||||||
|
_serviceTypeController.text = _serviceType;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
controller: _serviceTypeController,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.black87,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
readOnly: true,
|
||||||
borderRadius: BorderRadius.circular(50),
|
decoration: InputDecoration(
|
||||||
borderSide: BorderSide.none,
|
hintText:
|
||||||
),
|
_serviceType == '' ? 'Servicio' : _serviceType,
|
||||||
focusedBorder: OutlineInputBorder(
|
hintStyle: const TextStyle(
|
||||||
borderRadius: BorderRadius.circular(50),
|
color: Colors.black87,
|
||||||
borderSide: BorderSide.none,
|
fontWeight: FontWeight.w600),
|
||||||
|
border: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
items: opc.map((e) {
|
|
||||||
return DropdownMenuItem(
|
|
||||||
value: e,
|
|
||||||
child: Text(
|
|
||||||
e,
|
|
||||||
style:
|
|
||||||
const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
onChanged: (value) {
|
|
||||||
print(value);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -319,29 +328,35 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
|
readOnly: true,
|
||||||
controller: _locationController,
|
controller: _locationController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
prefixIcon: Icon(Icons.near_me),
|
prefixIcon: Icon(Icons.near_me),
|
||||||
hintText: 'Dirección'),
|
hintText: 'Dirección',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
// controller: _cedulaController,
|
controller: _profesionalController,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final String? profesional =
|
final Professional? profesional =
|
||||||
await Navigator.push(
|
await Navigator.push(
|
||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return const ProfessionalScreen();
|
return ProfessionalScreen(
|
||||||
|
profession: _serviceTypeController.text,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
) as String?;
|
);
|
||||||
|
|
||||||
if (profesional != null) {
|
if (profesional != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
// _profession = profesional;
|
_profesionalController.text =
|
||||||
|
profesional.name.toString();
|
||||||
|
professionalId = profesional.id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -396,14 +411,36 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
// controller: _cedulaController,
|
controller: _observacionController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
prefixIcon: Icon(Icons.message_outlined),
|
prefixIcon: Icon(Icons.message_outlined),
|
||||||
hintText: 'Observaciones'),
|
hintText: 'Observaciones'),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
int tiempo2 = ((_selectedTime!.hour * 3600 +
|
||||||
|
_selectedTime!.minute * 60) +
|
||||||
|
7200) %
|
||||||
|
86400;
|
||||||
|
|
||||||
|
int hora2 = tiempo2 ~/ 3600;
|
||||||
|
int minutos2 = (tiempo2 % 3600) ~/ 60;
|
||||||
|
|
||||||
|
TimeOfDay time2 =
|
||||||
|
TimeOfDay(hour: hora2, minute: minutos2);
|
||||||
|
|
||||||
|
UserModel.getUser(uid.toString()).then((value) {
|
||||||
|
eventoService.createEvent(
|
||||||
|
value.name,
|
||||||
|
_observacionController.text,
|
||||||
|
'${_selectedDate}Z',
|
||||||
|
_selectedTime!.format(context),
|
||||||
|
time2.format(context),
|
||||||
|
professionalId,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: const Color(0xFF2BA4EC),
|
backgroundColor: const Color(0xFF2BA4EC),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
import 'package:diacritic/diacritic.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
|
import 'package:prosappco/src/screens/profession.dart';
|
||||||
|
import 'package:prosappco/src/screens/service.dart';
|
||||||
|
|
||||||
|
class ServiceTypeScreen extends StatefulWidget {
|
||||||
|
const ServiceTypeScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ServiceTypeScreen> createState() => _ServiceTypeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ServiceTypeScreenState extends State<ServiceTypeScreen> {
|
||||||
|
List<String>? filteredProfessions;
|
||||||
|
TextEditingController searchController = TextEditingController();
|
||||||
|
List<String>? _professions;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
searchController.addListener(() {
|
||||||
|
setState(() {
|
||||||
|
if (_professions != null) {
|
||||||
|
if (searchController.text.isEmpty) {
|
||||||
|
filteredProfessions = _professions!;
|
||||||
|
} else {
|
||||||
|
filteredProfessions = _professions!
|
||||||
|
.where((profession) => removeDiacritics(profession)
|
||||||
|
.toLowerCase()
|
||||||
|
.contains(
|
||||||
|
removeDiacritics(searchController.text.toLowerCase())))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_professions == null) {
|
||||||
|
getProfessions().then((List<String> element) => setState(() {
|
||||||
|
_professions = element;
|
||||||
|
filteredProfessions = element;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (filteredProfessions == null) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFF2BA4EC)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var professions = filteredProfessions!;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: PopAppbar(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
label: 'Tipo de servicio'),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: TextField(
|
||||||
|
controller: searchController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: 'Escribe el tipo de servicio',
|
||||||
|
prefixIcon: Icon(Icons.assignment_ind_rounded),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: professions.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return ListTile(
|
||||||
|
title: Text(
|
||||||
|
professions[index],
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context, professions[index]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user