Skip to content

Commit

Permalink
Done: Validate misssing data
Browse files Browse the repository at this point in the history
  • Loading branch information
jccd1996 committed Mar 20, 2024
1 parent 981b748 commit 023f109
Show file tree
Hide file tree
Showing 22 changed files with 1,494 additions and 85 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

## run this command to generate builders
- dart run build_runner build --delete-conflicting-outputs
then add this in the model file if you will use freezed
- part '{nameOfTheModel}.freezed.dart';
- part '{nameOfTheModel}.g.dart';
18 changes: 2 additions & 16 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart';
import 'package:flutter/material.dart';
import 'package:flutter_community_ibague/firebase_options.dart';
import 'package:flutter_community_ibague/src/config/app_colors.dart';
import 'package:flutter_community_ibague/src/config/dependecy_injection.dart';
import 'package:flutter_community_ibague/src/config/es.dart';
import 'package:flutter_community_ibague/src/config/router.dart';
import 'package:intl/date_symbol_data_local.dart';
Expand All @@ -15,6 +16,7 @@ void main() async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
DependecyInjection.registerInjections();
FirebaseUIAuth.configureProviders([
EmailAuthProvider(),
GoogleProvider(
Expand All @@ -27,28 +29,12 @@ void main() async {
class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp.router(
title: 'Flutter Community Ibagué',
debugShowCheckedModeBanner: false,
theme: ThemeData(
// This is the theme of your application.
//
// TRY THIS: Try running your application with "flutter run". You'll see
// the application has a purple toolbar. Then, without quitting the app,
// try changing the seedColor in the colorScheme below to Colors.green
// and then invoke "hot reload" (save your changes or press the "hot
// reload" button in a Flutter-supported IDE, or press "r" if you used
// the command line to start the app).
//
// Notice that the counter didn't reset back to zero; the application
// state is not lost during the reload. To reset the state, use hot
// restart instead.
//
// This works for code too, not just values: Most code changes can be
// tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: AppColors.primary),
useMaterial3: true,
),
Expand Down
8 changes: 8 additions & 0 deletions lib/src/config/app_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class AppConstants {
static const genderList = [
'Mujer',
'Hombre',
'Otro',
'Perfiero no decir',
];
}
12 changes: 12 additions & 0 deletions lib/src/config/dependecy_injection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter_community_ibague/src/data/api/member_api.dart';
import 'package:flutter_community_ibague/src/domain/repository/member_repository.dart';
import 'package:get_it/get_it.dart';

final GetIt locator = GetIt.instance;

class DependecyInjection {
static void registerInjections() {
locator.registerSingleton<MemberApi>(MemberApiAdapter());
locator.registerSingleton<MemberRepository>(MemberRepositoryAdapter());
}
}
7 changes: 5 additions & 2 deletions lib/src/config/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import 'package:flutter_community_ibague/src/notifiers/events_notifier.dart';
import 'package:flutter_community_ibague/src/ui/screens/event_detail_screen.dart';
import 'package:flutter_community_ibague/src/ui/screens/events_screen.dart';
import 'package:flutter_community_ibague/src/ui/screens/home_screen.dart';
import 'package:flutter_community_ibague/src/ui/screens/person_screen.dart';
import 'package:flutter_community_ibague/src/ui/screens/person_screen/person_notifier.dart';
import 'package:flutter_community_ibague/src/ui/screens/person_screen/person_screen.dart';
import 'package:flutter_community_ibague/src/ui/screens/sponsors_screen.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -64,7 +65,9 @@ final GoRouter appRouter = GoRouter(
name: Routes.person,
path: Routes.person,
builder: (context, state) {
return const PersonScreen();
return ChangeNotifierProvider(
create: (_) => PersonNotifier()..init(),
child: const PersonScreen());
},
),
GoRoute(
Expand Down
106 changes: 106 additions & 0 deletions lib/src/data/api/member_api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_community_ibague/src/data/firebase_collections.dart';
import 'package:flutter_community_ibague/src/models/member.dart';
import 'package:flutter_community_ibague/src/models/server_exception.dart';
import 'package:multiple_result/multiple_result.dart';

abstract class MemberApi {
Future<Result<Member, Exception>> manageMember(Member member);

Future<Result<Member, Exception>> getMemberByEmail({String? email});

Future<Result<Member, Exception>> getCurrentUserLogged();

Future<Result<Member, Exception>> createMember();
}

class MemberApiAdapter extends MemberApi {
final _firebaseDb = FirebaseFirestore.instance;
final _firebaseAuth = FirebaseAuth.instance;

@override
Future<Result<Member, Exception>> manageMember(Member member) async {
try {
var collectionRef = _firebaseDb.collection(FirebaseCollections.user);
await collectionRef.doc(member.uid).set(member.toJson());
return Result.success(member);
} on FirebaseAuthException catch (e) {
return Result.error(
ServerException(
message: e.message,
codeError: e.code,
),
);
} catch (e) {
return Result.error(
ServerException(
//TODO CHANGE THIS IN THE FUTURE
codeError: 'Ups hubo un error',
),
);
}
}

@override
Future<Result<Member, Exception>> getMemberByEmail({String? email}) async {
try {
final userEmail = email ?? _firebaseAuth.currentUser?.email ?? '';
final document = await _firebaseDb
.collection(FirebaseCollections.user)
.doc(userEmail)
.get();
final event = Member.fromJson(document.data()!);
return Result.success(event);
} on FirebaseAuthException catch (e) {
return Result.error(
ServerException(
message: e.message,
codeError: e.code,
),
);
} catch (e) {
return Result.error(
ServerException(
//TODO CHANGE THIS IN THE FUTURE
codeError: 'Ups hubo un error',
),
);
}
}

@override
Future<Result<Member, Exception>> getCurrentUserLogged() async {
try {
final uid = _firebaseAuth.currentUser?.uid;
final document =
await _firebaseDb.collection(FirebaseCollections.user).doc(uid).get();
final event = Member.fromJson(document.data()!);
return Result.success(event);
} on FirebaseAuthException catch (e) {
return Result.error(
ServerException(
message: e.message,
codeError: e.code,
),
);
} catch (e) {
return Result.error(
ServerException(
//TODO CHANGE THIS IN THE FUTURE
codeError: 'Ups hubo un error',
),
);
}
}

@override
Future<Result<Member, Exception>> createMember() async {
final memberToSave = Member(
uid: _firebaseAuth.currentUser!.uid,
email: _firebaseAuth.currentUser!.email!,
photoURL: _firebaseAuth.currentUser?.photoURL ?? '',
);
return manageMember(memberToSave);
}
}
4 changes: 4 additions & 0 deletions lib/src/data/firebase_collections.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class FirebaseCollections {
static const user = 'users';
static const events = 'events';
}
39 changes: 39 additions & 0 deletions lib/src/domain/repository/member_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:flutter_community_ibague/src/config/dependecy_injection.dart';
import 'package:flutter_community_ibague/src/data/api/member_api.dart';
import 'package:flutter_community_ibague/src/models/member.dart';
import 'package:multiple_result/multiple_result.dart';

abstract class MemberRepository {
Future<Result<Member, Exception>> manageMember(Member member);

Future<Result<Member, Exception>> createMember();

///If the func does not have an email, it will get the member data with the current user logged
Future<Result<Member, Exception>> getMemberByEmail({String? email});

Future<Result<Member, Exception>> getCurrentUserLogged();
}

class MemberRepositoryAdapter extends MemberRepository {
final MemberApi _api = locator<MemberApi>();

@override
Future<Result<Member, Exception>> manageMember(Member member) {
return _api.manageMember(member);
}

@override
Future<Result<Member, Exception>> getMemberByEmail({String? email}) {
return _api.getMemberByEmail(email: email);
}

@override
Future<Result<Member, Exception>> createMember() {
return _api.createMember();
}

@override
Future<Result<Member, Exception>> getCurrentUserLogged() {
return _api.getCurrentUserLogged();
}
}
31 changes: 31 additions & 0 deletions lib/src/models/member.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter_community_ibague/src/models/timestamp_converter.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

part 'member.freezed.dart';

part 'member.g.dart';

@freezed
class Member with _$Member {
const factory Member({
String? uid,
@Default('') String displayName,
String? photoURL,
required String email,
@Default('') String cellPhone,
@Default('') String gender,
@TimestampConverter() DateTime? dateOfBirth,
}) = _Member;

factory Member.fromJson(Map<String, dynamic> json) => _$MemberFromJson(json);
}

extension MemberExtension on Member {
bool get hasAllInformationCompleted {
return cellPhone.isNotEmpty &&
gender.isNotEmpty &&
dateOfBirth != null &&
displayName.isNotEmpty;
}
}
11 changes: 11 additions & 0 deletions lib/src/models/server_exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class ServerException implements Exception {
final String? message;
final String? codeError;
final int? status;

ServerException({
this.message,
this.codeError,
this.status,
});
}
14 changes: 14 additions & 0 deletions lib/src/models/timestamp_converter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

class TimestampConverter implements JsonConverter<DateTime, Timestamp> {
const TimestampConverter();

@override
DateTime fromJson(Timestamp timestamp) {
return timestamp.toDate();
}

@override
Timestamp toJson(DateTime date) => Timestamp.fromDate(date);
}
26 changes: 25 additions & 1 deletion lib/src/notifiers/event_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ import 'dart:async';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_community_ibague/src/config/dependecy_injection.dart';
import 'package:flutter_community_ibague/src/data/events_repository.dart';
import 'package:flutter_community_ibague/src/domain/repository/member_repository.dart';
import 'package:flutter_community_ibague/src/models/event.dart';
import 'package:flutter_community_ibague/src/models/member.dart';
import 'package:multiple_result/multiple_result.dart';

class EventNotifier extends ChangeNotifier {
final EventsRepository _eventsRepository;
final MemberRepository _memberRepository = locator<MemberRepository>();
final FirebaseAuth _auth;

Event event;

bool get attending => event.attendees.any((uid) => uid == _user?.uid);
late final StreamSubscription _eventSubscription;

User? get _user => _auth.currentUser;

EventNotifier({
Expand All @@ -33,12 +40,29 @@ class EventNotifier extends ChangeNotifier {
}
}

void notAttendEvent() {
void notAttendEvent() async {
if (_user != null) {
_eventsRepository.notAttendToEvent(event.id, _user!.uid);
}
}

Future<Result<Member, Exception>> getCurrentUser() async {
final currentUser = await _memberRepository.getCurrentUserLogged();
notifyListeners();
return currentUser;
}

Future<Result<Member, Exception>> updateMember(Member member) async {
final currentUser = await _memberRepository.manageMember(member);
notifyListeners();
return currentUser;
}

//TODO move this to the Data layer
Future<void> updateName(Member member) async {
await _auth.currentUser?.updateDisplayName(member.displayName);
}

@override
void dispose() {
_eventSubscription.cancel();
Expand Down
Loading

0 comments on commit 023f109

Please sign in to comment.