connect with backend
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../config/api_config.dart';
|
||||
import 'dio_client.dart';
|
||||
|
||||
class AuthService {
|
||||
final Dio _dio = Dio(BaseOptions(
|
||||
baseUrl: ApiConfig.baseUrl,
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(seconds: 15),
|
||||
// You can add headers here if needed:
|
||||
// headers: {'Accept': 'application/json'},
|
||||
));
|
||||
late final Dio _dio;
|
||||
|
||||
/// Calls /api/user/login with login_id and password
|
||||
AuthService(BuildContext context) {
|
||||
_dio = DioClient.getInstance(context);
|
||||
}
|
||||
|
||||
/// Login API
|
||||
Future<Map<String, dynamic>> login(String loginId, String password) async {
|
||||
try {
|
||||
final response = await _dio.post('/user/login', data: {
|
||||
@@ -18,45 +18,44 @@ class AuthService {
|
||||
'password': password,
|
||||
});
|
||||
|
||||
// Ensure we return a Map<String, dynamic>
|
||||
if (response.data is Map) {
|
||||
return Map<String, dynamic>.from(response.data);
|
||||
} else {
|
||||
return {
|
||||
'success': false,
|
||||
'message': 'Invalid response from server',
|
||||
};
|
||||
}
|
||||
return Map<String, dynamic>.from(response.data);
|
||||
} on DioException catch (e) {
|
||||
// Try to extract message from server response
|
||||
dynamic respData = e.response?.data;
|
||||
String message = 'Login failed';
|
||||
if (respData is Map && respData['message'] != null) {
|
||||
message = respData['message'].toString();
|
||||
} else if (e.message != null) {
|
||||
message = e.message!;
|
||||
}
|
||||
final data = e.response?.data;
|
||||
return {
|
||||
'success': false,
|
||||
'message': message,
|
||||
'message': data is Map && data['message'] != null
|
||||
? data['message']
|
||||
: e.message ?? 'Login failed'
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
'success': false,
|
||||
'message': e.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Optional: logout (if you have logout endpoint)
|
||||
Future<Map<String, dynamic>> logout(String token) async {
|
||||
try {
|
||||
final Dio dio = Dio(BaseOptions(baseUrl: ApiConfig.baseUrl));
|
||||
dio.options.headers['Authorization'] = 'Bearer $token';
|
||||
final response = await dio.post('/user/logout');
|
||||
return Map<String, dynamic>.from(response.data ?? {'success': true});
|
||||
} catch (e) {
|
||||
return {'success': false, 'message': e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
/// Logout API
|
||||
Future<Map<String, dynamic>> logout() async {
|
||||
try {
|
||||
final response = await _dio.post('/user/logout');
|
||||
return Map<String, dynamic>.from(response.data);
|
||||
} catch (e) {
|
||||
return {'success': false, 'message': e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
/// Refresh token
|
||||
Future<Map<String, dynamic>> refreshToken(String oldToken) async {
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
'/user/refresh',
|
||||
options: Options(headers: {
|
||||
'Authorization': 'Bearer $oldToken',
|
||||
}),
|
||||
);
|
||||
|
||||
return Map<String, dynamic>.from(response.data);
|
||||
} on DioException catch (e) {
|
||||
final msg = e.response?.data?['message'] ?? 'Refresh failed';
|
||||
return {'success': false, 'message': msg};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
lib/services/dashboard_service.dart
Normal file
20
lib/services/dashboard_service.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dio_client.dart';
|
||||
|
||||
class DashboardService {
|
||||
late final Dio _dio;
|
||||
|
||||
DashboardService(BuildContext context) {
|
||||
_dio = DioClient.getInstance(context);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getSummary() async {
|
||||
try {
|
||||
final res = await _dio.get('/user/order-summary');
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {'status': false, 'message': e.toString()};
|
||||
}
|
||||
}
|
||||
}
|
||||
33
lib/services/dio_client.dart
Normal file
33
lib/services/dio_client.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../config/api_config.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
import 'token_interceptor.dart';
|
||||
|
||||
class DioClient {
|
||||
static Dio? _dio; // Singleton instance
|
||||
|
||||
static Dio getInstance(BuildContext context) {
|
||||
if (_dio == null) {
|
||||
_dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: ApiConfig.baseUrl,
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(seconds: 15),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
final authProvider = Provider.of<AuthProvider>(context, listen: false);
|
||||
|
||||
_dio!.interceptors.add(
|
||||
TokenInterceptor(authProvider, context, _dio!),
|
||||
);
|
||||
}
|
||||
|
||||
return _dio!;
|
||||
}
|
||||
}
|
||||
34
lib/services/invoice_service.dart
Normal file
34
lib/services/invoice_service.dart
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
class InvoiceService {
|
||||
final Dio dio;
|
||||
InvoiceService(this.dio);
|
||||
|
||||
Future<Map<String, dynamic>> getAllInvoices() async {
|
||||
try {
|
||||
final res = await dio.get("/user/invoices");
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getInstallments(int invoiceId) async {
|
||||
try {
|
||||
final res = await dio.get("/user/invoice/$invoiceId/installments");
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
/// 🔵 NEW FUNCTION — Fetch Full Invoice Details
|
||||
Future<Map<String, dynamic>> getInvoiceDetails(int invoiceId) async {
|
||||
try {
|
||||
final res = await dio.get("/user/invoice/$invoiceId/details");
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
}
|
||||
29
lib/services/mark_list_service.dart
Normal file
29
lib/services/mark_list_service.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dio_client.dart';
|
||||
|
||||
class MarkListService {
|
||||
late Dio _dio;
|
||||
|
||||
MarkListService(BuildContext context) {
|
||||
_dio = DioClient.getInstance(context);
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> addMark(Map<String, dynamic> data) async {
|
||||
try {
|
||||
final res = await _dio.post('/add-mark-no', data: data);
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {'success': false, 'message': e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getMarks() async {
|
||||
try {
|
||||
final res = await _dio.get('/show-mark-list');
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {'success': false, 'message': e.toString()};
|
||||
}
|
||||
}
|
||||
}
|
||||
32
lib/services/order_service.dart
Normal file
32
lib/services/order_service.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
class OrderService {
|
||||
final Dio _dio;
|
||||
|
||||
OrderService(this._dio);
|
||||
|
||||
Future<Map<String, dynamic>> getOrders() async {
|
||||
final res = await _dio.get('/user/orders');
|
||||
return res.data;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getOrderDetails(String id) async {
|
||||
final res = await _dio.get('/user/order/$id/details');
|
||||
return res.data;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getShipment(String id) async {
|
||||
final res = await _dio.get('/user/order/$id/shipment');
|
||||
return res.data;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> getInvoice(String id) async {
|
||||
final res = await _dio.get('/user/order/$id/invoice');
|
||||
return res.data;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> trackOrder(String id) async {
|
||||
final res = await _dio.get('/user/order/$id/track');
|
||||
return res.data;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import '../config/api_config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dio_client.dart';
|
||||
|
||||
class RequestService {
|
||||
final Dio _dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: ApiConfig.baseUrl,
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
),
|
||||
);
|
||||
/// Send signup request to backend (after OTP verified)
|
||||
late final Dio _dio;
|
||||
|
||||
RequestService(BuildContext context) {
|
||||
_dio = DioClient.getInstance(context);
|
||||
}
|
||||
|
||||
/// Signup request after OTP
|
||||
Future<Map<String, dynamic>> sendSignup(Map<String, dynamic> payload) async {
|
||||
try {
|
||||
final resp = await _dio.post('/signup-request', data: payload);
|
||||
return resp.data is Map ? Map<String, dynamic>.from(resp.data) : {'status': true, 'message': 'OK'};
|
||||
return Map<String, dynamic>.from(resp.data);
|
||||
} on DioException catch (e) {
|
||||
return {
|
||||
'status': false,
|
||||
|
||||
37
lib/services/token_interceptor.dart
Normal file
37
lib/services/token_interceptor.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
|
||||
class TokenInterceptor extends Interceptor {
|
||||
final AuthProvider auth;
|
||||
final BuildContext context;
|
||||
final Dio dio;
|
||||
|
||||
TokenInterceptor(this.auth, this.context, this.dio);
|
||||
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
if (auth.token != null) {
|
||||
options.headers['Authorization'] = 'Bearer ${auth.token}';
|
||||
}
|
||||
handler.next(options);
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) async {
|
||||
if (err.response?.statusCode == 401 &&
|
||||
err.response?.data['message'] == 'Token has expired') {
|
||||
|
||||
final refreshed = await auth.tryRefreshToken(context);
|
||||
|
||||
if (refreshed) {
|
||||
err.requestOptions.headers['Authorization'] = 'Bearer ${auth.token}';
|
||||
final newResponse = await dio.fetch(err.requestOptions);
|
||||
return handler.resolve(newResponse);
|
||||
}
|
||||
}
|
||||
|
||||
handler.next(err);
|
||||
}
|
||||
}
|
||||
|
||||
48
lib/services/user_profile_service.dart
Normal file
48
lib/services/user_profile_service.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dio_client.dart';
|
||||
|
||||
class UserProfileService {
|
||||
late final Dio _dio;
|
||||
|
||||
UserProfileService(BuildContext context) {
|
||||
_dio = DioClient.getInstance(context);
|
||||
}
|
||||
|
||||
/// Get profile
|
||||
Future<Map<String, dynamic>> getProfile() async {
|
||||
try {
|
||||
final res = await _dio.get('/user/profile');
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
/// Update profile IMAGE only
|
||||
Future<Map<String, dynamic>> updateProfileImage(File image) async {
|
||||
try {
|
||||
final form = FormData.fromMap({
|
||||
"profile_image": await MultipartFile.fromFile(image.path),
|
||||
});
|
||||
|
||||
final res = await _dio.post('/user/profile-image', data: form);
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
/// Send profile update request (admin approval needed)
|
||||
Future<Map<String, dynamic>> sendUpdateRequest(Map<String, dynamic> data) async {
|
||||
try {
|
||||
final res = await _dio.post('/user/profile-update-request', data: data);
|
||||
return Map<String, dynamic>.from(res.data);
|
||||
|
||||
} catch (e) {
|
||||
return {"success": false, "message": e.toString()};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user