100 lines
2.6 KiB
Dart
100 lines
2.6 KiB
Dart
import 'package:dio/dio.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../config/app_config.dart';
|
|
import '../auth/auth_provider.dart';
|
|
|
|
/// Client HTTP Dio configuré pour l'API Laverie.
|
|
class ApiClient {
|
|
ApiClient({
|
|
required this.baseUrl,
|
|
this.getAccessToken,
|
|
this.onUnauthorized,
|
|
}) : _dio = Dio(
|
|
BaseOptions(
|
|
baseUrl: baseUrl,
|
|
connectTimeout: const Duration(seconds: 15),
|
|
receiveTimeout: const Duration(seconds: 30),
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
),
|
|
) {
|
|
_dio.interceptors.add(
|
|
InterceptorsWrapper(
|
|
onRequest: (options, handler) async {
|
|
final token = await getAccessToken?.call();
|
|
if (token != null && token.isNotEmpty) {
|
|
options.headers['Authorization'] = 'Bearer $token';
|
|
}
|
|
handler.next(options);
|
|
},
|
|
onError: (error, handler) async {
|
|
if (error.response?.statusCode == 401) {
|
|
await onUnauthorized?.call();
|
|
}
|
|
handler.next(error);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
final String baseUrl;
|
|
final Future<String?> Function()? getAccessToken;
|
|
final Future<void> Function()? onUnauthorized;
|
|
final Dio _dio;
|
|
|
|
Dio get dio => _dio;
|
|
|
|
Future<Response<T>> get<T>(
|
|
String path, {
|
|
Map<String, dynamic>? queryParameters,
|
|
}) {
|
|
return _dio.get<T>(path, queryParameters: queryParameters);
|
|
}
|
|
|
|
Future<Response<T>> post<T>(
|
|
String path, {
|
|
dynamic data,
|
|
Map<String, dynamic>? queryParameters,
|
|
}) {
|
|
return _dio.post<T>(path, data: data, queryParameters: queryParameters);
|
|
}
|
|
|
|
Future<Response<T>> patch<T>(
|
|
String path, {
|
|
dynamic data,
|
|
Map<String, dynamic>? queryParameters,
|
|
}) {
|
|
return _dio.patch<T>(path, data: data, queryParameters: queryParameters);
|
|
}
|
|
|
|
Future<Response<T>> put<T>(
|
|
String path, {
|
|
dynamic data,
|
|
Map<String, dynamic>? queryParameters,
|
|
}) {
|
|
return _dio.put<T>(path, data: data, queryParameters: queryParameters);
|
|
}
|
|
|
|
Future<Response<T>> delete<T>(
|
|
String path, {
|
|
dynamic data,
|
|
Map<String, dynamic>? queryParameters,
|
|
}) {
|
|
return _dio.delete<T>(path, data: data, queryParameters: queryParameters);
|
|
}
|
|
}
|
|
|
|
/// Fournisseur Riverpod du client API (injecte le token depuis l'état auth).
|
|
final apiClientProvider = Provider<ApiClient>((ref) {
|
|
final authNotifier = ref.read(authProvider.notifier);
|
|
|
|
return ApiClient(
|
|
baseUrl: kApiBaseUrl,
|
|
getAccessToken: () async => ref.read(authProvider).accessToken,
|
|
onUnauthorized: () async => authNotifier.logout(),
|
|
);
|
|
});
|