fix
This commit is contained in:
@@ -70,4 +70,5 @@ flutter {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation platform('com.google.firebase:firebase-bom:31.3.0')
|
||||
implementation 'com.google.firebase:firebase-analytics-ktx'
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
package="com.example.prosappco">
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.SENDTO" />
|
||||
<data android:scheme="mailto" />
|
||||
</intent>
|
||||
</queries>
|
||||
<application
|
||||
android:label="prosapp"
|
||||
android:name="${applicationName}"
|
||||
@@ -29,6 +35,9 @@
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
|
||||
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
|
||||
+3
-1
@@ -1,3 +1,4 @@
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -19,6 +20,7 @@ import 'package:prosappco/src/screens/profile.dart';
|
||||
import 'package:prosappco/src/screens/profile_pro.dart';
|
||||
import 'package:prosappco/src/screens/register.dart';
|
||||
import 'package:prosappco/src/screens/request_sent.dart';
|
||||
import 'package:prosappco/src/screens/score.dart';
|
||||
import 'package:prosappco/src/screens/service.dart';
|
||||
import 'package:prosappco/src/screens/solicitudes.dart';
|
||||
import 'firebase_options.dart';
|
||||
@@ -64,7 +66,7 @@ class MyApp extends StatelessWidget {
|
||||
'/profilePro': (context) => const ProfilePro(),
|
||||
'/calendar': (context) => const CalendarScreen(),
|
||||
'/solicitud': (context) => SolicitudScreen(),
|
||||
'/misserviciospro': (context) => MyServicesProScreen(),
|
||||
'/misserviciospro': (context) => const MyServicesProScreen(),
|
||||
'/misservicios': (context) => MyServicesScreen(),
|
||||
},
|
||||
onGenerateRoute: (settings) {
|
||||
|
||||
@@ -6,8 +6,11 @@ import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
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/configuracion.dart';
|
||||
import 'package:prosappco/src/screens/messages_user.dart';
|
||||
import 'package:prosappco/src/screens/profile.dart';
|
||||
import 'package:prosappco/src/screens/reputation.dart';
|
||||
import 'package:prosappco/src/screens/support.dart';
|
||||
|
||||
class DrawerMenu extends StatefulWidget {
|
||||
@override
|
||||
@@ -144,7 +147,16 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const ConfiguracionScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: const Icon(
|
||||
Icons.construction_outlined,
|
||||
color: Colors.black,
|
||||
@@ -155,7 +167,16 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const SupportScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: const Icon(
|
||||
Icons.question_mark_rounded,
|
||||
color: Colors.black,
|
||||
@@ -227,7 +248,16 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
||||
color: const Color(0xFFD6F4FF),
|
||||
child: ListTile(
|
||||
tileColor: const Color(0xFFD6F4FF),
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const ReputationScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
trailing: const Icon(Icons.keyboard_arrow_right,
|
||||
color: Colors.black),
|
||||
title: const Text(
|
||||
@@ -255,7 +285,7 @@ class _DrawerMenuState extends State<DrawerMenu> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toString()}'),
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -14,6 +14,8 @@ import 'package:prosappco/src/screens/profile_pro.dart';
|
||||
import 'package:prosappco/src/screens/reputation.dart';
|
||||
|
||||
import '../models/scores_model.dart';
|
||||
import '../screens/configuracion.dart';
|
||||
import '../screens/support.dart';
|
||||
|
||||
class DrawerProfessional extends StatefulWidget {
|
||||
@override
|
||||
@@ -153,7 +155,16 @@ class _DrawerProfessionalState extends State<DrawerProfessional> {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const ConfiguracionScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: const Icon(
|
||||
Icons.construction_outlined,
|
||||
color: Colors.black,
|
||||
@@ -164,7 +175,16 @@ class _DrawerProfessionalState extends State<DrawerProfessional> {
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const SupportScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: const Icon(
|
||||
Icons.question_mark_rounded,
|
||||
color: Colors.black,
|
||||
@@ -296,7 +316,7 @@ class _DrawerProfessionalState extends State<DrawerProfessional> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toString()}'),
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -17,6 +17,7 @@ class EventoService {
|
||||
double latitude,
|
||||
double longitude,
|
||||
String status,
|
||||
int? tarifa,
|
||||
) async {
|
||||
try {
|
||||
DateTime ahora = DateTime.now();
|
||||
@@ -35,7 +36,8 @@ class EventoService {
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'status': status,
|
||||
'Timestamp': ahora
|
||||
'Timestamp': ahora,
|
||||
'tarifa': tarifa ?? 0,
|
||||
}).then((value) {
|
||||
FirebaseFirestore.instance.collection('users').doc(uid).update({
|
||||
'services': FieldValue.arrayUnion([value.id])
|
||||
@@ -135,6 +137,7 @@ class Event {
|
||||
double? latitud;
|
||||
String status;
|
||||
ScoresModel? scoresModel;
|
||||
int? tarifa;
|
||||
|
||||
Event({
|
||||
this.id,
|
||||
@@ -150,6 +153,7 @@ class Event {
|
||||
this.longitud,
|
||||
this.latitud,
|
||||
this.status = 'pendiente',
|
||||
this.tarifa,
|
||||
});
|
||||
|
||||
factory Event.fromJson(Map<String, dynamic> json) {
|
||||
@@ -167,6 +171,7 @@ class Event {
|
||||
longitud: json['longitude'] ?? 0,
|
||||
latitud: json['latitude'] ?? 0,
|
||||
status: json['status'],
|
||||
tarifa: json['tarifa'] ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class ScoresModel {
|
||||
String userReceived, bool isFromClient, bool userInfo) async {
|
||||
final receivedScoresQuery = FirebaseFirestore.instance
|
||||
.collection('scores')
|
||||
.where('is_from_client', isEqualTo: isFromClient)
|
||||
.where('is_from_professional', isEqualTo: isFromClient)
|
||||
.where('to_user', isEqualTo: userReceived);
|
||||
|
||||
final receivedScoresSnapshot = await receivedScoresQuery.get();
|
||||
@@ -48,7 +48,7 @@ class ScoresModel {
|
||||
String userGiven, bool isFromClient, bool userInfo) async {
|
||||
final givenScoresQuery = FirebaseFirestore.instance
|
||||
.collection('scores')
|
||||
.where('is_from_client', isEqualTo: isFromClient)
|
||||
.where('is_from_professional', isEqualTo: isFromClient)
|
||||
.where('from_user', isEqualTo: userGiven);
|
||||
|
||||
final givenScoresSnapshot = await givenScoresQuery.get();
|
||||
@@ -101,7 +101,7 @@ class ScoreDetailModel {
|
||||
fromUser: data['from_user'],
|
||||
toUser: data['to_user'],
|
||||
comment: data['comment'],
|
||||
isFromClient: data['is_from_client'],
|
||||
isFromClient: data['is_from_professional'],
|
||||
name: user?.name ?? "...",
|
||||
avatar: user?.photo);
|
||||
} catch (e) {
|
||||
|
||||
@@ -3,17 +3,51 @@ import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
class SettingModel {
|
||||
final bool domicilios;
|
||||
final bool tarifas;
|
||||
final String titulo;
|
||||
final String parrafo;
|
||||
final String numero;
|
||||
final String email;
|
||||
final String dias;
|
||||
final String horas;
|
||||
final String version;
|
||||
final String proliticasPrivacidad;
|
||||
final String terminosCondiciones;
|
||||
|
||||
SettingModel(this.domicilios, this.tarifas);
|
||||
SettingModel(
|
||||
this.domicilios,
|
||||
this.tarifas,
|
||||
this.titulo,
|
||||
this.parrafo,
|
||||
this.numero,
|
||||
this.email,
|
||||
this.dias,
|
||||
this.horas,
|
||||
this.version,
|
||||
this.proliticasPrivacidad,
|
||||
this.terminosCondiciones,
|
||||
);
|
||||
|
||||
static Future<SettingModel> fromJson(Map<String, dynamic> json) async {
|
||||
try {
|
||||
if (json == null) return SettingModel(false, false);
|
||||
if (json == null)
|
||||
return SettingModel(false, false, '', '', '', '', '', '', '', '', '');
|
||||
|
||||
return SettingModel(json['domicilio'], json['tarifa']);
|
||||
return SettingModel(
|
||||
json['domicilio'],
|
||||
json['tarifa'],
|
||||
json['titulo_soporte'],
|
||||
json['parrafo_soporte'],
|
||||
json['numero_soporte'],
|
||||
json['email_soporte'],
|
||||
json['dias_soporte'],
|
||||
json['horas_soporte'],
|
||||
json['version'],
|
||||
json['politicas_privacidad'],
|
||||
json['terminos_condiciones'],
|
||||
);
|
||||
} catch (e) {
|
||||
print('Error settings: $e');
|
||||
return SettingModel(false, false);
|
||||
return SettingModel(false, false, '', '', '', '', '', '', '', '', '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +58,14 @@ class SettingModel {
|
||||
.collection('settings')
|
||||
.doc('global')
|
||||
.get();
|
||||
|
||||
final Map<String, dynamic>? data = snapshot.data();
|
||||
|
||||
print('data $data');
|
||||
return fromJson(data!);
|
||||
} catch (e) {
|
||||
print('Error getting settings: $e');
|
||||
return SettingModel(false, false);
|
||||
return SettingModel(false, false, '', '', '', '', '', '', '', '', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,25 +8,27 @@ class UserModel {
|
||||
final String? profession;
|
||||
final String? state;
|
||||
final Reference? photo;
|
||||
final int? tarifa;
|
||||
|
||||
UserModel(this.name, this.city, this.profession, this.state, this.photo);
|
||||
UserModel(this.name, this.city, this.profession, this.state, this.photo,
|
||||
this.tarifa);
|
||||
|
||||
static Future<UserModel> fromJson(
|
||||
Map<String, dynamic>? json, String uid) async {
|
||||
try {
|
||||
if (json == null) return UserModel('', '', '', null, null);
|
||||
if (json == null) return UserModel('', '', '', null, null, 0);
|
||||
|
||||
String? avatar = json['photo'];
|
||||
return UserModel(
|
||||
json['name'],
|
||||
json['city'],
|
||||
json['profesion'],
|
||||
json['estado'],
|
||||
avatar != null ? storage.ref().child(avatar) : null,
|
||||
);
|
||||
json['name'],
|
||||
json['city'],
|
||||
json['profesion'],
|
||||
json['estado'],
|
||||
avatar != null ? storage.ref().child(avatar) : null,
|
||||
json['tarifa'] ?? 0);
|
||||
} catch (e) {
|
||||
print('XD user $e');
|
||||
return UserModel('', '', '', null, null);
|
||||
return UserModel('', '', '', null, null, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +40,7 @@ class UserModel {
|
||||
return fromJson(data, uid);
|
||||
} catch (e) {
|
||||
print('Error getting user: $e');
|
||||
return UserModel('', '', '', null, null);
|
||||
return UserModel('', '', '', null, null, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/setting_model.dart';
|
||||
import 'package:prosappco/src/screens/web_view.dart';
|
||||
|
||||
class AboutScreen extends StatefulWidget {
|
||||
const AboutScreen({super.key});
|
||||
|
||||
@override
|
||||
State<AboutScreen> createState() => _AboutScreenState();
|
||||
}
|
||||
|
||||
class _AboutScreenState extends State<AboutScreen> {
|
||||
SettingModel? settings;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (settings == null) {
|
||||
SettingModel.getSettings().then(
|
||||
(SettingModel value) => setState(() {
|
||||
settings = value;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: 'Acerca de la aplicación'),
|
||||
body: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebViewScreen(
|
||||
label: 'Políticas de privacidad',
|
||||
link: settings?.proliticasPrivacidad ?? '',
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
title: const Text('Políticas de privacidad'),
|
||||
trailing:
|
||||
const Icon(Icons.keyboard_arrow_right, color: Colors.black),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return WebViewScreen(
|
||||
label: 'Términos y condiciones',
|
||||
link: settings?.terminosCondiciones ?? '',
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
title: const Text('Términos y condiciones'),
|
||||
trailing:
|
||||
const Icon(Icons.keyboard_arrow_right, color: Colors.black),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Versión de la aplicación'),
|
||||
subtitle: Text(settings?.version ?? ''),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/components/primary_btn.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:table_calendar/table_calendar.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -26,7 +25,10 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
||||
|
||||
EventoService eventoService = EventoService();
|
||||
CalendarFormat _calendarFormat = CalendarFormat.month;
|
||||
|
||||
DateTime today = DateTime.now();
|
||||
DateTime now = DateTime.now();
|
||||
|
||||
TimeOfDay? _selectedTime1;
|
||||
TimeOfDay? _selectedTime2;
|
||||
|
||||
@@ -283,19 +285,36 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
||||
),
|
||||
PrimaryButtom(
|
||||
onPressed: () async {
|
||||
final DateTime combinedDate1 = DateTime(
|
||||
today.year,
|
||||
today.month,
|
||||
today.day,
|
||||
_selectedTime1!.hour,
|
||||
_selectedTime1!.minute,
|
||||
);
|
||||
final DateTime combinedDate2 = DateTime(
|
||||
today.year,
|
||||
today.month,
|
||||
today.day,
|
||||
_selectedTime2!.hour,
|
||||
_selectedTime2!.minute,
|
||||
);
|
||||
|
||||
await eventoService
|
||||
.createEvent(
|
||||
_titleController.text,
|
||||
_descriptionController.text,
|
||||
today.toString(),
|
||||
_selectedTime1!.format(context).toString(),
|
||||
_selectedTime2!.format(context).toString(),
|
||||
uid.toString(),
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
'aprobado')
|
||||
_titleController.text,
|
||||
_descriptionController.text,
|
||||
DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(today),
|
||||
'$combinedDate1',
|
||||
'$combinedDate2',
|
||||
uid.toString(),
|
||||
'',
|
||||
'',
|
||||
0,
|
||||
0,
|
||||
'aprobado',
|
||||
0,
|
||||
)
|
||||
.then((value) {
|
||||
Navigator.pop(context);
|
||||
_titleController.text = '';
|
||||
@@ -323,8 +342,7 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
||||
|
||||
Widget _eventList() {
|
||||
return FutureBuilder(
|
||||
future:
|
||||
getByProId('${DateFormat("yyyy-MM-dd 00:00:00.000").format(today)}Z'),
|
||||
future: getByProId(DateFormat("yyyy-MM-dd 00:00:00.000").format(today)),
|
||||
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Text('No tiene citas');
|
||||
@@ -355,7 +373,9 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: Text(e.range1Hour1),
|
||||
leading: Text(
|
||||
TimeOfDay.fromDateTime(DateTime.parse(e.range1Hour1))
|
||||
.format(context)),
|
||||
title: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
@@ -402,7 +422,7 @@ class _CalendarScreenState extends State<CalendarScreen> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${e.scoresModel?.total.toString()}) ${e.scoresModel?.average.toString()}'),
|
||||
'(${e.scoresModel?.total.toString()}) ${e.scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -37,12 +37,6 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// if (scoresModel == null) {
|
||||
// ScoresModel.scoreTo(uid.toString(), false, false).then(
|
||||
// (ScoresModel s) => setState(() => scoresModel = s),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -62,7 +56,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
color: Colors.grey.withOpacity(0.3),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 2), // changes position of shadow
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
+151
-6
@@ -3,6 +3,7 @@ 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:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/photo_view.dart';
|
||||
@@ -11,6 +12,7 @@ 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:prosappco/src/screens/score.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:community_material_icon/community_material_icon.dart';
|
||||
|
||||
@@ -25,13 +27,20 @@ class CitaScreen extends StatefulWidget {
|
||||
class _CitaScreenState extends State<CitaScreen> {
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
UserModel? user;
|
||||
@override
|
||||
DateTime today = DateTime.now();
|
||||
String nombre = '';
|
||||
int tarifa = 0;
|
||||
Reference? ref_photo;
|
||||
ScoresModel? scoresModel;
|
||||
|
||||
final phoneNumber = '+573022548060';
|
||||
|
||||
String formatCurrency(int number) {
|
||||
final formatter =
|
||||
NumberFormat.currency(locale: 'es_CO', decimalDigits: 0, symbol: '');
|
||||
return '\$${formatter.format(number)}';
|
||||
}
|
||||
|
||||
Future<void> _openMap(double lat, double lng) async {
|
||||
final Uri _url =
|
||||
Uri.parse('https://www.google.com/maps/search/?api=1&query=$lat,$lng');
|
||||
@@ -73,17 +82,25 @@ class _CitaScreenState extends State<CitaScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
today.difference(DateTime.parse(widget.evento.range1Hour1));
|
||||
// DateTime todays = DateFormat('hh:mm a').parse(today.timeZoneName);
|
||||
final eventDate = DateFormat('yyyy-MM-dd').parse(widget.evento.day);
|
||||
|
||||
if (nombre == '') {
|
||||
if (uid != widget.evento.userId) {
|
||||
UserModel.getUser(widget.evento.userId).then((value) {
|
||||
setState(() {
|
||||
nombre = value.name;
|
||||
ref_photo = value.photo;
|
||||
UserModel.getUser(uid.toString()).then((me) {
|
||||
setState(() {
|
||||
tarifa = me.tarifa ?? 0;
|
||||
nombre = value.name;
|
||||
ref_photo = value.photo;
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
UserModel.getUser(widget.evento.professionalId).then((value) {
|
||||
setState(() {
|
||||
tarifa = value.tarifa ?? 0;
|
||||
nombre = value.name;
|
||||
ref_photo = value.photo;
|
||||
});
|
||||
@@ -122,7 +139,7 @@ class _CitaScreenState extends State<CitaScreen> {
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day))} ${widget.evento.range1Hour1}',
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day))} ${TimeOfDay.fromDateTime(DateTime.parse(widget.evento.range1Hour1)).format(context)}',
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontSize: 16,
|
||||
@@ -151,7 +168,7 @@ class _CitaScreenState extends State<CitaScreen> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toString()}'),
|
||||
'(${scoresModel?.total.toString()}) ${scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -194,6 +211,18 @@ class _CitaScreenState extends State<CitaScreen> {
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Text(
|
||||
formatCurrency(tarifa),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600, fontSize: 25),
|
||||
),
|
||||
Text('Tarifa consulta ${widget.evento.tarifa}',
|
||||
style: const TextStyle(fontSize: 15)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
textAlign: TextAlign.center,
|
||||
'" ${widget.evento.description} "',
|
||||
@@ -367,6 +396,80 @@ 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))
|
||||
? 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"});
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2BA4EC),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
elevation: 0,
|
||||
minimumSize: const Size(230, 60),
|
||||
),
|
||||
child: const Text(
|
||||
'Iniciar 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(),
|
||||
widget.evento.status == 'pendiente'
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30),
|
||||
@@ -433,6 +536,48 @@ class _CitaScreenState extends State<CitaScreen> {
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
widget.evento.status == 'iniciado'
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30),
|
||||
child: Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
FirebaseFirestore.instance
|
||||
.collection("services")
|
||||
.doc('${widget.evento.id}')
|
||||
.update({"status": "terminado"}).then((value) {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return ScoreScreen(evento: widget.evento);
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2BA4EC),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
elevation: 0,
|
||||
minimumSize: const Size(230, 60),
|
||||
),
|
||||
child: const Text(
|
||||
'Terminar servicio',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/screens/about.dart';
|
||||
|
||||
class ConfiguracionScreen extends StatelessWidget {
|
||||
const ConfiguracionScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: 'Configuración'),
|
||||
body: ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const AboutScreen();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
title: const Text('Acerca de la aplicación'),
|
||||
trailing: const Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.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';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.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/models/scores_model.dart';
|
||||
import 'package:prosappco/src/screens/cita.dart';
|
||||
|
||||
class MyServicesScreen extends StatefulWidget {
|
||||
@@ -16,6 +19,7 @@ class MyServicesScreen extends StatefulWidget {
|
||||
|
||||
class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
DateTime today = DateTime.now();
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -44,10 +48,32 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
}
|
||||
|
||||
Widget _eventList() {
|
||||
return FutureBuilder(
|
||||
future: getByUserIdAll('aprobado', 'denegado'),
|
||||
return StreamBuilder<List<Event>>(
|
||||
stream: FirebaseFirestore.instance
|
||||
.collection('services')
|
||||
.where('user_id', isEqualTo: uid)
|
||||
.where('status',
|
||||
whereIn: ['aprobado', 'denegado', 'iniciado', 'terminado'])
|
||||
.snapshots()
|
||||
.asyncMap((snapshot) async {
|
||||
try {
|
||||
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');
|
||||
return eventos;
|
||||
} catch (e) {
|
||||
print('Error getByProId $e');
|
||||
return [];
|
||||
}
|
||||
}),
|
||||
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
@@ -67,13 +93,14 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
child: Center(child: Text('No tienes citas')),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
...eventos.map(
|
||||
(event) => ListTile(
|
||||
tileColor: event.status == 'aprobado'
|
||||
? Colors.blue[100]
|
||||
: Colors.red[100],
|
||||
tileColor: event.status == 'denegado'
|
||||
? Colors.red[100]
|
||||
: Colors.blue[100],
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
@@ -90,11 +117,23 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
color: Colors.blue,
|
||||
size: 40,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
size: 40,
|
||||
),
|
||||
: event.status == 'iniciado'
|
||||
? const Icon(
|
||||
Icons.access_time,
|
||||
color: Colors.blue,
|
||||
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: [
|
||||
@@ -108,7 +147,7 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(event.day))} - ${event.range1Hour1}',
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(event.day))} - ${TimeOfDay.fromDateTime(DateTime.parse(event.range1Hour1)).format(context)}',
|
||||
style: TextStyle(
|
||||
color: Colors.grey[600],
|
||||
fontSize: 16,
|
||||
@@ -141,7 +180,7 @@ class _MyServicesScreenState extends State<MyServicesScreen> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
|
||||
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.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';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.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/models/scores_model.dart';
|
||||
import 'package:prosappco/src/screens/cita.dart';
|
||||
|
||||
class MyServicesProScreen extends StatefulWidget {
|
||||
MyServicesProScreen({super.key});
|
||||
const MyServicesProScreen({super.key});
|
||||
|
||||
@override
|
||||
State<MyServicesProScreen> createState() => _MyServicesProScreenState();
|
||||
@@ -15,6 +19,7 @@ class MyServicesProScreen extends StatefulWidget {
|
||||
|
||||
class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
DateTime today = DateTime.now();
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -43,10 +48,32 @@ class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
}
|
||||
|
||||
Widget _eventList() {
|
||||
return FutureBuilder(
|
||||
future: getByProIdAll('aprobado', 'denegado'),
|
||||
return StreamBuilder<List<Event>>(
|
||||
stream: FirebaseFirestore.instance
|
||||
.collection('services')
|
||||
.where('professional_id', isEqualTo: uid)
|
||||
.where('status',
|
||||
whereIn: ['aprobado', 'denegado', 'iniciado', 'terminado'])
|
||||
.snapshots()
|
||||
.asyncMap((snapshot) async {
|
||||
try {
|
||||
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');
|
||||
return eventos;
|
||||
} catch (e) {
|
||||
print('Error getByProId $e');
|
||||
return [];
|
||||
}
|
||||
}),
|
||||
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
@@ -66,24 +93,23 @@ class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
child: Center(child: Text('No tienes citas')),
|
||||
);
|
||||
}
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
...eventos.map(
|
||||
(event) => ListTile(
|
||||
tileColor: event.status == 'aprobado'
|
||||
? Colors.blue[100]
|
||||
: Colors.red[100],
|
||||
tileColor: event.status == 'denegado'
|
||||
? Colors.red[100]
|
||||
: Colors.blue[100],
|
||||
onTap: () {
|
||||
print(event.id);
|
||||
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// CupertinoPageRoute(
|
||||
// builder: (BuildContext context) {
|
||||
// return CitaScreen(evento: event);
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return CitaScreen(evento: event);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: event.status == 'aprobado'
|
||||
? const Icon(
|
||||
@@ -91,11 +117,17 @@ class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
color: Colors.blue,
|
||||
size: 40,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
size: 40,
|
||||
),
|
||||
: event.status == 'iniciado'
|
||||
? const Icon(
|
||||
Icons.access_time,
|
||||
color: Colors.blue,
|
||||
size: 40,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
size: 40,
|
||||
),
|
||||
title: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
@@ -109,7 +141,7 @@ class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
),
|
||||
TextSpan(
|
||||
text:
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(event.day))} - ${event.range1Hour1}',
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(event.day))} - ${TimeOfDay.fromDateTime(DateTime.parse(event.range1Hour1)).format(context)}',
|
||||
style: TextStyle(
|
||||
color: Colors.grey[600],
|
||||
fontSize: 16,
|
||||
@@ -142,7 +174,7 @@ class _MyServicesProScreenState extends State<MyServicesProScreen> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'),
|
||||
'(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -36,6 +36,7 @@ class Professional {
|
||||
final double longitude;
|
||||
final List<String> professionalEspecializado;
|
||||
final ScoresModel scores;
|
||||
final int? tarifa;
|
||||
|
||||
Professional({
|
||||
required this.id,
|
||||
@@ -49,6 +50,7 @@ class Professional {
|
||||
required this.realAddress,
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
this.tarifa,
|
||||
});
|
||||
|
||||
String getEspecializaciones() {
|
||||
@@ -90,18 +92,18 @@ class Professional {
|
||||
.toList();
|
||||
|
||||
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.scoreFrom(uid, true, true),
|
||||
);
|
||||
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.scoreFrom(uid, true, true),
|
||||
tarifa: data['tarifa'] ?? 0);
|
||||
return professional;
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -170,7 +170,7 @@ class _ProfessionalInfoScreenState extends State<ProfessionalInfoScreen> {
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
'(${widget.professional.scores.total.toString()}) ${widget.professional.scores.average.toString()}'),
|
||||
'(${widget.professional.scores.total.toString()}) ${widget.professional.scores.average.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
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/components/photo_view.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/scores_model.dart';
|
||||
|
||||
class ReputationProScreen extends StatefulWidget {
|
||||
const ReputationProScreen({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ReputationProScreen> createState() => _ReputationProScreenState();
|
||||
}
|
||||
|
||||
class _ReputationProScreenState extends State<ReputationProScreen> {
|
||||
ScoresModel? scoresModel;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
|
||||
if (scoresModel == null) {
|
||||
ScoresModel.scoreFrom(uid.toString(), false, true).then(
|
||||
(ScoresModel s) => setState(() => scoresModel = s),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: 'Reputación'),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
..._scoresList(scoresModel?.details ?? []),
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _scoresList(List<ScoreDetailModel> list) {
|
||||
return list.map((e) => _scoreItem(e)).toList();
|
||||
}
|
||||
|
||||
Widget _scoreItem(ScoreDetailModel scoreDetails) {
|
||||
return ListTile(
|
||||
onTap: () {},
|
||||
leading: ReferencePhoto(
|
||||
ref: scoreDetails.avatar,
|
||||
size: 50,
|
||||
sizeCircle: 50,
|
||||
sizeIcon: 35,
|
||||
),
|
||||
title: Row(
|
||||
children: [
|
||||
RatingBar.builder(
|
||||
initialRating: scoreDetails.score,
|
||||
minRating: 1,
|
||||
direction: Axis.horizontal,
|
||||
allowHalfRating: true,
|
||||
itemCount: 5,
|
||||
itemSize: 22,
|
||||
maxRating: 5,
|
||||
itemPadding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
itemBuilder: (context, _) => const Icon(
|
||||
Icons.star,
|
||||
color: Color(0xFF2BA4EC),
|
||||
),
|
||||
onRatingUpdate: (rating) {},
|
||||
ignoreGestures: true,
|
||||
),
|
||||
Text(
|
||||
' (${scoreDetails.score})',
|
||||
style: const TextStyle(color: Colors.black54, fontSize: 13),
|
||||
)
|
||||
],
|
||||
),
|
||||
subtitle: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${scoreDetails.name}, ',
|
||||
style: const TextStyle(fontSize: 15, color: Colors.black),
|
||||
),
|
||||
TextSpan(
|
||||
text: '"${scoreDetails.comment}"',
|
||||
style: const TextStyle(fontSize: 15, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,9 @@ import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/photo_view.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/scores_model.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
|
||||
class ReputationScreen extends StatefulWidget {
|
||||
ReputationScreen({
|
||||
const ReputationScreen({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -24,7 +23,7 @@ class _ReputationScreenState extends State<ReputationScreen> {
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
|
||||
if (scoresModel == null) {
|
||||
ScoresModel.scoreTo(uid.toString(), true, true).then(
|
||||
ScoresModel.scoreTo(uid.toString(), false, true).then(
|
||||
(ScoresModel s) => setState(() => scoresModel = s),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_storage/firebase_storage.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/photo_view.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/event_model.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
|
||||
class ScoreScreen extends StatefulWidget {
|
||||
final Event evento;
|
||||
|
||||
const ScoreScreen({super.key, required this.evento});
|
||||
|
||||
@override
|
||||
State<ScoreScreen> createState() => ScoreScreenState();
|
||||
}
|
||||
|
||||
class ScoreScreenState extends State<ScoreScreen> {
|
||||
TextEditingController commentController = TextEditingController();
|
||||
Reference? ref_photo;
|
||||
String nombre = '';
|
||||
double _rating = 1.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (nombre == '') {
|
||||
if (uid != widget.evento.userId) {
|
||||
UserModel.getUser(widget.evento.userId).then((value) {
|
||||
UserModel.getUser(uid.toString()).then((me) {
|
||||
setState(() {
|
||||
nombre = value.name;
|
||||
ref_photo = value.photo;
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
UserModel.getUser(widget.evento.professionalId).then((value) {
|
||||
setState(() {
|
||||
nombre = value.name;
|
||||
ref_photo = value.photo;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(onPressed: () {}, label: 'Puntuación'),
|
||||
body: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||
child: ListTile(
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
child: ReferencePhoto(
|
||||
ref: ref_photo,
|
||||
size: 50,
|
||||
sizeCircle: 50,
|
||||
sizeIcon: 35,
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
nombre,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 16),
|
||||
),
|
||||
subtitle: Text(
|
||||
'${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day))} ${TimeOfDay.fromDateTime(DateTime.parse(widget.evento.range1Hour1)).format(context)}'),
|
||||
),
|
||||
),
|
||||
RatingBar.builder(
|
||||
initialRating: _rating,
|
||||
minRating: 1,
|
||||
direction: Axis.horizontal,
|
||||
allowHalfRating: true,
|
||||
itemCount: 5,
|
||||
itemSize: 40,
|
||||
glow: false,
|
||||
maxRating: 5,
|
||||
itemPadding: const EdgeInsets.symmetric(horizontal: 5),
|
||||
itemBuilder: (context, _) => const Icon(
|
||||
Icons.star,
|
||||
color: Color(0xFF2BA4EC),
|
||||
),
|
||||
onRatingUpdate: (rating) {
|
||||
setState(() {
|
||||
_rating = rating;
|
||||
});
|
||||
},
|
||||
ignoreGestures: false,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 40),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Comentario',
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
TextFormField(
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType
|
||||
.multiline, // establece el tipo de teclado como "multilinea"
|
||||
controller: commentController,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 30),
|
||||
child: Column(
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
if (widget.evento.professionalId == uid) {
|
||||
FirebaseFirestore.instance.collection("scores").add({
|
||||
"comment": commentController.text,
|
||||
"from_user": uid,
|
||||
"is_from_professional": false,
|
||||
"score": _rating,
|
||||
"to_user": widget.evento.userId,
|
||||
}).then((value) {
|
||||
// Navigator.pushReplacementNamed(context, '/score');
|
||||
});
|
||||
} else {
|
||||
FirebaseFirestore.instance.collection("scores").add({
|
||||
"comment": commentController.text,
|
||||
"from_user": uid,
|
||||
"is_from_professional": true,
|
||||
"score": _rating,
|
||||
"to_user": widget.evento.professionalId,
|
||||
}).then((value) {
|
||||
// Navigator.pushReplacementNamed(context, '/score');
|
||||
});
|
||||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF2BA4EC),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
),
|
||||
elevation: 0,
|
||||
minimumSize: const Size(230, 60),
|
||||
),
|
||||
child: const Text(
|
||||
'Enviar',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:community_material_icon/community_material_icon.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -35,6 +35,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
final _serviceTypeController = TextEditingController();
|
||||
final _observacionController = TextEditingController();
|
||||
String professionalId = '';
|
||||
int professionalTarifa = 0;
|
||||
String professionalAddress = '';
|
||||
String professionalUbicacion = '';
|
||||
double? professionalLatitude;
|
||||
@@ -130,6 +131,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
|
||||
final FirebaseStorage storage = FirebaseStorage.instance;
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
final fcmToken = FirebaseMessaging.instance.getToken();
|
||||
|
||||
BitmapDescriptor? _markerIcon;
|
||||
|
||||
@@ -411,6 +413,9 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
|
||||
professionalId = profesional.id;
|
||||
|
||||
professionalTarifa =
|
||||
profesional.tarifa ?? 0;
|
||||
|
||||
professionalUbicacion =
|
||||
profesional.ubicacion;
|
||||
|
||||
@@ -549,35 +554,36 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
int tiempo2 = ((_selectedTime!.hour * 3600 +
|
||||
_selectedTime!.minute * 60) +
|
||||
7200) %
|
||||
86400;
|
||||
final DateTime combinedDate = DateTime(
|
||||
_selectedDate!.year,
|
||||
_selectedDate!.month,
|
||||
_selectedDate!.day,
|
||||
_selectedTime!.hour,
|
||||
_selectedTime!.minute);
|
||||
|
||||
int hora2 = tiempo2 ~/ 3600;
|
||||
int minutos2 = (tiempo2 % 3600) ~/ 60;
|
||||
|
||||
TimeOfDay time2 =
|
||||
TimeOfDay(hour: hora2, minute: minutos2);
|
||||
DateTime time2 =
|
||||
combinedDate.add(const Duration(hours: 2));
|
||||
|
||||
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,
|
||||
'pendiente')
|
||||
value.name,
|
||||
_observacionController.text,
|
||||
'$_selectedDate',
|
||||
'$combinedDate',
|
||||
'$time2',
|
||||
professionalId,
|
||||
ubicacion,
|
||||
_locationController.text,
|
||||
ubicacion != 'sitio'
|
||||
? coordinates.latitude
|
||||
: professionalLatitude,
|
||||
ubicacion != 'sitio'
|
||||
? coordinates.longitude
|
||||
: professionalLongitude,
|
||||
'pendiente',
|
||||
professionalTarifa,
|
||||
)
|
||||
.then((value) {
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.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';
|
||||
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 {
|
||||
@@ -50,8 +52,29 @@ class _SolicitudScreenState extends State<SolicitudScreen> {
|
||||
}
|
||||
|
||||
Widget _eventList() {
|
||||
return FutureBuilder(
|
||||
future: getByProIdAll('pendiente', ''),
|
||||
return StreamBuilder<List<Event>>(
|
||||
stream: FirebaseFirestore.instance
|
||||
.collection('services')
|
||||
.where('professional_id', isEqualTo: uid)
|
||||
.where('status', whereIn: ['pendiente', ''])
|
||||
.snapshots()
|
||||
.asyncMap((snapshot) async {
|
||||
try {
|
||||
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');
|
||||
return eventos;
|
||||
} catch (e) {
|
||||
print('Error getByProId $e');
|
||||
return [];
|
||||
}
|
||||
}),
|
||||
builder: (BuildContext context, AsyncSnapshot<List<Event>> snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(
|
||||
@@ -87,7 +110,10 @@ class _SolicitudScreenState extends State<SolicitudScreen> {
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: Text(event.range1Hour1),
|
||||
leading: Text(
|
||||
TimeOfDay.fromDateTime(DateTime.parse(event.range1Hour1))
|
||||
.format(context),
|
||||
),
|
||||
title: RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
@@ -134,7 +160,7 @@ 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.toStringAsFixed(1)}'),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import 'package:community_material_icon/community_material_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_email_sender/flutter_email_sender.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/setting_model.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class SupportScreen extends StatefulWidget {
|
||||
const SupportScreen({super.key});
|
||||
|
||||
@override
|
||||
State<SupportScreen> createState() => SsupportStateScreen();
|
||||
}
|
||||
|
||||
class SsupportStateScreen extends State<SupportScreen> {
|
||||
SettingModel? settings;
|
||||
|
||||
Future<void> _sendWhatsapp(String? number) async {
|
||||
final _whatsappUrl =
|
||||
'https://wa.me/$number?text=${Uri.parse('Hola! soy usuario de Prosapp y quisiera conocer mas sobre esta app')}';
|
||||
|
||||
if (!await launch(_whatsappUrl)) {
|
||||
throw Exception('Could not launch $_whatsappUrl');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _sendEmail(String recipients) async {
|
||||
final Email email = Email(
|
||||
body: '',
|
||||
subject: 'Soporte Prosapp',
|
||||
recipients: [recipients],
|
||||
isHTML: false,
|
||||
);
|
||||
|
||||
await FlutterEmailSender.send(email);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (settings == null) {
|
||||
SettingModel.getSettings().then(
|
||||
(SettingModel value) => setState(() {
|
||||
settings = value;
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: 'Soporte'),
|
||||
body: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 30, left: 35, right: 35),
|
||||
child: Text(
|
||||
'${settings?.titulo}',
|
||||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 35),
|
||||
child: Text('${settings?.parrafo}'),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const Expanded(child: SizedBox()),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_sendWhatsapp(settings?.numero);
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: const Color(0xFF2BA4EC),
|
||||
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(
|
||||
CommunityMaterialIcons.whatsapp,
|
||||
size: 30,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_sendEmail(settings?.email ?? '');
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: const Color(0xFF2BA4EC),
|
||||
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.email_outlined,
|
||||
size: 30,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Expanded(child: SizedBox()),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
||||
child: Column(
|
||||
children: [
|
||||
const Text(
|
||||
'Horario de atención:',
|
||||
style: TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text('${settings?.dias}'),
|
||||
const SizedBox(height: 5),
|
||||
Text('${settings?.horas}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class WebViewScreen extends StatefulWidget {
|
||||
String label;
|
||||
String link;
|
||||
WebViewScreen({super.key, required this.label, required this.link});
|
||||
|
||||
@override
|
||||
State<WebViewScreen> createState() => _WebViewScreenState();
|
||||
}
|
||||
|
||||
class _WebViewScreenState extends State<WebViewScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setBackgroundColor(const Color(0x00000000))
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onProgress: (int progress) {
|
||||
// Update loading bar.
|
||||
},
|
||||
onPageStarted: (String url) {},
|
||||
onPageFinished: (String url) {},
|
||||
onWebResourceError: (WebResourceError error) {},
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
if (request.url.startsWith('https://www.youtube.com/')) {
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
),
|
||||
)
|
||||
..loadRequest(Uri.parse('${widget.link}'));
|
||||
return Scaffold(
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: widget.label,
|
||||
),
|
||||
body: WebViewWidget(controller: controller),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import Foundation
|
||||
import cloud_firestore
|
||||
import firebase_auth
|
||||
import firebase_core
|
||||
import firebase_messaging
|
||||
import firebase_storage
|
||||
import geolocator_apple
|
||||
import url_launcher_macos
|
||||
@@ -16,6 +17,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
|
||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||
FLTFirebaseStoragePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseStoragePlugin"))
|
||||
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
|
||||
+72
-8
@@ -5,10 +5,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: f175bc1414e4edf8c5b83372c98eeabecf8353f39c9da423c2cfdf1f1f508788
|
||||
sha256: "867b77e2367bc502dcd4d5a66302615409f04eb20ed82ba1c0ba073f9107e018"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -141,26 +141,50 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: ed611fb8e67e43ecc7956f242cecca383d87cf71aace27287aa5dd4bdba4ac07
|
||||
sha256: dcf54c170c5371ad0e79229d0fb372c58262ae0968b7de222bf28e51dd236be0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.0"
|
||||
version: "2.11.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b"
|
||||
sha256: ae79f335f6c7f2dadb00c98c429da2ca905d265e0225fb5e7dfa62ac3accad48
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.0"
|
||||
version: "4.7.0"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b"
|
||||
sha256: e57ef862257a0d977c1308d02e2fbb9b68525e6d85711b08f3df8cec836fb444
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.0"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: "88a4bf569899344d863db26a73092681b590274f570f0a431051b92c4dd9bee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.5.0"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: "482fa6998f6cb10b30324ca8bfa0e2fcc0defed9484ccccce118b1b347e39a24"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: "61f7d323085704fbcc7b056a49d75211b2eb698610b878fec6cda18dd04d754f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
firebase_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -198,6 +222,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.1+1"
|
||||
flutter_email_sender:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_email_sender
|
||||
sha256: "9e253c69617f43d4cb5de672e93a7a19c12a21fb6a75e66c6ce7626336c4c1bc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -725,6 +757,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
webview_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: webview_flutter
|
||||
sha256: "1a37bdbaaf5fbe09ad8579ab09ecfd473284ce482f900b5aea27cf834386a567"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
webview_flutter_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_android
|
||||
sha256: "1acea8def62592123e2fbbca164ed8681a98a890bdcbb88f916d5b4a22687759"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
webview_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_platform_interface
|
||||
sha256: "78715dc442b7849dbde74e92bb67de1cecf5addf95531c5fb474e72f5fe9a507"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
webview_flutter_wkwebview:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webview_flutter_wkwebview
|
||||
sha256: "61f33512810bf1ee9ac89761a4b02663ff64e8227b7dc80654642acd660fd49d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.2"
|
||||
sdks:
|
||||
dart: ">=2.19.3 <3.0.0"
|
||||
flutter: ">=3.3.0"
|
||||
|
||||
+4
-1
@@ -56,8 +56,11 @@ dependencies:
|
||||
google_maps_flutter: ^2.2.5
|
||||
geolocator: ^9.0.2
|
||||
geocoding: ^2.1.0
|
||||
url_launcher: ^6.0.3
|
||||
url_launcher: ^6.1.10
|
||||
community_material_icon: ^5.9.55
|
||||
flutter_email_sender: ^5.2.0
|
||||
webview_flutter: ^4.2.0
|
||||
firebase_messaging: ^14.5.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <geolocator_windows/geolocator_windows.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||
GeolocatorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("GeolocatorWindows"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
firebase_core
|
||||
geolocator_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user