114 lines
3.2 KiB
Dart
114 lines
3.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:mime/mime.dart';
|
|
|
|
import '../config/api_config.dart';
|
|
|
|
class MedicalCertificatesApi {
|
|
static Uri _u(String path, [Map<String, String>? q]) =>
|
|
Uri.parse('${ApiConfig.phpApiBase}/$path').replace(queryParameters: q);
|
|
|
|
static Future<List<Map<String, dynamic>>> list({
|
|
required String token,
|
|
}) async {
|
|
final res = await http.get(
|
|
_u('api_medical_certificates_list.php'),
|
|
headers: {'Accept': 'application/json', 'Authorization': 'Bearer $token'},
|
|
);
|
|
|
|
if (res.statusCode != 200) {
|
|
throw Exception('List failed (${res.statusCode}): ${res.body}');
|
|
}
|
|
|
|
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
|
if (data['success'] != true) {
|
|
throw Exception(data['message'] ?? 'List error');
|
|
}
|
|
|
|
final certs = (data['certificates'] as List).cast<Map<String, dynamic>>();
|
|
return certs;
|
|
}
|
|
|
|
static Future<Map<String, dynamic>> upload({
|
|
required String token,
|
|
required File file,
|
|
required String documentName,
|
|
required String expiryDateYYYYMMDD,
|
|
String? notes,
|
|
}) async {
|
|
final req = http.MultipartRequest(
|
|
'POST',
|
|
_u('api_medical_certificates_upload.php'),
|
|
);
|
|
|
|
req.headers.addAll({
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Bearer $token',
|
|
});
|
|
|
|
req.fields['document_name'] = documentName.trim().isEmpty
|
|
? 'certificato'
|
|
: documentName.trim();
|
|
req.fields['expiry_date'] = expiryDateYYYYMMDD;
|
|
if (notes != null && notes.trim().isNotEmpty)
|
|
req.fields['notes'] = notes.trim();
|
|
|
|
final mimeType = lookupMimeType(file.path) ?? 'application/octet-stream';
|
|
|
|
req.files.add(
|
|
await http.MultipartFile.fromPath(
|
|
'certificate',
|
|
file.path,
|
|
contentType: _parseMediaType(mimeType),
|
|
),
|
|
);
|
|
|
|
final streamed = await req.send();
|
|
final body = await streamed.stream.bytesToString();
|
|
|
|
if (streamed.statusCode != 200) {
|
|
throw Exception('Upload failed (${streamed.statusCode}): $body');
|
|
}
|
|
|
|
final data = jsonDecode(body) as Map<String, dynamic>;
|
|
if (data['success'] != true) {
|
|
throw Exception(data['message'] ?? 'Upload error');
|
|
}
|
|
return (data['certificate'] as Map).cast<String, dynamic>();
|
|
}
|
|
|
|
static Future<void> delete({
|
|
required String token,
|
|
required int certId,
|
|
}) async {
|
|
// usiamo POST fallback (più compatibile)
|
|
final res = await http.post(
|
|
_u('api_medical_certificates_delete.php'),
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Bearer $token',
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: 'cert_id=$certId',
|
|
);
|
|
|
|
if (res.statusCode != 200) {
|
|
throw Exception('Delete failed (${res.statusCode}): ${res.body}');
|
|
}
|
|
|
|
final data = jsonDecode(res.body) as Map<String, dynamic>;
|
|
if (data['success'] != true) {
|
|
throw Exception(data['message'] ?? 'Delete error');
|
|
}
|
|
}
|
|
}
|
|
|
|
// helper per MediaType senza dipendenze extra
|
|
http.MediaType? _parseMediaType(String mime) {
|
|
final parts = mime.split('/');
|
|
if (parts.length != 2) return null;
|
|
return http.MediaType(parts[0], parts[1]);
|
|
}
|