This commit is contained in:
Felipe
2024-03-13 13:59:33 -05:00
parent 312cc3d863
commit a25bc6a987
26 changed files with 684 additions and 60 deletions
+10 -4
View File
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/screens/city/city_screen.dart';
import 'package:prosappco/screens/profile/profile_screen.dart';
class GeneralDrawerHeader extends StatelessWidget {
@@ -20,15 +21,20 @@ class GeneralDrawerHeader extends StatelessWidget {
CupertinoPageRoute(
builder: (BuildContext context) {
return const ProfileScreen();
// return const CityScreen();
},
),
);
},
title: Text(user.name ?? '',style: const TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text(user.drawerLabel,style: const TextStyle(fontSize: 12)),
title: Text(user.name ?? '',
style: const TextStyle(fontWeight: FontWeight.bold)),
subtitle:
Text(user.drawerLabel, style: const TextStyle(fontSize: 12)),
leading: pictureWidget(user.picture, context),
trailing: const Icon(Icons.keyboard_arrow_right, color: Colors.black),
contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
trailing:
const Icon(Icons.keyboard_arrow_right, color: Colors.black),
contentPadding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 15),
);
} else if (state.status == MyUserStatus.failure) {
return const Text('Error obteniendo datos del usuario');
@@ -8,14 +8,17 @@ import 'package:prosappco/blocs/setting_bloc/setting_bloc.dart';
import 'package:prosappco/blocs/sign_up_bloc/sign_up_bloc.dart';
import 'package:prosappco/blocs/sing_in_bloc/sign_in_bloc.dart';
import 'package:user_repository/user_repository.dart';
import 'package:city_repository/city_repository.dart';
class UserDI {
class AppDI {
void register() {
final injector = Injector.appInstance;
injector.registerSingleton<UserRepository>(
(() => FirebaseUserRepository(FirebaseAuth.instance)));
injector.registerSingleton<CityRepository>(() => FirebaseCityRepository());
injector.registerSingleton<AuthenticationBloc>((() =>
AuthenticationBloc(myUserRepository: injector.get<UserRepository>())));
+2 -2
View File
@@ -173,7 +173,7 @@ import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:prosappco/dependency_user/user_di.dart';
import 'package:prosappco/dependency/app_di.dart';
import 'app.dart';
import 'simple_bloc_observer.dart';
@@ -182,6 +182,6 @@ void main() async {
await Firebase.initializeApp();
Bloc.observer = SimpleBlocObserver();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
UserDI().register();
AppDI().register();
runApp(const MainApp());
}
+165
View File
@@ -0,0 +1,165 @@
import 'package:city_repository/city_repository.dart';
import 'package:flutter/material.dart';
import 'package:injector/injector.dart';
import 'package:intl_phone_field/helpers.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:shimmer/shimmer.dart';
class CityScreen extends StatefulWidget {
const CityScreen({Key? key}) : super(key: key);
@override
State<CityScreen> createState() => _CityScreenState();
}
class _CityScreenState extends State<CityScreen> {
final _searchController = TextEditingController();
final cityRepository = Injector.appInstance.get<CityRepository>();
List<CityUi>? _cities;
List<CityUi>? _filteredCities;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadCities();
}
void _loadCities() {
cityRepository.getCities().then((List<CityUi> element) {
setState(() {
_cities = element;
_filteredCities = _cities;
_isLoading = false;
});
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: PopAppbar(
onPressed: () {
Navigator.pop(context);
},
label: 'Ciudad',
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 15, right: 15, bottom: 15),
child: TextField(
controller: _searchController,
onChanged: (value) {
_filterCities(value);
},
decoration: const InputDecoration(
hintText: 'Busca una ciudad',
prefixIcon: Icon(Icons.search),
),
),
),
_isLoading
? _buildShimmerEffect()
: Expanded(
child: _filteredCities != null && _filteredCities!.isNotEmpty
? ListView.builder(
itemCount: _filteredCities!.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(
_filteredCities![index].cityName,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
subtitle: Text(
"${_filteredCities![index].stateOfCity}, ${_filteredCities![index].countryOfCity}",
style: const TextStyle(color: Colors.black54),
),
onTap: () {
// Handle city selection
},
);
},
)
: const Center(
child: Text('No se encontraron ciudades.'),
),
),
],
),
),
);
}
void _filterCities(String query) {
if (_cities != null) {
setState(() {
_filteredCities = _cities!
.where((city) => removeDiacritics(city.cityName.toLowerCase())
.contains(removeDiacritics(query.toLowerCase())))
.toList();
});
}
}
Widget _buildShimmerEffect() {
return Expanded(
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: ListView.builder(
itemCount: 8,
itemBuilder: (_, __) => const ListTileShimmer(),
),
),
);
}
}
class ListTileShimmer extends StatelessWidget {
const ListTileShimmer({super.key});
@override
Widget build(BuildContext context) {
return ListTile(
title: Row(
children: [
Container(
width: MediaQuery.of(context).size.width * 0.8,
height: 18.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
),
],
),
subtitle: Row(
children: [
Container(
width: MediaQuery.of(context).size.width * 0.3,
height: 15.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
),
const SizedBox(width: 5),
Container(
width: MediaQuery.of(context).size.width * 0.3,
height: 15.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
)
],
),
);
}
}
+38
View File
@@ -10,6 +10,7 @@ import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart';
import 'package:prosappco/components/birthday_picker.dart';
import 'package:prosappco/components/gender_dropdown.dart';
import 'package:prosappco/screens/city/city_screen.dart';
import 'package:prosappco/screens/profile/components/profile_item.dart';
import 'package:prosappco/screens/profile/profile_register_email_screen.dart';
import 'package:prosappco/screens/profile/profile_register_phone_screen.dart';
@@ -128,6 +129,43 @@ class _ProfileScreenState extends State<ProfileScreen> {
return null;
},
),
const SizedBox(height: 20.0),
TextFormField(
// controller: _nameController,
readOnly: true,
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return const CityScreen();
},
),
);
},
decoration: const InputDecoration(
labelText: 'Ciudad',
prefixIcon: Icon(Icons.near_me_rounded),
hintText: 'Elige tu ciudad',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0),
)),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
focusedErrorBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.red, width: 2.0),
),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Por favor, ingrese su nombre';
}
return null;
},
),
_birthdayController.text.isEmpty &&
_genderController.text.isEmpty
? Column(