Skip to content

Commit 089809f

Browse files
fixes part 2
1 parent d247aa5 commit 089809f

25 files changed

Lines changed: 815 additions & 529 deletions

File tree

school_data_hub_flutter/lib/common/audio/presentation/audio_button.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import 'package:school_data_hub_flutter/core/auth/auth_clearance_helper.dart';
1111
/// A button that displays an audio thumbnail and handles playback.
1212
///
1313
/// On tap, it pre-loads the audio and shows the player overlay.
14-
/// On long press (admin only), it allows deletion of the audio file.
14+
/// On long press (authorized only), it allows deletion of the audio file.
1515
class AudioButton extends StatefulWidget {
1616
const AudioButton({required this.file, required this.onDelete, super.key});
1717

school_data_hub_flutter/lib/common/widgets/hub_document/hub_documents_section.dart

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class HubDocumentsSectionWidget extends StatelessWidget {
2525
final Future<void> Function(File? file) onImageFileCaptured;
2626

2727
/// Callback when a file is recorded (audio).
28-
final Future<void> Function(File? file, Map<String, dynamic>? fileInfo)?
28+
final Future<void> Function(File? file, String? fileInfo)?
2929
onAudioFileRecorded;
3030

3131
/// Callback when a document should be removed.
@@ -127,14 +127,11 @@ class HubDocumentsSectionWidget extends StatelessWidget {
127127
const Gap(10),
128128
],
129129
if (totalCount < maxDocuments) ...[
130-
if (withSpacerToButtons) const Spacer(),
130+
withSpacerToButtons ? const Spacer() : const Gap(15),
131131
MediaCaptureButtons(
132132
onFileCaptured: onImageFileCaptured,
133133
onFileRecorded: (file, fileInfo) {
134-
onAudioFileRecorded?.call(
135-
file,
136-
fileInfo != null ? {'info': fileInfo} : null,
137-
);
134+
onAudioFileRecorded?.call(file, fileInfo);
138135
},
139136
iconSize: 20,
140137
padding: captureButtonPadding ?? const EdgeInsets.all(11),

school_data_hub_flutter/lib/features/books/data/pupil_book_lending_api_service.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,40 @@ class PupilBookLendingApiService {
5656
return lending;
5757
}
5858

59+
//- Add file to lending
60+
61+
Future<PupilBookLending?> addFileToPupilBookLending({
62+
required String lendingId,
63+
required String filePath,
64+
required String addedBy,
65+
}) async {
66+
final lending = await ClientHelper.apiCall(
67+
call: () => _client.pupilBookLending.addFileToPupilBookLending(
68+
lendingId,
69+
filePath,
70+
addedBy,
71+
),
72+
errorMessage: 'Fehler beim Hinzufügen der Datei zur Ausleihe',
73+
);
74+
return lending;
75+
}
76+
77+
//- delete file from lending
78+
79+
Future<bool?> removeFileFromPupilBookLending({
80+
required String lendingId,
81+
required String fileId,
82+
}) async {
83+
final success = await ClientHelper.apiCall(
84+
call: () => _client.pupilBookLending.removeFileFromPupilBookLending(
85+
lendingId,
86+
fileId,
87+
),
88+
errorMessage: 'Fehler beim Entfernen der Datei von der Ausleihe',
89+
);
90+
return success;
91+
}
92+
5993
//- delete
6094

6195
Future<bool?> deletePupilBookLending({required String lendingId}) async {

school_data_hub_flutter/lib/features/books/domain/book_helper.dart

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1+
import 'package:flutter_it/flutter_it.dart';
12
import 'package:school_data_hub_client/school_data_hub_client.dart';
3+
import 'package:school_data_hub_flutter/features/books/domain/pupil_book_lending_manager.dart';
24
import 'package:school_data_hub_flutter/features/pupil/domain/pupil_proxy_manager.dart';
3-
import 'package:flutter_it/flutter_it.dart';
45

56
enum BookBorrowStatus { since2Weeks, since3Weeks, since5weeks }
67

78
class BookHelpers {
9+
static int totalPupilBookLendings() {
10+
return di<PupilBookLendingManager>().allPupilBookLendings.length;
11+
}
12+
13+
static int totalOpenPupilBookLendings() {
14+
return di<PupilBookLendingManager>().allPupilBookLendings
15+
.where((lending) => lending.returnedAt == null)
16+
.length;
17+
}
18+
819
static List<PupilBookLending> pupilBookLendingsLinkedToLibraryBook({
920
required int libraryBookId,
1021
}) {
1122
// Get all pupil book lendings
1223
final allPupilBookLendings = di<PupilProxyManager>().allPupils
13-
.map((pupil) => pupil.pupilBookLendings ?? <PupilBookLending>[])
24+
.map((pupil) => pupil.pupilBookLendings)
1425
.expand((element) => element)
1526
.toList();
1627

school_data_hub_flutter/lib/features/books/domain/pupil_book_lending_manager.dart

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import 'dart:io';
2+
13
import 'package:flutter/foundation.dart';
24
import 'package:flutter_it/flutter_it.dart';
35
import 'package:school_data_hub_client/school_data_hub_client.dart';
6+
import 'package:school_data_hub_flutter/app_utils/custom_encrypter.dart';
7+
import 'package:school_data_hub_flutter/common/data/file_upload_service.dart';
48
import 'package:school_data_hub_flutter/common/services/notification_service.dart';
59
import 'package:school_data_hub_flutter/core/session/hub_session_manager.dart';
610
import 'package:school_data_hub_flutter/features/books/data/pupil_book_lending_api_service.dart';
@@ -11,6 +15,7 @@ class PupilBookLendingManager with ChangeNotifier {
1115

1216
final Map<int, List<PupilBookLending>> _pupilBookLendings = {};
1317
final Map<String, PupilBookLending> _lendingIdMap = {};
18+
final Map<int, List<PupilBookLending>> _isbnPupilBookLendingsMap = {};
1419
final _pupilBookLendingApiService = PupilBookLendingApiService();
1520

1621
Future<PupilBookLendingManager> init() async {
@@ -45,6 +50,14 @@ class PupilBookLendingManager with ChangeNotifier {
4550
} else {
4651
_pupilBookLendings[lending.pupilId] = [lending];
4752
}
53+
if (lending.libraryBook != null) {
54+
final isbn = lending.isbn;
55+
if (_isbnPupilBookLendingsMap.containsKey(isbn)) {
56+
_isbnPupilBookLendingsMap[isbn]!.add(lending);
57+
} else {
58+
_isbnPupilBookLendingsMap[isbn] = [lending];
59+
}
60+
}
4861
// Add to lending ID map for quick lookups
4962
_lendingIdMap[lending.lendingId] = lending;
5063
}
@@ -59,6 +72,17 @@ class PupilBookLendingManager with ChangeNotifier {
5972
_pupilBookLendings.remove(lending.pupilId);
6073
}
6174
}
75+
if (lending.libraryBook != null) {
76+
final isbn = lending.isbn;
77+
if (_isbnPupilBookLendingsMap.containsKey(isbn)) {
78+
_isbnPupilBookLendingsMap[isbn]!.removeWhere(
79+
(l) => l.lendingId == lending.lendingId,
80+
);
81+
if (_isbnPupilBookLendingsMap[isbn]!.isEmpty) {
82+
_isbnPupilBookLendingsMap.remove(isbn);
83+
}
84+
}
85+
}
6286
// Remove from lending ID map
6387
_lendingIdMap.remove(lending.lendingId);
6488
}
@@ -77,6 +101,21 @@ class PupilBookLendingManager with ChangeNotifier {
77101
} else {
78102
_pupilBookLendings[lending.pupilId] = [lending];
79103
}
104+
if (lending.libraryBook != null) {
105+
final isbn = lending.isbn;
106+
if (_isbnPupilBookLendingsMap.containsKey(isbn)) {
107+
final index = _isbnPupilBookLendingsMap[isbn]!.indexWhere(
108+
(l) => l.lendingId == lending.lendingId,
109+
);
110+
if (index != -1) {
111+
_isbnPupilBookLendingsMap[isbn]![index] = lending;
112+
} else {
113+
_isbnPupilBookLendingsMap[isbn]!.add(lending);
114+
}
115+
} else {
116+
_isbnPupilBookLendingsMap[isbn] = [lending];
117+
}
118+
}
80119
// Update in lending ID map
81120
_lendingIdMap[lending.lendingId] = lending;
82121
}
@@ -193,6 +232,88 @@ class PupilBookLendingManager with ChangeNotifier {
193232
);
194233
}
195234

235+
//- add book lending file
236+
Future<void> addPupilBookLendingFile(
237+
File file, {
238+
required PupilBookLending pupilBookLending,
239+
String? fileInfo,
240+
}) async {
241+
try {
242+
final encryptedFile = await customEncrypter.encryptFile(file);
243+
final fileResponse = await ClientFileUpload.uploadFile(
244+
file: encryptedFile,
245+
storageId: StorageId.private,
246+
folder: ServerStorageFolder.documents,
247+
fileInfo: fileInfo,
248+
);
249+
250+
if (!fileResponse.success) {
251+
_notificationService.showSnackBar(
252+
NotificationType.error,
253+
'Die Datei konnte nicht hochgeladen werden!',
254+
);
255+
return;
256+
}
257+
258+
final pupilBookLendingWithFile = await _pupilBookLendingApiService
259+
.addFileToPupilBookLending(
260+
lendingId: pupilBookLending.lendingId,
261+
filePath: fileResponse.path!,
262+
addedBy: _hubSessionManager.userName!,
263+
);
264+
265+
if (pupilBookLendingWithFile == null) {
266+
return;
267+
}
268+
269+
_updatePupilBookLendingInCollections(pupilBookLendingWithFile);
270+
notifyListeners();
271+
272+
_notificationService.showSnackBar(
273+
NotificationType.success,
274+
'Datei zum Leihvorgang hinzugefügt',
275+
);
276+
} catch (e) {
277+
_notificationService.showSnackBar(
278+
NotificationType.error,
279+
'Fehler beim Hochladen der Datei: $e',
280+
);
281+
}
282+
}
283+
284+
//- delete file from lending
285+
Future<void> deletePupilBookLendingFile({
286+
required PupilBookLending pupilBookLending,
287+
required String fileId,
288+
}) async {
289+
try {
290+
final success = await _pupilBookLendingApiService
291+
.removeFileFromPupilBookLending(
292+
lendingId: pupilBookLending.lendingId,
293+
fileId: fileId,
294+
);
295+
296+
if (success == null) {
297+
return;
298+
}
299+
pupilBookLending.pupilBookLendingFiles!.removeWhere(
300+
(file) => file.documentId == fileId,
301+
);
302+
303+
notifyListeners();
304+
305+
_notificationService.showSnackBar(
306+
NotificationType.success,
307+
'Datei aus Leihvorgang entfernt',
308+
);
309+
} catch (e) {
310+
_notificationService.showSnackBar(
311+
NotificationType.error,
312+
'Fehler beim Löschen der Datei: $e',
313+
);
314+
}
315+
}
316+
196317
//- delete
197318

198319
Future<void> deletePupilBookLending({required String lendingId}) async {

0 commit comments

Comments
 (0)