import 'dart:convert'; import 'package:http/http.dart' as http; class ApiException implements Exception { final int statusCode; final String message; const ApiException({required this.statusCode, required this.message}); @override String toString() => 'ApiException($statusCode): $message'; } class ApiClient { final String baseUrl; String? _token; ApiClient({required this.baseUrl}); void setToken(String token) => _token = token; void clearToken() => _token = null; Map get _headers => { 'Content-Type': 'application/json', if (_token != null) 'Authorization': 'Bearer $_token', }; Future post(String path, Map body) async { final response = await http.post( Uri.parse('$baseUrl$path'), headers: _headers, body: jsonEncode(body), ); return _handleResponse(response); } Future get(String path) async { final response = await http.get( Uri.parse('$baseUrl$path'), headers: _headers, ); return _handleResponse(response); } dynamic _handleResponse(http.Response response) { if (response.body.isEmpty) return null; final data = jsonDecode(response.body); if (response.statusCode >= 200 && response.statusCode < 300) { return data; } final detail = data is Map ? (data['detail'] ?? 'Unknown error') : 'Unknown error'; throw ApiException(statusCode: response.statusCode, message: detail.toString()); } }