import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; class NetworkManager { final Dio mainDio; NetworkManager() : mainDio = Dio( BaseOptions( // baseUrl: 'https://stage.cura-bau.de', connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), contentType: 'application/json', headers: {'Accept': 'application/json'}, ), ); Future init() async { await addInterceptors(); } Future addInterceptors() async { final requestInterceptor = InterceptorsWrapper( onRequest: (options, handler) { // TODO: add more return handler.next(options); }, ); mainDio.interceptors.add(requestInterceptor); } Future makeRequest( String endpoint, T Function(Map) fromJson, { String method = 'GET', FormData? data, }) async { SharedPreferences prefs = await SharedPreferences.getInstance(); Dio dioInstance = mainDio; await addInterceptors(); Future makeApiCall(String token, String url) async { final headers = token.isEmpty ? {} : {'Authorization': 'Bearer $token'}; switch (method.toUpperCase()) { case 'POST': return await dioInstance.post( url + endpoint, data: data, options: Options(headers: headers), ); case 'PUT': return await dioInstance.put( url + endpoint, data: data, options: Options(headers: headers), ); case 'PATCH': return await dioInstance.patch( url + endpoint, data: data, options: Options(headers: headers), ); case 'DELETE': return await dioInstance.delete( url + endpoint, data: data, options: Options(headers: headers), ); case 'GET': return await dioInstance.get( url + endpoint, data: data, options: Options(headers: headers), ); default: return await dioInstance.get( url + endpoint, options: Options(headers: headers), ); } } try { String? bearerToken = prefs.getString('bearer'); String? url = prefs.getString('url'); Response res = await makeApiCall(bearerToken ?? '', url ?? ''); switch (res.statusCode) { case 200: case 201: return fromJson(res.data); case 401: break; case 403: throw Exception('Forbidden: ${res.data['message']}'); case 404: throw Exception('Not found: ${res.data['message']}'); case 423: throw Exception('Locked: ${res.data['message']}'); case 500: throw Exception('Internal server error: ${res.data['message']}'); default: throw Exception('Error: ${res.data['message']}'); } } on DioException catch (e) { if (e.response?.statusCode == 401) { // await api.refreshToken(); String? bearerToken = prefs.getString('bearer'); String? url = prefs.getString('url'); Response res = await makeApiCall(bearerToken ?? '', url ?? ''); if (res.statusCode == 200 || res.statusCode == 201) { return fromJson(res.data); } throw Exception(e.message ?? 'Error occurred'); } } catch (e) { throw Exception(e.toString()); } throw Exception('Unhandled error occurred'); } }