Skip to content

Commit 86cded0

Browse files
committed
minor changes
1 parent 8a23e34 commit 86cded0

File tree

11 files changed

+317
-106
lines changed

11 files changed

+317
-106
lines changed

lib/core/network/dio_cleint.dart

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,48 @@ import 'package:myapp/core/network/token_intercepter.dart';
33

44
import '../constants/api_constants.dart';
55

6+
/* A singleton class that manages Dio HTTP client configuration
7+
including base URL, timeouts, and interceptors. */
8+
69
class DioClient {
10+
/* Private constructor for singleton pattern. */
711
DioClient._();
12+
13+
/// The single shared instance of [DioClient].
814
static final DioClient _instance = DioClient._();
15+
16+
/// Factory constructor that always returns the same instance.
917
factory DioClient() => _instance;
1018

19+
/// The Dio instance used for making HTTP requests.
1120
late final Dio dio;
1221

22+
/* Initializes Dio with base options and interceptors.
23+
Should be called once at app startup before making any network requests. */
1324
Future<void> init() async {
14-
dio = Dio(BaseOptions(
15-
baseUrl: ApiConstants.baseUrl,
16-
connectTimeout: const Duration(seconds: 10),
17-
receiveTimeout: const Duration(seconds: 10),
18-
contentType: 'application/json',
19-
));
25+
dio = Dio(
26+
BaseOptions(
27+
baseUrl: ApiConstants.baseUrl,
28+
connectTimeout: const Duration(seconds: 10),
29+
receiveTimeout: const Duration(seconds: 10),
30+
contentType: 'application/json',
31+
),
32+
);
33+
34+
/// interceptor for attaching authentication tokens.
2035
dio.interceptors.add(TokenInterceptor());
21-
dio.interceptors.add(LogInterceptor(
22-
request: true,
23-
requestHeader: true,
24-
requestBody: true,
25-
responseHeader: false,
26-
responseBody: true,
27-
error: true,
28-
logPrint: (obj) => print("🔐 $obj"),
29-
));
36+
37+
/// Add log interceptor for debugging network calls.
38+
dio.interceptors.add(
39+
LogInterceptor(
40+
request: true,
41+
requestHeader: true,
42+
requestBody: true,
43+
responseHeader: false,
44+
responseBody: true,
45+
error: true,
46+
logPrint: (obj) => print("🔐 $obj"), // Custom log format
47+
),
48+
);
3049
}
31-
}
50+
}
Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
11
import 'package:dio/dio.dart';
22
import '../../core/constants/api_constants.dart';
33
import '../model/auth_response_model.dart';
4-
4+
5+
/// Remote data source responsible for user authentication API calls.
6+
///
7+
/// Uses [Dio] for HTTP requests and maps API responses to [AuthResponseModel].
58
class AuthRemoteDatasource {
69
final Dio dio;
10+
11+
/// Creates an instance with the provided [dio] HTTP client.
712
AuthRemoteDatasource(this.dio);
813

9-
Future<AuthResponseModel> signUp(
10-
{required String name,
11-
required String email,
12-
required String password}) async {
13-
final res = await dio.post(ApiConstants.signUp,
14-
data: {'name': name, 'email': email, 'password': password});
14+
/// Registers a new user by sending a POST request to the signup endpoint.
15+
///
16+
/// Requires [name], [email], and [password] for account creation.
17+
/// Returns an [AuthResponseModel] containing the authentication token and other data.
18+
/// Throws [DioError] if the network call fails or the server returns an error.
19+
Future<AuthResponseModel> signUp({
20+
required String name,
21+
required String email,
22+
required String password,
23+
}) async {
24+
final res = await dio.post(
25+
ApiConstants.signUp,
26+
data: {'name': name, 'email': email, 'password': password},
27+
);
1528
return AuthResponseModel.fromJson(res.data);
1629
}
1730

18-
Future<AuthResponseModel> login(
19-
{required String email, required String password}) async {
20-
final res =
21-
await dio.post(ApiConstants.login, data: {'email': email, 'password': password});
31+
/// Logs in an existing user by sending a POST request to the login endpoint.
32+
///
33+
/// Requires [email] and [password].
34+
/// Returns an [AuthResponseModel] containing the authentication token and other data.
35+
/// Throws [DioError] if the network call fails or the server returns an error.
36+
Future<AuthResponseModel> login({
37+
required String email,
38+
required String password,
39+
}) async {
40+
final res = await dio.post(
41+
ApiConstants.login,
42+
data: {'email': email, 'password': password},
43+
);
2244
return AuthResponseModel.fromJson(res.data);
2345
}
2446
}

lib/data/datasource/todo_remote_datasource.dart

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,53 @@ import 'package:dio/dio.dart';
22
import '../../core/constants/api_constants.dart';
33
import '../model/todo_model.dart';
44

5+
/// Remote data source for fetching and modifying todos via REST API.
6+
///
7+
/// Uses [Dio] for making HTTP requests. Returns data layer models ([TodoModel])
8+
/// which are later converted to domain entities in the repository layer.
59
class TodoRemoteDatasource {
610
final Dio dio;
11+
12+
/// Creates a new instance with the given [dio] HTTP client.
713
TodoRemoteDatasource(this.dio);
814

15+
/// Fetches the list of todos from the remote API.
16+
///
17+
/// Returns a list of [TodoModel] parsed from JSON.
18+
/// Throws [DioError] if the network call fails.
919
Future<List<TodoModel>> getTodos() async {
1020
final res = await dio.get(ApiConstants.todos);
11-
return (res.data as List).map((e) => TodoModel.fromJson(e)).toList();
21+
return (res.data as List)
22+
.map((e) => TodoModel.fromJson(e))
23+
.toList();
1224
}
1325

26+
/// Adds a new todo with the given [text].
27+
///
28+
/// Returns the created [TodoModel] parsed from JSON.
29+
/// Sets `completed` to `false` by default for new todos.
1430
Future<TodoModel> addTodo(String text) async {
15-
final res = await dio.post(ApiConstants.todos,
16-
data: {'todo': text, 'completed': false});
31+
final res = await dio.post(
32+
ApiConstants.todos,
33+
data: {'todo': text, 'completed': false},
34+
);
1735
return TodoModel.fromJson(res.data);
1836
}
1937

38+
/// Updates an existing todo represented by [m].
39+
///
40+
/// Sends a PUT request to update the todo and returns the updated [TodoModel].
2041
Future<TodoModel> updateTodo(TodoModel m) async {
21-
final res = await dio.put('${ApiConstants.todos}/${m.id}', data: m.toJson());
42+
final res = await dio.put(
43+
'${ApiConstants.todos}/${m.id}',
44+
data: m.toJson(),
45+
);
2246
return TodoModel.fromJson(res.data);
2347
}
2448

49+
/// Deletes a todo by its [id].
50+
///
51+
/// Sends a DELETE request to the API. Does not return any data.
2552
Future<void> deleteTodo(int id) async {
2653
await dio.delete('${ApiConstants.todos}/$id');
2754
}

lib/data/repositories/auth_repositories_impl.dart

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,53 @@
1-
21
import '../../core/error/exceptions.dart';
32
import '../../domain/entities/token.dart';
43
import '../../domain/repositories/auth_repository.dart';
54
import '../datasource/auth_remote_datesource.dart';
65

6+
/// Implementation of [AuthRepository] that handles user authentication.
7+
///
8+
/// Uses a remote data source ([AuthRemoteDatasource]) to perform actual API calls
9+
/// and maps data models to domain entities ([Token]).
710
class AuthRepositoryImpl implements AuthRepository {
811
final AuthRemoteDatasource remote;
12+
13+
/// Constructor injecting the remote datasource.
914
AuthRepositoryImpl(this.remote);
1015

16+
/// Registers a new user with [name], [email], and [password].
17+
///
18+
/// Returns a [Token] on successful signup.
19+
/// Throws a [ServerException] if any error occurs during the remote call.
1120
@override
1221
Future<Token> signUp(String name, String email, String password) async {
1322
try {
14-
final model =
15-
await remote.signUp(name: name, email: email, password: password);
23+
final model = await remote.signUp(
24+
name: name,
25+
email: email,
26+
password: password,
27+
);
28+
// Map remote model to domain entity
1629
return Token(model.token);
1730
} on Exception catch (e) {
31+
// Wrap and rethrow as a domain-specific exception
1832
throw ServerException(e.toString());
1933
}
2034
}
2135

36+
/// Logs in a user with [email] and [password].
37+
///
38+
/// Returns a [Token] on successful login.
39+
/// Throws a [ServerException] if any error occurs during the remote call.
2240
@override
2341
Future<Token> login(String email, String password) async {
2442
try {
25-
final model =
26-
await remote.login(email: email, password: password);
43+
final model = await remote.login(
44+
email: email,
45+
password: password,
46+
);
47+
// Map remote model to domain entity
2748
return Token(model.token);
2849
} on Exception catch (e) {
50+
// Wrap and rethrow as a domain-specific exception
2951
throw ServerException(e.toString());
3052
}
3153
}

lib/data/repositories/todo_repositories.dart

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import 'package:myapp/data/mapper/todo_mapper.dart';
32

43
import '../../core/error/exceptions.dart';
@@ -7,19 +6,34 @@ import '../../domain/repositories/todo_repository.dart';
76
import '../datasource/todo_remote_datasource.dart';
87
import '../model/todo_model.dart';
98

9+
/// Implementation of [TodoRepository] that communicates with the remote data source.
10+
///
11+
/// Converts between data layer models ([TodoModel]) and domain layer entities ([Todo]).
1012
class TodoRepositoryImpl implements TodoRepository {
1113
final TodoRemoteDatasource remote;
14+
15+
/// Creates an instance with the required [TodoRemoteDatasource].
1216
TodoRepositoryImpl(this.remote);
1317

18+
/// Retrieves all todos from the remote API.
19+
///
20+
/// Returns a list of [Todo] entities mapped from [TodoModel].
21+
/// Throws [ServerException] if a network or server error occurs.
1422
@override
1523
Future<List<Todo>> getTodos() async {
1624
try {
17-
return (await remote.getTodos()).map((e) => e.toEntity()).toList();
25+
return (await remote.getTodos())
26+
.map((e) => e.toEntity()) // Map each data model to domain entity
27+
.toList();
1828
} on Exception catch (e) {
1929
throw ServerException(e.toString());
2030
}
2131
}
2232

33+
/// Adds a new todo with the given [text].
34+
///
35+
/// Returns the created [Todo] entity.
36+
/// Throws [ServerException] if a network or server error occurs.
2337
@override
2438
Future<Todo> addTodo(String text) async {
2539
try {
@@ -29,20 +43,30 @@ class TodoRepositoryImpl implements TodoRepository {
2943
}
3044
}
3145

46+
/// Updates an existing [todo].
47+
///
48+
/// Converts the [Todo] entity to a [TodoModel] before making the remote call.
49+
/// Returns the updated [Todo] entity.
50+
/// Throws [ServerException] if a network or server error occurs.
3251
@override
3352
Future<Todo> updateTodo(Todo todo) async {
3453
try {
35-
return (await remote.updateTodo(TodoModel(
36-
id: todo.id,
37-
todo: todo.todo,
38-
completed: todo.completed,
39-
)))
54+
return (await remote.updateTodo(
55+
TodoModel(
56+
id: todo.id,
57+
todo: todo.todo,
58+
completed: todo.completed,
59+
),
60+
))
4061
.toEntity();
4162
} on Exception catch (e) {
4263
throw ServerException(e.toString());
4364
}
4465
}
4566

67+
/// Deletes the todo with the specified [id].
68+
///
69+
/// Throws [ServerException] if a network or server error occurs.
4670
@override
4771
Future<void> deleteTodo(int id) async {
4872
try {

lib/main.dart

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
1-
import 'package:flutter/material.dart';
2-
31
import 'package:flutter/material.dart';
42
import 'package:get/get.dart';
53
import 'package:myapp/routes/app_pages.dart';
64
import 'package:myapp/routes/routes.dart';
75

86
import 'di/service_locator.dart' as di;
97

8+
/// Entry point of the application.
109
void main() async {
10+
// Ensures that plugin services are initialized before runApp is called.
1111
WidgetsFlutterBinding.ensureInitialized();
12+
13+
// Initialize all dependencies (DI setup: repositories, use cases, controllers, etc.)
1214
await di.init();
15+
16+
// Launch the root widget of the app.
1317
runApp(const MyApp());
1418
}
1519

20+
/// Root widget of the application.
21+
///
22+
/// Uses [GetMaterialApp] for routing and dependency injection.
1623
class MyApp extends StatelessWidget {
1724
const MyApp({super.key});
1825

1926
@override
2027
Widget build(BuildContext context) {
2128
return GetMaterialApp(
22-
title: 'Clean Todo',
29+
title: 'My Todo',
30+
31+
// Define the initial screen of the app.
2332
initialRoute: Routes.login,
33+
34+
// Define the application's named routes.
2435
getPages: AppPages.pages,
36+
37+
// Disable the debug banner for production-like appearance.
2538
debugShowCheckedModeBanner: false,
2639
);
2740
}
2841
}
29-

0 commit comments

Comments
 (0)