diff --git a/lib/components/general_drawer.dart b/lib/components/general_drawer.dart index 296d002..1815aca 100644 --- a/lib/components/general_drawer.dart +++ b/lib/components/general_drawer.dart @@ -15,7 +15,6 @@ import 'package:prosappco/screens/professional/professional_form_screen.dart'; import 'package:prosappco/screens/professional/professional_pending_screen.dart'; import 'package:prosappco/screens/professional/professional_profile_screen.dart'; import 'package:prosappco/screens/user/user_history_services_screen.dart'; -import 'package:prosappco/screens/user/user_services_screen.dart'; import 'package:prosappco/screens/web/web_view_screen.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:user_repository/user_repository.dart'; @@ -226,61 +225,60 @@ class GeneralDrawer extends StatelessWidget { buttonOfState(BuildContext context, ProfessionalState state) { return ElevatedButton( - onPressed: () { - final myUserState = context.read().state; - if (myUserState.status == MyUserStatus.success) { - final user = myUserState.user!; + onPressed: () { + final myUserState = context.read().state; + if (myUserState.status == MyUserStatus.success) { + final user = myUserState.user!; - switch (user.proState) { - case ProState.active: - Navigator.pop(context); + switch (user.proState) { + case ProState.active: + Navigator.pop(context); - context - .read() - .add(const SwitchProModeEvent()); + context.read().add(const SwitchProModeEvent()); - break; - case ProState.inactive: - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => const ProfessionalFormScreen(), - ), - ); - break; - case ProState.pending: - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => const ProfessionalPendingScreen(), - ), - ); - break; - case ProState.denied: - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => const ProfessionalDeniedScreen(), - ), - ); - break; - } - } else {} - }, - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, - padding: const EdgeInsets.symmetric(vertical: 15), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - )), - child: (state is LoadedModeProState) - ? Text( - state.isProModeActive ? 'Modo cliente' : 'Modo profesional', - style: const TextStyle(color: Colors.white, fontSize: 18), - ) - : const CircularProgressIndicator( - color: Colors.white, - )); + break; + case ProState.inactive: + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ProfessionalFormScreen(), + ), + ); + break; + case ProState.pending: + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ProfessionalPendingScreen(), + ), + ); + break; + case ProState.denied: + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ProfessionalDeniedScreen(), + ), + ); + break; + } + } else {} + }, + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.primary, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + )), + child: (state is LoadedModeProState) + ? Text( + state.isProModeActive ? 'Modo cliente' : 'Modo profesional', + style: const TextStyle(color: Colors.white, fontSize: 18), + ) + : const CircularProgressIndicator( + color: Colors.white, + ), + ); } shouldProModeActive(BuildContext context, ProfessionalState state) { diff --git a/lib/screens/home/home_screen.dart b/lib/screens/home/home_screen.dart index 65907e9..94a376e 100644 --- a/lib/screens/home/home_screen.dart +++ b/lib/screens/home/home_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:prosappco/blocs/professional_bloc/professional_bloc.dart'; import 'package:prosappco/components/general_drawer.dart'; +import 'package:prosappco/screens/user/user_map_screen.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @@ -23,10 +24,8 @@ class HomeScreen extends StatelessWidget { : Scaffold( backgroundColor: Theme.of(context).colorScheme.background, drawer: GeneralDrawer(), - appBar: AppBar(), body: const Center( - child: Text('Bienvenido cliente'), - // child: Text('Bienvenido profesional'), + child: UserMapScreen(), ), ), ); diff --git a/lib/screens/lists/professional_list_screen.dart b/lib/screens/lists/professional_list_screen.dart index 053eed7..b027842 100644 --- a/lib/screens/lists/professional_list_screen.dart +++ b/lib/screens/lists/professional_list_screen.dart @@ -5,6 +5,7 @@ import 'package:injector/injector.dart'; import 'package:intl_phone_field/helpers.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; +import 'package:prosappco/screens/user/user_calendar_screen.dart'; import 'package:prosappco/screens/user/user_view_profile_screen.dart'; import 'package:shimmer/shimmer.dart'; @@ -98,7 +99,16 @@ class _ProfessionalListScreenState extends State { ), ), child: ListTile( - onTap: () {}, + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => UserCalendarScreen( + // userProfessional: filteredUsers[index], + ), + ), + ); + }, trailing: GestureDetector( onTap: () { Navigator.push( diff --git a/lib/screens/professional/professional_map_screen.dart b/lib/screens/professional/professional_map_screen.dart index 2268a18..8d5a56a 100644 --- a/lib/screens/professional/professional_map_screen.dart +++ b/lib/screens/professional/professional_map_screen.dart @@ -86,12 +86,6 @@ class _ProfessionalMapScreenState extends State { return Scaffold( appBar: AppBar( title: const Text('Ubicación'), - // leading: BackButton( - // onPressed: () { - // Navigator.pop( - // context, {"address": '', 'longitude': 0, 'latitude': 0}); - // }, - // ), actions: [ IconButton( icon: const Icon(Icons.my_location), diff --git a/lib/screens/user/user_calendar_screen.dart b/lib/screens/user/user_calendar_screen.dart new file mode 100644 index 0000000..247a44a --- /dev/null +++ b/lib/screens/user/user_calendar_screen.dart @@ -0,0 +1,105 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class UserCalendarScreen extends StatefulWidget { + const UserCalendarScreen({super.key}); + + @override + State createState() => UserCalendarScreenState(); +} + +class UserCalendarScreenState extends State { + DateTime today = DateTime.now(); + DateTime now = DateTime.now(); + late int numDay; + + CalendarFormat _calendarFormat = CalendarFormat.month; + + @override + void initState() { + super.initState(); + + today = DateTime.utc(today.year, today.month, today.day); + numDay = today.weekday; + } + + void _onDaySelected(DateTime day, DateTime focusedDay) { + setState(() { + today = day; + numDay = today.weekday; + }); + } + + void _onFormatChange(CalendarFormat format) { + setState(() { + _calendarFormat = format; + }); + } + + @override + Widget build(BuildContext context) { + DateTime lastDay = today.add(const Duration(days: 365)); + + return Scaffold( + appBar: AppBar( + title: const Text('Calendario'), + ), + floatingActionButtonLocation: kIsWeb + ? FloatingActionButtonLocation.startFloat + : FloatingActionButtonLocation.endFloat, + resizeToAvoidBottomInset: false, + body: Column( + children: [ + Container( + color: const Color.fromARGB(255, 224, 247, 255), + child: TableCalendar( + // locale: 'es_MX', + firstDay: DateTime.now(), + lastDay: lastDay, + focusedDay: today, + availableGestures: AvailableGestures.all, + onDaySelected: _onDaySelected, + selectedDayPredicate: (day) => isSameDay(day, today), + calendarFormat: _calendarFormat, + onFormatChanged: _onFormatChange, + availableCalendarFormats: const { + CalendarFormat.month: 'Mes', + CalendarFormat.week: 'Semana', + CalendarFormat.twoWeeks: '2 Semanas', + }, + ), + ), + SizedBox( + width: double.infinity, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), + child: Text( + 'adwa', + // DateFormat('dd MMMM yyyy', 'es').format(today), + style: const TextStyle( + color: Colors.black, + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + const Divider( + height: 0, + ), + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.only(bottom: 15), + child: Column( + children: [ + Text('Hola'), + ], + ), + ), + ) + ], + ), + ); + } +} diff --git a/lib/screens/user/user_map_screen.dart b/lib/screens/user/user_map_screen.dart new file mode 100644 index 0000000..4879472 --- /dev/null +++ b/lib/screens/user/user_map_screen.dart @@ -0,0 +1,291 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:injector/injector.dart'; +import 'package:prosappco/constansts.dart'; +import 'package:prosappco/screens/lists/professional_list_screen.dart'; +import 'package:setting_repository/setting_repository.dart'; + +class UserMapScreen extends StatefulWidget { + const UserMapScreen({super.key}); + + @override + State createState() => _UserMapScreenState(); +} + +class _UserMapScreenState extends State { + final Completer _mapController = + Completer(); + LatLng? _currentP; + + final settingRepository = Injector.appInstance.get(); + SettingEntity? settings; + + @override + void initState() { + super.initState(); + + _loadSettings(); + } + + void _loadSettings() { + settingRepository.getSettings().then( + (value) => setState(() { + settings = value; + }), + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: Stack( + children: [ + GoogleMap( + myLocationEnabled: true, + onMapCreated: (GoogleMapController controller) { + _mapController.complete(controller); + }, + initialCameraPosition: const CameraPosition( + target: LatLng(7.078511421411328, -73.08832615613937 + // currentPosition.latitude, currentPosition.longitude + ), + zoom: 16, + ), + myLocationButtonEnabled: false, + ), + Positioned( + top: 10, + left: 0, + child: Builder( + builder: (context) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + shape: const CircleBorder(), + elevation: 3, + minimumSize: const Size(50, 50), + ), + child: const Icon( + Icons.menu, + color: Colors.black, + size: 35, + ), + onPressed: () { + Scaffold.of(context).openDrawer(); + }, + ); + }, + ), + ), + const Positioned( + bottom: 30, + right: 0, + left: 0, + top: 0, + child: Icon( + Icons.location_on, + size: 40, + color: Color(0xFFFF0000), + ), + ), + Positioned( + top: 10, + right: 10, + child: FloatingActionButton( + onPressed: () async { + try { + Position position = await _determinePosition(); + + if (mounted) { + setState(() { + _currentP = LatLng( + position.latitude, + position.longitude, + ); + }); + + _animateCameraToPosition(_currentP!); + } + } catch (e) { + ScaffoldMessenger.of(context).clearSnackBars(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Por favor activa la ubicacion'), + ), + ); + } + }, + elevation: 0, + child: const Icon( + Icons.gps_fixed, + size: 30, + ), + ), + ), + ], + ), + ), + buildBottom(context) + ], + ); + } + + Container buildBottom(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10), + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + readOnly: true, + onTap: () async { + var datos = await Navigator.push(context, CupertinoPageRoute(builder: (context) { + return const ProfessionalListScreen(); + })); + + log('xd -- $datos'); + }, + decoration: const InputDecoration( + prefixIcon: Icon(Icons.assignment_ind_rounded), + suffixIcon: Icon(Icons.arrow_drop_down), + hintText: 'Selecciona un profesional', + ), + ), + const SizedBox(height: 15), + const TextField( + readOnly: true, + decoration: InputDecoration( + prefixIcon: Icon(Icons.location_on), + hintText: 'Dirección', + ), + ), + const SizedBox(height: 15), + const Row( + children: [ + Expanded( + child: TextField( + readOnly: true, + decoration: InputDecoration( + prefixIcon: Icon(Icons.calendar_month), + hintText: 'Fecha', + ), + ), + ), + Expanded( + child: TextField( + readOnly: true, + decoration: InputDecoration( + prefixIcon: Icon(Icons.watch_later_outlined), + hintText: 'Hora', + ), + ), + ), + ], + ), + const SizedBox(height: 15), + const TextField( + // controller: _observacionController, + decoration: InputDecoration( + prefixIcon: Icon(Icons.message_outlined), + hintText: 'Observaciones', + ), + ), + const SizedBox(height: 15), + Row( + children: [ + Expanded( + child: FilledButton( + onPressed: () {}, + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.primary, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + // style: ElevatedButton.styleFrom( + // backgroundColor: Theme.of(context).colorScheme.primary, + // padding: const EdgeInsets.symmetric(vertical: 15), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10), + // ), + // ), + child: const Text( + 'Pedir cita', + style: TextStyle(color: Colors.white, fontSize: 18), + ), + ), + ), + const SizedBox(width: 10), + FilledButton( + onPressed: () {}, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + padding: const EdgeInsets.symmetric(vertical: 15), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + //x + child: const Icon( + CupertinoIcons.xmark, + color: Colors.white, + size: 30, + ), + ), + ], + ) + ], + ), + ); + } + + Future _animateCameraToPosition(LatLng position) async { + final GoogleMapController controller = await _mapController.future; + controller.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition( + target: position, + zoom: 17.5, + ), + ), + ); + } + + Future _determinePosition() async { + bool serviceEnabled; + LocationPermission permission; + + serviceEnabled = await Geolocator.isLocationServiceEnabled(); + + if (!serviceEnabled) { + return Future.error('Location services are disabled'); + } + + permission = await Geolocator.checkPermission(); + + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + + if (permission == LocationPermission.denied) { + return Future.error('Location permission denied'); + } + } + + if (permission == LocationPermission.deniedForever) { + return Future.error('Location permissions are permanently denied'); + } + + Position position = await Geolocator.getCurrentPosition(); + + return position; + } +}