Skip to content

Implementation of login screen with validations #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/config/routes/app_routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ import 'package:go_router/go_router.dart';

import '../../screens/create_task_screen.dart';
import '../../screens/home_screen.dart';
import '../../screens/login_screen.dart';

final appRoutes = [
GoRoute(
path: RouteLocation.login,
parentNavigatorKey: navigationKey,
builder: LoginScreen.builder,
),
GoRoute(
path: RouteLocation.home,
parentNavigatorKey: navigationKey,
Expand Down
3 changes: 2 additions & 1 deletion lib/data/datasource/datasource.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'task_datasource.dart';
export 'task_datasource_provider.dart';

export 'profile_datasource.dart';
export 'profile_datasource_provider.dart';
84 changes: 84 additions & 0 deletions lib/data/datasource/profile_datasource.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

import '../../utils/app_keys.dart';
import '../../utils/profile_keys.dart';
import '../models/profile.dart';

class ProfileDatasource {
static final ProfileDatasource _instance = ProfileDatasource._();

factory ProfileDatasource() => _instance;

ProfileDatasource._() {
_initDb();
}

static Database? _database;

Future<Database> get database async {
_database ??= await _initDb();
return _database!;
}

Future<Database> _initDb() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'profile.db');

return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
);
}

void _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE ${AppKeys.dbTableProfile} (
${ProfileKeys.id} INTEGER PRIMARY KEY AUTOINCREMENT,
${ProfileKeys.email} TEXT,
${ProfileKeys.password} TEXT,
${ProfileKeys.firstName} TEXT,
${ProfileKeys.lastName} TEXT
)
''');
}

Future<bool> createNewUser(Profile profile) async {
final db = await database;
return db.transaction((txn) async {
return await txn.insert(
AppKeys.dbTableProfile,
profile.toJson(),
conflictAlgorithm: ConflictAlgorithm.replace,
) !=
0;
});
}

Future<int> updateUser(Profile profile) async {
final db = await database;
return db.transaction((txn) async {
return await txn.update(
AppKeys.dbTableProfile,
profile.toJson(),
where: 'id = ?',
whereArgs: [profile.id],
);
});
}

Future<Profile?> getUser(Profile profile) async {
final db = await database;
var items = await db.query(AppKeys.dbTableProfile,
where: '${ProfileKeys.email} = ? and ${ProfileKeys.password} = ?',
whereArgs: [
profile.email,
profile.password,
]);
if (items.isNotEmpty) {
return Profile.fromJson(items.first);
}
return null;
}
}
6 changes: 6 additions & 0 deletions lib/data/datasource/profile_datasource_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_todo_template_app/data/datasource/profile_datasource.dart';

final profileDatasourceProvider = Provider<ProfileDatasource>((ref) {
return ProfileDatasource();
});
1 change: 1 addition & 0 deletions lib/data/models/models.dart
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export 'task.dart';
export 'profile.dart';
47 changes: 47 additions & 0 deletions lib/data/models/profile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import 'package:equatable/equatable.dart';

import '../../utils/profile_keys.dart';

class Profile extends Equatable {
final int? id;
final String? email;
final String? password;
final String? firstName;
final String? lastName;

@override
List<Object?> get props => [id, email, password, firstName, lastName];

const Profile(
{this.id, this.email, this.password, this.firstName, this.lastName});

Map<String, dynamic> toJson() {
return <String, dynamic>{
ProfileKeys.id: id,
ProfileKeys.email: email ?? '',
ProfileKeys.password: password ?? '',
ProfileKeys.firstName: firstName ?? '',
ProfileKeys.lastName: lastName ?? '',
};
}

factory Profile.fromJson(Map<String, dynamic> map) {
return Profile(
id: map[ProfileKeys.id],
email: map[ProfileKeys.email],
password: map[ProfileKeys.password],
firstName: ProfileKeys.firstName,
lastName: ProfileKeys.lastName,
);
}

Profile copyWith() {
return Profile(
id: id ,
email: email ,
password: password ,
firstName: firstName ,
lastName: lastName ,
);
}
}
9 changes: 9 additions & 0 deletions lib/data/repositories/profile_repository.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import '../models/profile.dart';

abstract class ProfileRepository {
Future<bool> createNewUser(Profile profile);

Future<void> updateUser(Profile profile);

Future<Profile?> getUser(Profile profile);
}
38 changes: 38 additions & 0 deletions lib/data/repositories/profile_repository_impl.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@


import '../datasource/profile_datasource.dart';
import '../models/profile.dart';
import 'profile_repository.dart';

class ProfileRepositoryImpl implements ProfileRepository {
final ProfileDatasource _datasource;

ProfileRepositoryImpl(this._datasource);

@override
Future<bool> createNewUser(Profile profile) async {
try {
return await _datasource.createNewUser(profile);
} catch (e) {
throw '$e';
}
}

@override
Future<Profile?> getUser(Profile profile) async {
try {
return await _datasource.getUser(profile);
} catch (e) {
throw '$e';
}
}

@override
Future<void> updateUser(Profile profile) async {
try {
await _datasource.updateUser(profile);
} catch (e) {
throw '$e';
}
}
}
10 changes: 10 additions & 0 deletions lib/data/repositories/profile_repository_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_todo_template_app/data/repositories/profile_repository.dart';
import 'package:flutter_todo_template_app/data/repositories/profile_repository_impl.dart';
import '../datasource/profile_datasource_provider.dart';


final profileRepositoryProvider = Provider<ProfileRepository>((ref) {
final datasource = ref.read(profileDatasourceProvider);
return ProfileRepositoryImpl(datasource);
});
4 changes: 3 additions & 1 deletion lib/data/repositories/repositories.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export 'task_repository.dart';
export 'task_repository_provider.dart';
export 'task_repository_impl.dart';

export 'profile_repository.dart';
export 'profile_repository_provider.dart';
export 'profile_repository_impl.dart';
16 changes: 16 additions & 0 deletions lib/providers/login/login_status_notifier.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../data/models/profile.dart';
import '../../validators/login_validator.dart';



class LoginStatusNotifier extends StateNotifier<String> {
Profile _profile;

LoginStatusNotifier(this._profile) : super('');

Future<void> validate() async {
state = LoginValidator(profile: _profile).validate();
}
}
10 changes: 10 additions & 0 deletions lib/providers/login/login_status_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_todo_template_app/providers/login/profile_entity_provider.dart';
import 'login_status_notifier.dart';


final loginStatusProvider =
StateNotifierProvider<LoginStatusNotifier, String>((ref) {
final profile = ref.watch(profileEntityProvider);
return LoginStatusNotifier(profile);
});
6 changes: 6 additions & 0 deletions lib/providers/login/profile_entity_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../data/models/profile.dart';

final profileEntityProvider = StateProvider<Profile>((ref) {
return const Profile();
});
2 changes: 2 additions & 0 deletions lib/providers/profile/profile.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'profile_notifier.dart';
export 'profile_provider.dart';
31 changes: 31 additions & 0 deletions lib/providers/profile/profile_notifier.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../data/models/profile.dart';
import '../../data/repositories/profile_repository.dart';

class ProfileNotifier extends StateNotifier<Profile?> {
final ProfileRepository _repository;

ProfileNotifier(this._repository) : super(null);

Future<bool> createNewUser(Profile profile) async {
try {
return await _repository.createNewUser(profile);
} catch (e) {
debugPrint(e.toString());
return false;
}
}

Future<Profile?> getUser(Profile profile) async {
try {
var data = await _repository.getUser(profile);
state = data?.copyWith();
return state;
} catch (e) {
debugPrint(e.toString());
return null;
}
}
}
11 changes: 11 additions & 0 deletions lib/providers/profile/profile_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_todo_template_app/providers/profile/profile_notifier.dart';

import '../../data/models/profile.dart';
import '../../data/repositories/profile_repository_provider.dart';


final profileProvider = StateNotifierProvider<ProfileNotifier, Profile?>((ref) {
final repository = ref.watch(profileRepositoryProvider);
return ProfileNotifier(repository);
});
Loading