added certificate page
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
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]);
|
||||
}
|
||||
Reference in New Issue
Block a user