init
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../config/api_config.dart';
|
||||
import '../models/models.dart';
|
||||
|
||||
class ApiException implements Exception {
|
||||
ApiException(this.message, {this.statusCode});
|
||||
|
||||
final String message;
|
||||
final int? statusCode;
|
||||
|
||||
@override
|
||||
String toString() => message;
|
||||
}
|
||||
|
||||
class ApiClient {
|
||||
ApiClient() {
|
||||
dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: resolveApiBaseUrl(),
|
||||
connectTimeout: const Duration(seconds: 15),
|
||||
receiveTimeout: const Duration(seconds: 15),
|
||||
headers: const {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
dio.interceptors.add(
|
||||
InterceptorsWrapper(
|
||||
onRequest: (options, handler) {
|
||||
if (token != null && token!.isNotEmpty) {
|
||||
options.headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
handler.next(options);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late final Dio dio;
|
||||
String? token;
|
||||
|
||||
Future<({String token, AppUser user})> staffLogin(String phone, String password) {
|
||||
return _send(
|
||||
dio.post('/auth/staff-login', data: {'phone': phone, 'password': password}),
|
||||
(data) {
|
||||
final map = data as Map<String, dynamic>;
|
||||
return (
|
||||
token: map['token'] as String,
|
||||
user: AppUser.fromJson(map['user'] as Map<String, dynamic>),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<({String requestId, String secret})> dealerLogin(String phone) {
|
||||
return _send(dio.post('/auth/dealer-login', data: {'phone': phone}), (data) {
|
||||
final map = data as Map<String, dynamic>;
|
||||
return (requestId: map['requestId'] as String, secret: map['secret'] as String);
|
||||
});
|
||||
}
|
||||
|
||||
Future<DealerLoginStatus> dealerLoginStatus(String requestId, String secret) {
|
||||
return _send(
|
||||
dio.get('/auth/dealer-login/$requestId', queryParameters: {'secret': secret}),
|
||||
(data) => DealerLoginStatus.fromJson(data as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<LoginRequestItem>> loginRequests() {
|
||||
return _send(dio.get('/auth/login-requests'), (data) => _list(data, LoginRequestItem.fromJson));
|
||||
}
|
||||
|
||||
Future<void> approveLogin(String id) {
|
||||
return _send(dio.post('/auth/login-requests/$id/approve'), (_) {});
|
||||
}
|
||||
|
||||
Future<void> rejectLogin(String id) {
|
||||
return _send(dio.post('/auth/login-requests/$id/reject'), (_) {});
|
||||
}
|
||||
|
||||
Future<AppUser> me() {
|
||||
return _send(
|
||||
dio.get('/auth/me'),
|
||||
(data) => AppUser.fromJson(data as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<Dealer>> dealers() {
|
||||
return _send(dio.get('/dealers'), (data) => _list(data, Dealer.fromJson));
|
||||
}
|
||||
|
||||
Future<List<StockItem>> stocks({String? dealerId}) {
|
||||
return _send(
|
||||
dio.get(
|
||||
'/stocks',
|
||||
queryParameters: {
|
||||
if (dealerId != null && dealerId.isNotEmpty) 'dealerId': dealerId,
|
||||
},
|
||||
),
|
||||
(data) => _list(data, StockItem.fromJson),
|
||||
);
|
||||
}
|
||||
|
||||
Future<StockItem> createStock(Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.post('/stocks', data: body),
|
||||
(data) => StockItem.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<StockItem> updateStage(String chassisNumber, Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.patch('/stocks/$chassisNumber/stage', data: body),
|
||||
(data) => StockItem.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<StockItem> transferStock(String chassisNumber, String dealerId) {
|
||||
return _send(
|
||||
dio.post('/stocks/$chassisNumber/transfer', data: {'dealerId': dealerId}),
|
||||
(data) => StockItem.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<EventPlan>> events({String? dealerId, String? planType}) {
|
||||
return _send(
|
||||
dio.get(
|
||||
'/events',
|
||||
queryParameters: {
|
||||
if (dealerId != null && dealerId.isNotEmpty) 'dealerId': dealerId,
|
||||
if (planType != null && planType.isNotEmpty) 'planType': planType,
|
||||
},
|
||||
),
|
||||
(data) => _list(data, EventPlan.fromJson),
|
||||
);
|
||||
}
|
||||
|
||||
Future<EventPlan> createEvent(Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.post('/events', data: body),
|
||||
(data) => EventPlan.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<ServicePoint>> servicePoints({String? district, String? search}) {
|
||||
return _send(
|
||||
dio.get(
|
||||
'/service-points',
|
||||
queryParameters: {
|
||||
if (district != null && district.isNotEmpty) 'district': district,
|
||||
if (search != null && search.isNotEmpty) 'search': search,
|
||||
},
|
||||
),
|
||||
(data) => _list(data, ServicePoint.fromJson),
|
||||
);
|
||||
}
|
||||
|
||||
Future<ServicePoint> createServicePoint(Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.post('/service-points', data: body),
|
||||
(data) => ServicePoint.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Dealer> createDealer(Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.post('/admin/dealers', data: body),
|
||||
(data) => Dealer.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteDealer(String id) {
|
||||
return _send(dio.delete('/admin/dealers/$id'), (_) {});
|
||||
}
|
||||
|
||||
Future<List<Dealer>> adminDealers() {
|
||||
return _send(dio.get('/admin/dealers'), (data) => _list(data, Dealer.fromJson));
|
||||
}
|
||||
|
||||
Future<List<AppUser>> salesReps() {
|
||||
return _send(dio.get('/admin/sales-reps'), (data) => _list(data, AppUser.fromJson));
|
||||
}
|
||||
|
||||
Future<AppUser> createSalesRep(Map<String, dynamic> body) {
|
||||
return _send(
|
||||
dio.post('/admin/sales-reps', data: body),
|
||||
(data) => AppUser.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<AppUser> assignDealer({
|
||||
required String salesRepId,
|
||||
required String dealerId,
|
||||
required bool assigned,
|
||||
}) {
|
||||
return _send(
|
||||
dio.patch(
|
||||
'/admin/assign-dealer',
|
||||
data: {
|
||||
'salesRepId': salesRepId,
|
||||
'dealerId': dealerId,
|
||||
'assigned': assigned,
|
||||
},
|
||||
),
|
||||
(data) => AppUser.fromJson((data as Map<String, dynamic>)['data'] as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
Future<T> _send<T>(Future<Response<dynamic>> request, T Function(dynamic data) parse) async {
|
||||
try {
|
||||
final response = await request;
|
||||
return parse(response.data);
|
||||
} on DioException catch (error) {
|
||||
final data = error.response?.data;
|
||||
final message = data is Map && data['message'] is String
|
||||
? data['message'] as String
|
||||
: 'Network request failed';
|
||||
throw ApiException(message, statusCode: error.response?.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
List<T> _list<T>(dynamic data, T Function(Map<String, dynamic>) parse) {
|
||||
final raw = (data as Map<String, dynamic>)['data'] as List<dynamic>;
|
||||
return raw.map((item) => parse(item as Map<String, dynamic>)).toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user