base_project

This commit is contained in:
2026-01-28 05:53:02 +00:00
commit 664afae198
1349 changed files with 89007 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
class AppExceptions implements Exception {
final String? _message;
final String? _prefix;
AppExceptions([this._message, this._prefix]);
@override
String toString() {
return "${_prefix ?? ''}${_message ?? 'An unknown error occurred'}";
}
}
// Network error when data fetch fails
class FetchDataException extends AppExceptions {
FetchDataException([String? message])
: super(message ?? "Network Error: Failed to communicate with the server. Please check your internet connection and try again.",
"Error During Communication: ");
}
// Error for invalid or malformed requests
class BadRequestException extends AppExceptions {
BadRequestException([String? message])
: super(message ?? "Client Error: The request sent to the server was malformed or contained invalid parameters.",
"Invalid Request: ");
}
// Error for unauthorized access
class UnauthorizedException extends AppExceptions {
UnauthorizedException([String? message])
: super(message ?? "Authorization Error: You are not authorized to perform this action. Please log in with appropriate credentials.",
"Unauthorized: ");
}
// Error when a resource is not found
class NotFoundException extends AppExceptions {
NotFoundException([String? message])
: super(message ?? "Resource Not Found: The requested resource could not be found on the server. It may have been moved or deleted.",
"Not Found: ");
}
// Error for server-side issues
class InternalServerErrorException extends AppExceptions {
InternalServerErrorException([String? message])
: super(message ?? "Server Error: An unexpected error occurred on the server. Please try again later or contact support.",
"Internal Server Error: ");
}
// Error when user input is invalid
class InvalidInputException extends AppExceptions {
InvalidInputException([String? message])
: super(message ?? "Validation Error: The provided input does not match the required format. Please correct the errors and try again.",
"Invalid Input: ");
}
// Error when a request times out
class TimeoutException extends AppExceptions {
TimeoutException([String? message])
: super(message ?? "Request Timeout: The server took too long to respond. Please check your connection and try again.",
"Timeout: ");
}
// Error when a request conflicts with the current state
class ConflictException extends AppExceptions {
ConflictException([String? message])
: super(message ?? "Conflict Error: The request could not be processed because of a conflict with the current state of the resource.",
"Conflict: ");
}
// Error when the service is unavailable
class ServiceUnavailableException extends AppExceptions {
ServiceUnavailableException([String? message])
: super(message ?? "Service Unavailable: The server is currently unable to handle the request. Please try again later.",
"Service Unavailable: ");
}
// Error when access to a resource is forbidden
class ForbiddenException extends AppExceptions {
ForbiddenException([String? message])
: super(message ?? "Forbidden: You do not have the necessary permissions to access this resource.",
"Forbidden: ");
}

View File

@@ -0,0 +1,7 @@
abstract class BaseNetworkService {
Future<dynamic> getGetApiResponse(String? url);
Future<dynamic> getPostApiResponse(String? url, dynamic body);
Future<dynamic> getPutApiResponse(String? url, dynamic body);
Future<dynamic> getDeleteApiResponse(String? url);
}

View File

@@ -0,0 +1,157 @@
import 'dart:io';
import 'package:base_project/utils/managers/user_manager.dart';
import 'package:dio/dio.dart';
import '../exceptions/app_exceptions.dart';
import 'base_network_service.dart';
class NetworkApiService extends BaseNetworkService {
final Dio _dio = Dio();
NetworkApiService() {
// Optionally configure Dio, e.g. add interceptors
_dio.options.connectTimeout = const Duration(seconds: 30); // 30 seconds
_dio.options.receiveTimeout = const Duration(seconds: 30);
}
@override
Future<dynamic> getGetApiResponse(String? url) async {
try {
final token = UserManager().token;
// print("token..$token");
final headers = {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.get(
url!,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getPostApiResponse(String? url, dynamic body) async {
try {
final token = UserManager().token;
final headers = {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.post(
url!,
data: body,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getPutApiResponse(String? url, dynamic body) async {
try {
final token = UserManager().token;
final headers = {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.put(
url!,
data: body,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getDeleteApiResponse(String? url) async {
try {
final token = UserManager().token;
final headers = {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.delete(
url!,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
dynamic _handleResponse(Response response) {
switch (response.statusCode) {
case 200:
case 201:
try {
// Handle empty body
if (response.data == null || response.data.toString().isEmpty) {
return null;
}
return response.data;
} catch (e) {
throw FetchDataException('Error parsing response: $e');
}
case 400:
throw BadRequestException('Bad request: ${response.data}');
case 401:
throw UnauthorizedException('Unauthorized request: ${response.data}');
case 403:
throw ForbiddenException('Forbidden request: ${response.data}');
case 404:
throw NotFoundException('Not found: ${response.data}');
case 500:
throw InternalServerErrorException('Server error: ${response.data}');
default:
throw FetchDataException(
'Error while communicating with server: ${response.statusCode}');
}
}
dynamic _handleDioError(DioException error) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw FetchDataException("Request timed out.");
case DioExceptionType.badResponse:
return _handleResponse(error.response!);
case DioExceptionType.cancel:
throw FetchDataException("Request was cancelled.");
case DioExceptionType.connectionError:
throw FetchDataException("Connection failed due to internet issue.");
default:
throw FetchDataException("Unexpected error occurred.");
}
}
}

View File

@@ -0,0 +1,142 @@
import 'dart:io';
import 'package:dio/dio.dart';
import '../exceptions/app_exceptions.dart';
import 'no_token_base_network_service.dart';
class NoTokenNetworkApiService extends NoTokenBaseNetworkService {
final Dio _dio = Dio();
NetworkApiService() {
// Optionally configure Dio, e.g. add interceptors
_dio.options.connectTimeout = const Duration(seconds: 30); // 30 seconds
_dio.options.receiveTimeout = const Duration(seconds: 30);
}
@override
Future<dynamic> getGetApiResponse(String? url) async {
try {
final headers = {
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.get(
url!,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getPostApiResponse(String? url, dynamic body) async {
try {
final headers = {
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.post(
url!,
data: body,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getPutApiResponse(String? url, dynamic body) async {
try {
final headers = {
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.put(
url!,
data: body,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
@override
Future<dynamic> getDeleteApiResponse(String? url) async {
try {
final headers = {
'Content-Type': 'application/json', // Add other headers if needed
};
final response = await _dio.delete(
url!,
options: Options(headers: headers),
);
return _handleResponse(response);
} on DioException catch (e) {
return _handleDioError(e);
} on SocketException {
throw FetchDataException('No Internet Connection');
} catch (e) {
throw FetchDataException('An unexpected error occurred: $e');
}
}
dynamic _handleResponse(Response response) {
switch (response.statusCode) {
case 200:
case 201:
try {
// Handle empty body
if (response.data == null || response.data.toString().isEmpty) {
return null;
}
return response.data;
} catch (e) {
throw FetchDataException('Error parsing response: $e');
}
case 400:
throw BadRequestException('Bad request: ${response.data}');
case 401:
throw UnauthorizedException('Unauthorized request: ${response.data}');
case 403:
throw ForbiddenException('Forbidden request: ${response.data}');
case 404:
throw NotFoundException('Not found: ${response.data}');
case 500:
throw InternalServerErrorException('Server error: ${response.data}');
default:
throw FetchDataException(
'Error while communicating with server: ${response.statusCode}');
}
}
dynamic _handleDioError(DioException error) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw FetchDataException("Request timed out.");
case DioExceptionType.badResponse:
return _handleResponse(error.response!);
case DioExceptionType.cancel:
throw FetchDataException("Request was cancelled.");
case DioExceptionType.connectionError:
throw FetchDataException("Connection failed due to internet issue.");
default:
throw FetchDataException("Unexpected error occurred.");
}
}
}

View File

@@ -0,0 +1,7 @@
abstract class NoTokenBaseNetworkService {
Future<dynamic> getGetApiResponse(String? url);
Future<dynamic> getPostApiResponse(String? url, dynamic body);
Future<dynamic> getPutApiResponse(String? url, dynamic body);
Future<dynamic> getDeleteApiResponse(String? url);
}

View File

@@ -0,0 +1,36 @@
// import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// class NotificationService {
// final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// Future<void> initialize() async {
// const AndroidInitializationSettings initializationSettingsAndroid =
// AndroidInitializationSettings('@mipmap/ic_launcher');
// const InitializationSettings initializationSettings =
// InitializationSettings(android: initializationSettingsAndroid);
// await flutterLocalNotificationsPlugin.initialize(initializationSettings);
// }
// Future<void> showNotification(int id, String title, String body) async {
// const AndroidNotificationDetails androidPlatformChannelSpecifics =
// AndroidNotificationDetails(
// 'channel_id',
// 'channel_name',
// channelDescription: 'channel_description',
// importance: Importance.max,
// priority: Priority.high,
// );
// const NotificationDetails platformChannelSpecifics =
// NotificationDetails(android: androidPlatformChannelSpecifics);
// await flutterLocalNotificationsPlugin.show(
// id,
// title,
// body,
// platformChannelSpecifics,
// );
// }
// }

View File

@@ -0,0 +1,23 @@
import 'package:base_project/data/response/status.dart';
class ApiResponse<T> {
Status? status;
T? data;
String? message;
ApiResponse(this.status, this.data, this.message);
// Named constructor for loading state
ApiResponse.loading() : status = Status.LOADING;
// Named constructor for completed state
ApiResponse.success(this.data) : status = Status.SUCCESS;
// Named constructor for error state
ApiResponse.error(this.message) : status = Status.ERROR;
@override
String toString() {
return "Status: $status \n Message: $message \n Data: $data";
}
}

View File

@@ -0,0 +1 @@
enum Status {LOADING,SUCCESS,ERROR}