Skip to content
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: 3 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.8.0'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
19 changes: 19 additions & 0 deletions lib/config/app_const_size/app_space.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class CrudTestSpace{
CrudTestSpace._();

static const ScreenDimensions screen = ScreenDimensions._();


static const double margin32 = 32;
static const double margin16 = 16;
static const double margin8 = 8;
static const double margin18 = 18;
static const double margin14 = 14;

}
class ScreenDimensions {
const ScreenDimensions._();
double get downMargin => 60;
double get sHeaderBody => 24;
double get upMargin => 72;
}
58 changes: 58 additions & 0 deletions lib/config/app_datasource/local/database_helper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:mc_crud_test/features/register/domain/params/cosumer_param.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;

DatabaseHelper._privateConstructor();

Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}

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

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

Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
firstname TEXT,
lastname TEXT,
dateOfBirth TEXT,
phoneNumber TEXT,
email TEXT UNIQUE,
bankAccountNumber TEXT
)
''');
}



Future<int> saveCustomer(CustomerParams param) async {
final db = await database;
try {
return await db.insert('customers', param.toMap());
} catch (e) {
if (e is DatabaseException && e.isUniqueConstraintError()) {
print('Error: Email must be unique.');
return -1; // Indicate failure due to unique constraint
} else {
throw e;
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'data_source_di.dart';
export 'use_case_di.dart';
export 'bloc_di.dart';
11 changes: 11 additions & 0 deletions lib/config/app_dependency_injection/bloc_di.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../../features/register/presentation/bloc/register/register_cubit.dart';
import 'main_dependency_injection.dart';

class BlocInjection {
static setup() {

/// Register
locator.registerFactory(() => RegisterCubit(locator()));

}
}
23 changes: 23 additions & 0 deletions lib/config/app_dependency_injection/data_source_di.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import '../../features/register/data/data_source/local/register_ds.dart';
import '../../features/register/data/repo/register_repository_impl.dart';
import '../../features/register/domain/repo/register_repository.dart';
import '../app_datasource/local/database_helper.dart';
import 'main_dependency_injection.dart';

class DataSourceInjection {
static setup() {

/// Register local database
locator.registerLazySingleton<DatabaseHelper>(() => DatabaseHelper.instance);


/// Register repository
locator.registerLazySingleton<RegisterRepository>(
() => RegisterRepositoryImpl(locator()));

/// Register datasource
locator.registerLazySingleton<RegisterLocalDS>(
() => RegisterLocalDSImpl(locator()));

}
}
15 changes: 15 additions & 0 deletions lib/config/app_dependency_injection/main_dependency_injection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:get_it/get_it.dart';
import 'app_dependency_injection.dart';


final locator = GetIt.instance;


class MainDependencyInjection {
static setup(){
DataSourceInjection.setup();
UseCaseInjection.setup();
BlocInjection.setup();
}

}
8 changes: 8 additions & 0 deletions lib/config/app_dependency_injection/use_case_di.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import '../../features/register/domain/use_cases/register.dart';
import 'main_dependency_injection.dart';

class UseCaseInjection {
static setup() {
locator.registerLazySingleton(() => RegisterUC(locator()));
}
}
22 changes: 22 additions & 0 deletions lib/config/app_extension/string_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
extension StringExtension on String{

bool isValidEmail(){
return RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+",
).hasMatch(this);
}


bool isValidPhone() {
return RegExp(
r'^\+?\d{1,3}\s?\d{1,14}$',
).hasMatch(this);
}


bool isValidBankAccountNumber() {
return RegExp(
r'^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$',
).hasMatch(this);
}
}
16 changes: 16 additions & 0 deletions lib/config/app_extension/widget_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import 'package:flutter/cupertino.dart';

extension WidgetExtension on num {
SizedBox get space => SizedBox(
height: toDouble(),
width: toDouble(),
);

SizedBox get hsp => SizedBox(
height: toDouble(),
);

SizedBox get wsp => SizedBox(
width: toDouble(),
);
}
3 changes: 3 additions & 0 deletions lib/config/app_type/usecase/use_case.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
abstract class UseCase<T, P> {
T call(P param);
}
42 changes: 42 additions & 0 deletions lib/config/app_type/vlaue_object/bank_account_number.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:mc_crud_test/config/app_extension/string_extension.dart';
import 'package:mc_crud_test/config/app_type/vlaue_object/value_failure.dart';

class BankAccountNumberInput extends Equatable {
final Either<ValueFailure, String> value;
final String input;

const BankAccountNumberInput._({required this.input, required this.value});

factory BankAccountNumberInput(String input) {
final inputTrim = input.trim();
return BankAccountNumberInput._(
input: inputTrim,
value: _validatePhone(inputTrim),
);
}

@override
List<Object?> get props => [input, value];
}

Either<ValueFailure, String> _validatePhone(String input) {
if (input.isEmpty) {
return left(
ValueFailure(
type: InputFailureType.empty,
failedValue: input,
),
);
} else if (!input.isValidBankAccountNumber() || input.length < 5) {
return left(
ValueFailure(
type: InputFailureType.invalid,
failedValue: input,
),
);
} else {
return right(input);
}
}
39 changes: 39 additions & 0 deletions lib/config/app_type/vlaue_object/email.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:mc_crud_test/config/app_extension/string_extension.dart';
import 'package:mc_crud_test/config/app_type/vlaue_object/value_failure.dart';

class EmailInput extends Equatable {
final Either<ValueFailure, String> value;
final String input;

const EmailInput._({required this.input, required this.value});

factory EmailInput(String input) {
final inputTrim = input.trim();
return EmailInput._(input: inputTrim, value: _validateEmail(inputTrim));
}

@override
List<Object?> get props => [value, input];
}

Either<ValueFailure, String> _validateEmail(String input) {
if (input.isEmpty) {
return left(
ValueFailure(
type: InputFailureType.empty,
failedValue: input,
),
);
} else if (!input.isValidEmail()) {
return left(
ValueFailure(
type: InputFailureType.invalid,
failedValue: input,
),
);
} else {
return right(input);
}
}
42 changes: 42 additions & 0 deletions lib/config/app_type/vlaue_object/phone.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:mc_crud_test/config/app_extension/string_extension.dart';
import 'package:mc_crud_test/config/app_type/vlaue_object/value_failure.dart';

class PhoneInput extends Equatable {
final Either<ValueFailure, String> value;
final String input;

const PhoneInput._({required this.input, required this.value});

factory PhoneInput(String input) {
final inputTrim = input.trim();
return PhoneInput._(
input: inputTrim,
value: _validatePhone(inputTrim),
);
}

@override
List<Object?> get props => [input, value];
}

Either<ValueFailure, String> _validatePhone(String input) {
if (input.isEmpty) {
return left(
ValueFailure(
type: InputFailureType.empty,
failedValue: input,
),
);
} else if (!input.isValidPhone() || input.length < 5) {
return left(
ValueFailure(
type: InputFailureType.invalid,
failedValue: input,
),
);
} else {
return right(input);
}
}
18 changes: 18 additions & 0 deletions lib/config/app_type/vlaue_object/value_failure.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:equatable/equatable.dart';
enum InputFailureType{
invalid,
empty,
short
}

class ValueFailure<T> extends Equatable{
final T failedValue;
final InputFailureType type;

const ValueFailure({required this.failedValue,required this.type});


@override
List<Object?> get props => [failedValue,type];

}
2 changes: 2 additions & 0 deletions lib/config/app_type/vlaue_object/vlaue_objects.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export 'email.dart';
export 'phone.dart';
Loading