import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; // For cache storage import 'package:file/memory.dart'; import 'sheet.dart'; class ApiClient { final String baseUrl = 'http://localhost:8080/api'; // Replace with your API base URL String? _token; // Holds the JWT token after login /// Checks if the user is authenticated bool get isAuthenticated => _token != null; /// Login and store the JWT token Future login(String username, String password) async { print("Logging in..."); try { final url = '$baseUrl/login'; final response = await http.post( Uri.parse(url), headers: {'Content-Type': 'application/json'}, body: jsonEncode({ 'email': username, 'password': password, }), ); if (response.statusCode == 200) { _token = jsonDecode(response.body); print('Login successful, token: $_token'); return true; } else { print('Login failed: ${response.statusCode}, ${response.body}'); } } catch (e) { print('Error during login: $e'); } return false; } /// Logout and clear the token void logout() { _token = null; print('Logged out successfully.'); } /// Make a GET request Future get(String endpoint, {bool isBinary = false}) async { try { final url = '$baseUrl$endpoint'; final headers = { 'Authorization': 'Bearer $_token', if (!isBinary) 'Content-Type': 'application/json', }; final response = await http.get(Uri.parse(url), headers: headers); if (response.statusCode == 200) { return response; } else { print('GET request failed: ${response.statusCode} ${response.body}'); } } catch (e) { print('Error during GET request: $e'); } return null; } /// Make a POST request Future post( String endpoint, Map body) async { try { final url = '$baseUrl$endpoint'; final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', }; final response = await http.post( Uri.parse(url), headers: headers, body: jsonEncode(body), ); if (response.statusCode == 200 || response.statusCode == 201) { return response; } else { print('POST request failed: ${response.statusCode} ${response.body}'); } } catch (e) { print('Error during POST request: $e'); } return null; } /// Make a POST request with form data Future postFormData(String endpoint, String body) async { try { final url = '$baseUrl$endpoint'; final headers = { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/x-www-form-urlencoded', }; final response = await http.post( Uri.parse(url), headers: headers, body: body, ); if (response.statusCode == 200 || response.statusCode == 201) { return response; } else { print( 'POST Form Data request failed: ${response.statusCode} ${response.body}'); } } catch (e) { print('Error during POST Form Data request: $e'); } return null; } Future> fetchSheets({String sortBy = "last_opened desc"}) async { try { final bodyFormData = { "page": 1, "limit": "1000", "sort_by": sortBy, }; print("doing post..."); final response = await postFormData("/sheets", jsonEncode(bodyFormData)); print("got response..."); if (response == null) { print("Empty reponse"); return List.empty(); } if (response.statusCode == 200) { final data = jsonDecode(response.body); print("Data: $data"); return (data['rows'] as List) .map((sheet) => Sheet.fromJson(sheet as Map)) .toList(); } else { print('Failed to fetch sheets with status: ${response.statusCode}'); print('Response: ${response.body}'); } } catch (e) { print('Error during fetching sheets: $e'); } return List.empty(); } Future getPdfFileCached(String sheetUuid) async { try { // Get the cache directory print("Creating cache dir..."); // final cacheDir = kIsWeb // ? await MemoryFileSystem().systemTempDirectory.createTemp('cache') // : await getTemporaryDirectory(); final cacheDir = await getTemporaryDirectory(); final cachedPdfPath = '${cacheDir.path}/$sheetUuid.pdf'; print("cache dir created"); // Check if the file already exists in the cache final cachedFile = File(cachedPdfPath); print("file created: $cachedFile"); if (await cachedFile.exists()) { print("PDF found in cache: $cachedPdfPath"); return cachedFile; } // Make the authenticated API call print("getting response"); final response = await this.get('/sheet/pdf/$sheetUuid', isBinary: true); print("got response"); if (response != null && response.statusCode == 200) { // Save the fetched file to the cache // print("writing file...: $cachedFile"); await cachedFile.writeAsBytes(response.bodyBytes); print("PDF downloaded and cached at: $cachedPdfPath"); return cachedFile; } else { print("Failed to fetch PDF from API. Status: ${response?.statusCode}"); } } catch (e) { print("Error fetching PDF: $e"); } return null; } }