Merge pull request 'feature/unit2/UNIT2-#20Implement-attachment-feature' (#28) from feature/unit2/UNIT2-#20Implement-attachment-feature into develop
Reviewed-on: http://git.agusandelnorte.gov.ph:3000/SoftwareDevelopmentSection/unit2-null-safety-repository/pulls/28feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
commit
58c8435f9e
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="461.000000pt" height="547.000000pt" viewBox="0 0 461.000000 547.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,547.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M291 5399 c-105 -20 -175 -79 -208 -174 -17 -47 -18 -189 -18 -2515
|
||||
0 -2388 1 -2467 19 -2519 25 -71 86 -132 157 -157 52 -18 121 -19 2069 -19
|
||||
1948 0 2017 1 2069 19 68 23 131 85 157 152 18 47 19 105 22 1769 2 1189 -1
|
||||
1740 -8 1785 -6 36 -25 94 -42 130 -28 60 -89 124 -727 761 -523 522 -709 702
|
||||
-747 722 -112 59 -64 57 -1439 56 -693 -1 -1280 -5 -1304 -10z m2599 -309 c13
|
||||
-8 16 -85 20 -562 5 -551 5 -553 28 -603 41 -89 97 -132 200 -154 35 -7 225
|
||||
-11 565 -11 305 0 518 -4 527 -10 13 -8 15 -52 18 -275 l3 -265 -1941 0 -1940
|
||||
0 2 919 c3 879 4 920 22 939 10 12 28 23 40 25 46 9 2441 6 2456 -3z m-611
|
||||
-2175 c170 -41 263 -149 264 -308 1 -225 -152 -356 -418 -361 l-95 -1 -2 -185
|
||||
-3 -185 -117 -3 -118 -3 0 520 0 520 33 5 c66 11 96 13 242 14 103 1 170 -3
|
||||
214 -13z m1176 -5 c43 -11 80 -22 82 -24 6 -5 -37 -169 -47 -179 -4 -5 -34 0
|
||||
-66 9 -41 13 -93 18 -169 18 -100 0 -116 -2 -173 -28 -115 -53 -172 -143 -180
|
||||
-283 -9 -164 53 -281 180 -338 53 -24 77 -29 148 -29 125 -1 120 -6 120 124
|
||||
l0 110 -85 0 -85 0 0 90 0 90 200 0 200 0 0 -274 0 -275 -52 -14 c-163 -47
|
||||
-385 -56 -508 -23 -234 64 -370 247 -370 501 0 263 151 459 402 525 104 27
|
||||
297 27 403 0z m-1867 -392 c-3 -391 -4 -405 -26 -459 -30 -76 -81 -132 -150
|
||||
-166 -50 -24 -70 -28 -167 -31 -60 -2 -128 1 -150 5 l-40 9 1 50 c0 27 4 70 8
|
||||
97 l7 47 42 -7 c66 -12 145 -7 173 12 14 9 34 35 45 58 17 39 19 71 19 415 l0
|
||||
372 121 0 120 0 -3 -402z m2660 -1543 l-3 -604 -23 -23 -23 -23 -1889 0 -1889
|
||||
0 -23 23 -23 23 -3 604 -3 605 1941 0 1941 0 -3 -605z"/>
|
||||
<path d="M2030 2590 l0 -160 73 0 c128 1 197 52 204 154 8 109 -60 166 -199
|
||||
166 l-78 0 0 -160z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="454.000000pt" height="545.000000pt" viewBox="0 0 454.000000 545.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,545.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M251 5399 c-105 -20 -175 -79 -208 -174 -17 -47 -18 -189 -18 -2515
|
||||
0 -2388 1 -2467 19 -2519 25 -71 86 -132 157 -157 52 -18 121 -19 2069 -19
|
||||
1948 0 2017 1 2069 19 68 23 131 85 157 152 18 47 19 105 22 1769 2 1189 -1
|
||||
1740 -8 1785 -6 36 -25 94 -42 130 -28 60 -89 124 -727 761 -523 522 -709 702
|
||||
-747 722 -112 59 -64 57 -1439 56 -693 -1 -1280 -5 -1304 -10z m2599 -309 c13
|
||||
-8 16 -85 20 -562 5 -551 5 -553 28 -603 41 -89 97 -132 200 -154 35 -7 225
|
||||
-11 565 -11 305 0 518 -4 527 -10 13 -8 15 -52 18 -275 l3 -265 -1941 0 -1940
|
||||
0 2 919 c3 879 4 920 22 939 10 12 28 23 40 25 46 9 2441 6 2456 -3z m-520
|
||||
-2165 c77 -8 195 -45 251 -81 139 -88 209 -229 209 -424 0 -175 -55 -317 -158
|
||||
-411 -117 -107 -225 -140 -480 -146 -100 -3 -207 -2 -237 2 l-55 6 0 520 c0
|
||||
448 2 520 15 525 21 9 271 22 335 18 30 -2 84 -6 120 -9z m-898 -6 c180 -38
|
||||
278 -166 265 -349 -14 -211 -175 -330 -449 -330 l-68 0 0 -185 0 -185 -120 0
|
||||
-120 0 2 523 3 522 45 6 c81 11 388 9 442 -2z m2168 -89 l0 -100 -205 0 -205
|
||||
0 0 -120 0 -120 190 0 190 0 0 -100 0 -100 -190 0 -190 0 0 -210 0 -210 -120
|
||||
0 -120 0 0 530 0 530 325 0 325 0 0 -100z m608 -1855 l-3 -604 -23 -23 -23
|
||||
-23 -1889 0 -1889 0 -23 23 -23 23 -3 604 -3 605 1941 0 1941 0 -3 -605z"/>
|
||||
<path d="M2105 2739 c-3 -8 -4 -167 -3 -354 l3 -340 86 1 c115 1 179 24 245
|
||||
89 72 70 97 138 98 270 2 163 -46 255 -160 311 -47 23 -73 28 -160 32 -82 4
|
||||
-105 2 -109 -9z"/>
|
||||
<path d="M1180 2590 l0 -160 75 0 c87 0 128 14 170 59 25 27 30 41 33 99 4 63
|
||||
2 71 -24 101 -39 47 -80 61 -174 61 l-80 0 0 -160z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="228.000000pt" height="317.000000pt" viewBox="0 0 228.000000 317.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,317.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M95 3120 c-11 -4 -31 -20 -45 -35 l-25 -27 -3 -1465 c-2 -1456 -2
|
||||
-1466 18 -1498 43 -69 -23 -66 1109 -63 l1021 3 37 38 38 37 3 1003 c1 551 0
|
||||
1013 -3 1027 -7 28 -923 952 -967 976 -23 12 -121 14 -595 13 -312 0 -577 -4
|
||||
-588 -9z m1085 -585 l5 -470 473 -3 472 -2 -2 -298 -3 -297 -992 -3 -993 -2 0
|
||||
768 c0 423 3 772 7 775 3 4 236 6 517 5 l511 -3 5 -470z m-465 -1301 c54 -27
|
||||
77 -63 83 -128 9 -109 -73 -186 -197 -186 l-61 0 0 -90 0 -90 -60 0 -60 0 0
|
||||
253 c0 140 3 257 8 261 4 5 61 6 128 4 92 -4 130 -9 159 -24z m378 -146 l112
|
||||
-171 5 169 5 169 53 3 52 3 0 -260 0 -261 -58 0 -59 0 -116 178 -116 177 -1
|
||||
-177 0 -178 -55 0 -55 0 0 260 0 260 61 0 60 0 112 -172z m697 163 c22 -6 25
|
||||
-13 28 -60 3 -48 1 -53 -15 -46 -50 19 -129 27 -170 16 -107 -29 -154 -168
|
||||
-93 -269 27 -44 70 -64 133 -60 l52 3 3 53 3 52 -50 0 -51 0 0 45 0 45 110 0
|
||||
110 0 0 -109 c0 -60 -4 -121 -9 -134 -14 -36 -70 -52 -181 -52 -86 0 -100 3
|
||||
-147 29 -88 49 -129 131 -121 245 8 107 63 187 158 230 35 16 65 20 130 20 47
|
||||
-1 96 -4 110 -8z m340 -906 l0 -185 -995 0 -995 0 0 185 0 185 995 0 995 0 0
|
||||
-185z"/>
|
||||
<path d="M540 1089 l0 -80 51 3 c67 4 95 36 85 93 -6 29 -14 39 -41 51 -19 8
|
||||
-48 14 -65 14 l-30 0 0 -81z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -11,8 +11,42 @@ PODS:
|
|||
- SwiftProtobuf
|
||||
- device_info (0.0.1):
|
||||
- Flutter
|
||||
- DKImagePickerController/Core (4.3.4):
|
||||
- DKImagePickerController/ImageDataManager
|
||||
- DKImagePickerController/Resource
|
||||
- DKImagePickerController/ImageDataManager (4.3.4)
|
||||
- DKImagePickerController/PhotoGallery (4.3.4):
|
||||
- DKImagePickerController/Core
|
||||
- DKPhotoGallery
|
||||
- DKImagePickerController/Resource (4.3.4)
|
||||
- DKPhotoGallery (0.0.17):
|
||||
- DKPhotoGallery/Core (= 0.0.17)
|
||||
- DKPhotoGallery/Model (= 0.0.17)
|
||||
- DKPhotoGallery/Preview (= 0.0.17)
|
||||
- DKPhotoGallery/Resource (= 0.0.17)
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Core (0.0.17):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Preview
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Model (0.0.17):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Preview (0.0.17):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Resource
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Resource (0.0.17):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- easy_app_installer (0.0.1):
|
||||
- Flutter
|
||||
- file_picker (0.0.1):
|
||||
- DKImagePickerController/PhotoGallery
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- fluttertoast (0.0.2):
|
||||
- Flutter
|
||||
|
@ -36,6 +70,9 @@ PODS:
|
|||
- Flutter
|
||||
- rive_common (0.0.1):
|
||||
- Flutter
|
||||
- SDWebImage (5.17.0):
|
||||
- SDWebImage/Core (= 5.17.0)
|
||||
- SDWebImage/Core (5.17.0)
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
|
@ -43,6 +80,7 @@ PODS:
|
|||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
- SwiftProtobuf (1.20.3)
|
||||
- SwiftyGif (5.4.4)
|
||||
- Toast (4.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
|
@ -52,6 +90,7 @@ DEPENDENCIES:
|
|||
- barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
|
||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||
- easy_app_installer (from `.symlinks/plugins/easy_app_installer/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- location (from `.symlinks/plugins/location/ios`)
|
||||
|
@ -66,9 +105,13 @@ DEPENDENCIES:
|
|||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- DKImagePickerController
|
||||
- DKPhotoGallery
|
||||
- FMDB
|
||||
- MTBBarcodeScanner
|
||||
- SDWebImage
|
||||
- SwiftProtobuf
|
||||
- SwiftyGif
|
||||
- Toast
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
|
@ -84,6 +127,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/device_info/ios"
|
||||
easy_app_installer:
|
||||
:path: ".symlinks/plugins/easy_app_installer/ios"
|
||||
file_picker:
|
||||
:path: ".symlinks/plugins/file_picker/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
fluttertoast:
|
||||
|
@ -113,7 +158,10 @@ SPEC CHECKSUMS:
|
|||
audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40
|
||||
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
|
||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||
easy_app_installer: 29abe397da7d86721fee853281202f414373f45c
|
||||
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
|
@ -125,9 +173,11 @@ SPEC CHECKSUMS:
|
|||
permission_handler_apple: 8f116445eff3c0e7c65ad60f5fef5490aa94b4e4
|
||||
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
|
||||
rive_common: 60ae7896ab40f9513974f36f015de33f70d2c5c5
|
||||
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
|
||||
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
|
||||
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
|
||||
SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1
|
||||
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
|
||||
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
|
||||
|
|
|
@ -3,6 +3,9 @@ import 'package:equatable/equatable.dart';
|
|||
import 'package:unit2/model/profile/educational_background.dart';
|
||||
import 'package:unit2/sevices/profile/education_services.dart';
|
||||
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../utils/attachment_services.dart';
|
||||
|
||||
part 'education_event.dart';
|
||||
part 'education_state.dart';
|
||||
|
||||
|
@ -11,20 +14,27 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
|||
List<School> schools = [];
|
||||
List<Course> programs = [];
|
||||
List<Honor> honors = [];
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
EducationBloc() : super(EducationInitial()) {
|
||||
on<GetEducationalBackground>((event, emit) async {
|
||||
emit(EducationalBackgroundLoadingState());
|
||||
try {
|
||||
if (attachmentCategories.isEmpty) {
|
||||
attachmentCategories =
|
||||
await AttachmentServices.instance.getCategories();
|
||||
}
|
||||
if (educationalBackgrounds.isEmpty) {
|
||||
List<EducationalBackground> educations = await EducationService
|
||||
.instace
|
||||
.getEducationalBackground(event.profileId, event.token);
|
||||
educationalBackgrounds = educations;
|
||||
emit(EducationalBackgroundLoadedState(
|
||||
educationalBackground: educationalBackgrounds));
|
||||
emit(EducationalBackgroundLoadedState(
|
||||
educationalBackground: educationalBackgrounds,
|
||||
attachmentCategory: attachmentCategories));
|
||||
} else {
|
||||
emit(EducationalBackgroundLoadedState(
|
||||
educationalBackground: educationalBackgrounds));
|
||||
educationalBackground: educationalBackgrounds,
|
||||
attachmentCategory: attachmentCategories));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
|
@ -77,7 +87,8 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
|||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
educationalBackgrounds.removeWhere((element) => event.educationalBackground.id == element.id);
|
||||
educationalBackgrounds.removeWhere(
|
||||
(element) => event.educationalBackground.id == element.id);
|
||||
EducationalBackground educationalBackground =
|
||||
EducationalBackground.fromJson(status['data']);
|
||||
educationalBackgrounds.add(educationalBackground);
|
||||
|
@ -89,7 +100,8 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
|||
////LOAD
|
||||
on<LoadEducations>((event, emit) {
|
||||
emit(EducationalBackgroundLoadedState(
|
||||
educationalBackground: educationalBackgrounds));
|
||||
educationalBackground: educationalBackgrounds,
|
||||
attachmentCategory: attachmentCategories));
|
||||
});
|
||||
//// SHOW EDIT FORM
|
||||
on<ShowEditEducationForm>((event, emit) async {
|
||||
|
@ -134,5 +146,65 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
|||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Add attachment
|
||||
on<AddEducationAttachment>((event, emit) async {
|
||||
emit(EducationalBackgroundLoadingState());
|
||||
EducationalBackground educationalBackground =
|
||||
educationalBackgrounds.firstWhere(
|
||||
(element) => element.id.toString() == event.attachmentModule);
|
||||
List<Attachment> attachments = [];
|
||||
try {
|
||||
Map<dynamic, dynamic> status = await AttachmentServices.instance
|
||||
.attachment(
|
||||
categoryId: event.categoryId,
|
||||
module: event.attachmentModule,
|
||||
paths: event.filePaths,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
|
||||
if (status['success']) {
|
||||
status['data'].forEach((element) {
|
||||
Attachment newAttachment = Attachment.fromJson(element);
|
||||
attachments.add(newAttachment);
|
||||
});
|
||||
educationalBackground.attachments == null
|
||||
? educationalBackground.attachments = attachments
|
||||
: educationalBackground.attachments = [
|
||||
...educationalBackground.attachments!,
|
||||
...attachments
|
||||
];
|
||||
emit(EducationAddedState(response: status));
|
||||
} else {
|
||||
emit(EducationAddedState(response: status));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
on<DeleteEducationAttachment>((event, emit) async {
|
||||
emit(EducationalBackgroundLoadingState());
|
||||
try {
|
||||
final bool success = await AttachmentServices.instance.deleteAttachment(
|
||||
attachment: event.attachment,
|
||||
moduleId: event.moduleId,
|
||||
profileId: event.profileId.toString(),
|
||||
token: event.token);
|
||||
if (success) {
|
||||
final EducationalBackground educationalBackground =
|
||||
educationalBackgrounds
|
||||
.firstWhere((element) => element.id == event.moduleId);
|
||||
educationalBackground.attachments
|
||||
?.removeWhere((element) => element.id == event.attachment.id);
|
||||
educationalBackgrounds
|
||||
.removeWhere((element) => element.id == event.moduleId);
|
||||
educationalBackgrounds.add(educationalBackground);
|
||||
emit(EducationAttachmentDeletedState(success: success));
|
||||
} else {
|
||||
emit(EducationAttachmentDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,3 +63,23 @@ class DeleteEducation extends EducationEvent{
|
|||
@override
|
||||
List<Object> get props => [educationalBackground, profileId, token];
|
||||
}
|
||||
////Add attachment
|
||||
class AddEducationAttachment extends EducationEvent{
|
||||
final String categoryId;
|
||||
final String attachmentModule;
|
||||
final List<String> filePaths;
|
||||
final String token;
|
||||
final String profileId;
|
||||
const AddEducationAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
|
||||
}
|
||||
|
||||
////Delete Attachment
|
||||
class DeleteEducationAttachment extends EducationEvent{
|
||||
final int moduleId;
|
||||
final Attachment attachment;
|
||||
final String token;
|
||||
final int profileId;
|
||||
const DeleteEducationAttachment({required this.attachment, required this.moduleId, required this.profileId, required this.token});
|
||||
}
|
||||
|
|
|
@ -10,8 +10,10 @@ abstract class EducationState extends Equatable {
|
|||
class EducationInitial extends EducationState {}
|
||||
|
||||
class EducationalBackgroundLoadedState extends EducationState {
|
||||
final List<AttachmentCategory> attachmentCategory;
|
||||
final List<EducationalBackground> educationalBackground;
|
||||
const EducationalBackgroundLoadedState({required this.educationalBackground});
|
||||
const EducationalBackgroundLoadedState(
|
||||
{required this.educationalBackground, required this.attachmentCategory});
|
||||
@override
|
||||
List<Object> get props => [educationalBackground];
|
||||
}
|
||||
|
@ -57,6 +59,8 @@ class EducationAddedState extends EducationState {
|
|||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
|
||||
//// Edited State
|
||||
class EditedEducationState extends EducationState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
|
@ -72,3 +76,17 @@ class EducationDeletedState extends EducationState {
|
|||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
||||
////Attachment AddedState
|
||||
class EducationAttachmentAddedState extends EducationState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const EducationAttachmentAddedState({required this.response});
|
||||
}
|
||||
|
||||
////Attachment Deleted State State
|
||||
class EducationAttachmentDeletedState extends EducationState {
|
||||
final bool success;
|
||||
const EducationAttachmentDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:unit2/utils/attachment_services.dart';
|
||||
import '../../../model/location/city.dart';
|
||||
import '../../../model/location/country.dart';
|
||||
import '../../../model/location/provinces.dart';
|
||||
import '../../../model/location/region.dart';
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../model/profile/eligibility.dart';
|
||||
import '../../../model/utils/eligibility.dart';
|
||||
import '../../../sevices/profile/eligibility_services.dart';
|
||||
|
@ -18,10 +20,13 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
List<Region> globalRegions = [];
|
||||
List<Eligibility> globalEligibilities = [];
|
||||
List<EligibityCert> eligibilities = [];
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
//// LOAD ELIGIBILTY
|
||||
on<LoadEligibility>((event, emit) {
|
||||
emit(EligibilityLoadingState());
|
||||
emit(EligibilityLoaded(eligibilities: eligibilities));
|
||||
emit(EligibilityLoaded(
|
||||
eligibilities: eligibilities,
|
||||
attachmentCategory: attachmentCategories));
|
||||
});
|
||||
|
||||
//// DELETE
|
||||
|
@ -34,11 +39,11 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
if (success) {
|
||||
eligibilities.removeWhere(
|
||||
((EligibityCert element) => element.id == event.eligibilityId));
|
||||
emit(DeletedState(
|
||||
emit(EligibilityDeletedState(
|
||||
success: success,
|
||||
));
|
||||
} else {
|
||||
emit(DeletedState(success: success));
|
||||
emit(EligibilityDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EligibilityErrorState(message: e.toString()));
|
||||
|
@ -48,13 +53,21 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
//// GET ELIGIBILITY
|
||||
on<GetEligibilities>((event, emit) async {
|
||||
try {
|
||||
if (attachmentCategories.isEmpty) {
|
||||
attachmentCategories =
|
||||
await AttachmentServices.instance.getCategories();
|
||||
}
|
||||
if (eligibilities.isNotEmpty) {
|
||||
emit(EligibilityLoaded(eligibilities: eligibilities));
|
||||
emit(EligibilityLoaded(
|
||||
eligibilities: eligibilities,
|
||||
attachmentCategory: attachmentCategories));
|
||||
} else {
|
||||
emit(EligibilityLoadingState());
|
||||
eligibilities = await EligibilityService.instance
|
||||
.getEligibilities(event.profileId, event.token);
|
||||
emit(EligibilityLoaded(eligibilities: eligibilities));
|
||||
emit(EligibilityLoaded(
|
||||
eligibilities: eligibilities,
|
||||
attachmentCategory: attachmentCategories));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EligibilityErrorState(message: e.toString()));
|
||||
|
@ -208,5 +221,63 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
emit(const EligibilityErrorState(
|
||||
message: "Something went wrong. Please try again"));
|
||||
});
|
||||
////Add attachment
|
||||
on<AddEligibiltyAttachment>((event, emit) async {
|
||||
emit(EligibilityLoadingState());
|
||||
List<Attachment> attachments = [];
|
||||
EligibityCert eligibityCert = eligibilities.firstWhere(
|
||||
(element) => element.id.toString() == event.attachmentModule);
|
||||
try {
|
||||
Map<dynamic, dynamic> status = await AttachmentServices.instance
|
||||
.attachment(
|
||||
categoryId: event.categoryId,
|
||||
module: event.attachmentModule,
|
||||
paths: event.filePaths,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
status['data'].forEach((element) {
|
||||
Attachment newAttachment = Attachment.fromJson(element);
|
||||
attachments.add(newAttachment);
|
||||
});
|
||||
eligibityCert.attachments == null
|
||||
? eligibityCert.attachments = attachments
|
||||
: eligibityCert.attachments = [
|
||||
...eligibityCert.attachments!,
|
||||
...attachments
|
||||
];
|
||||
emit(EligibilityAttachmentAddedState(response: status));
|
||||
} else {
|
||||
emit(EligibilityAttachmentAddedState(response: status));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EligibilityErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
|
||||
on<DeleteEligibyAttachment>((event, emit) async {
|
||||
emit(EligibilityLoadingState());
|
||||
// try {
|
||||
final bool success = await AttachmentServices.instance.deleteAttachment(
|
||||
attachment: event.attachment,
|
||||
moduleId: int.parse(event.moduleId),
|
||||
profileId: event.profileId.toString(),
|
||||
token: event.token);
|
||||
if (success) {
|
||||
final EligibityCert eligibityCert = eligibilities
|
||||
.firstWhere((element) => element.id.toString() == event.moduleId);
|
||||
eligibityCert.attachments
|
||||
?.removeWhere((element) => element.id == event.attachment.id);
|
||||
eligibilities.removeWhere(
|
||||
(element) => element.id.toString() == event.moduleId);
|
||||
eligibilities.add(eligibityCert);
|
||||
emit(EligibilitytAttachmentDeletedState(success: success));
|
||||
} else {
|
||||
emit(EligibilitytAttachmentDeletedState(success: success));
|
||||
}
|
||||
// } catch (e) {
|
||||
// emit(EligibilityErrorState(message: e.toString()));
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ class DeleteEligibility extends EligibilityEvent {
|
|||
final String profileId;
|
||||
final int eligibilityId;
|
||||
final String token;
|
||||
|
||||
const DeleteEligibility(
|
||||
{
|
||||
required this.eligibilityId,
|
||||
|
@ -67,5 +68,32 @@ class DeleteEligibility extends EligibilityEvent {
|
|||
class CallErrorState extends EligibilityEvent{
|
||||
|
||||
}
|
||||
////Add Attachment
|
||||
class AddEligibiltyAttachment extends EligibilityEvent{
|
||||
final String categoryId;
|
||||
final String attachmentModule;
|
||||
final List<String> filePaths;
|
||||
final String token;
|
||||
final String profileId;
|
||||
const AddEligibiltyAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
|
||||
}
|
||||
|
||||
////Delete Attachment
|
||||
class DeleteEligibyAttachment extends EligibilityEvent{
|
||||
final String profileId;
|
||||
final String token;
|
||||
final Attachment attachment;
|
||||
final String moduleId;
|
||||
const DeleteEligibyAttachment({required this.attachment,required this.moduleId, required this.profileId, required this.token});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ abstract class EligibilityState extends Equatable {
|
|||
|
||||
class EligibilityInitial extends EligibilityState {}
|
||||
|
||||
|
||||
class EditEligibilityState extends EligibilityState {
|
||||
final EligibityCert eligibityCert;
|
||||
final List<Eligibility> eligibilities;
|
||||
|
@ -23,13 +22,14 @@ class EditEligibilityState extends EligibilityState {
|
|||
final Province? currentProvince;
|
||||
final CityMunicipality? currentCity;
|
||||
final Country selectedCountry;
|
||||
const EditEligibilityState({
|
||||
required this.provinces,
|
||||
required this.cities,
|
||||
required this.currentProvince,
|
||||
required this.currentCity,
|
||||
required this.currentRegion,
|
||||
required this.currentEligibility,
|
||||
|
||||
const EditEligibilityState({
|
||||
required this.provinces,
|
||||
required this.cities,
|
||||
required this.currentProvince,
|
||||
required this.currentCity,
|
||||
required this.currentRegion,
|
||||
required this.currentEligibility,
|
||||
required this.isOverseas,
|
||||
required this.eligibityCert,
|
||||
required this.eligibilities,
|
||||
|
@ -42,9 +42,9 @@ class EditEligibilityState extends EligibilityState {
|
|||
[isOverseas, eligibityCert, eligibilities, regions, countries];
|
||||
}
|
||||
|
||||
class DeletedState extends EligibilityState {
|
||||
class EligibilityDeletedState extends EligibilityState {
|
||||
final bool success;
|
||||
const DeletedState({required this.success});
|
||||
const EligibilityDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
@ -53,41 +53,57 @@ class AddEligibilityState extends EligibilityState {
|
|||
final List<Eligibility> eligibilities;
|
||||
final List<Country> countries;
|
||||
final List<Region> regions;
|
||||
const AddEligibilityState({
|
||||
const AddEligibilityState({
|
||||
required this.eligibilities,
|
||||
required this.countries,
|
||||
required this.regions,
|
||||
});
|
||||
@override
|
||||
List<Object> get props => [eligibilities,countries,regions];
|
||||
List<Object> get props => [eligibilities, countries, regions];
|
||||
}
|
||||
class EligibilityEditedState extends EligibilityState{
|
||||
final Map<dynamic,dynamic> response;
|
||||
|
||||
class EligibilityEditedState extends EligibilityState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const EligibilityEditedState({required this.response});
|
||||
@override
|
||||
List<Object> get props =>[ response];
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
class EligibilityAddedState extends EligibilityState{
|
||||
final Map<dynamic,dynamic> response;
|
||||
class EligibilityAddedState extends EligibilityState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
|
||||
const EligibilityAddedState({ required this.response});
|
||||
const EligibilityAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props =>[response];
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
class EligibilityLoadingState extends EligibilityState{
|
||||
|
||||
}
|
||||
class EligibilityErrorState extends EligibilityState{
|
||||
class EligibilityLoadingState extends EligibilityState {}
|
||||
|
||||
class EligibilityErrorState extends EligibilityState {
|
||||
final String message;
|
||||
const EligibilityErrorState({required this.message});
|
||||
@override
|
||||
List<Object> get props =>[message];
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
class EligibilityLoaded extends EligibilityState {
|
||||
final List< AttachmentCategory> attachmentCategory;
|
||||
final List<EligibityCert> eligibilities;
|
||||
const EligibilityLoaded({required this.eligibilities});
|
||||
const EligibilityLoaded({required this.eligibilities, required this.attachmentCategory});
|
||||
@override
|
||||
List<Object> get props => [eligibilities];
|
||||
}
|
||||
|
||||
////Attachment AddedState
|
||||
class EligibilityAttachmentAddedState extends EligibilityState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const EligibilityAttachmentAddedState({required this.response});
|
||||
}
|
||||
|
||||
////Attachment Deleted State State
|
||||
class EligibilitytAttachmentDeletedState extends EligibilityState {
|
||||
final bool success;
|
||||
const EligibilitytAttachmentDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@ import 'package:unit2/sevices/profile/learningDevelopment_service.dart';
|
|||
import '../../../model/location/barangay.dart';
|
||||
import '../../../model/location/city.dart';
|
||||
import '../../../model/location/provinces.dart';
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../model/profile/learning_development.dart';
|
||||
import '../../../model/utils/agency.dart';
|
||||
import '../../../model/utils/category.dart';
|
||||
import '../../../utils/attachment_services.dart';
|
||||
import '../../../utils/location_utilities.dart';
|
||||
import '../../../utils/profile_utilities.dart';
|
||||
part 'learning_development_event.dart';
|
||||
|
@ -27,7 +29,7 @@ class LearningDevelopmentBloc
|
|||
List<Barangay> globalBarangay = [];
|
||||
List<Agency> agencies = [];
|
||||
List<Category> agencyCategory = [];
|
||||
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
Region? currentRegion;
|
||||
Country? currentCountry;
|
||||
Province? currentProvince;
|
||||
|
@ -37,12 +39,16 @@ class LearningDevelopmentBloc
|
|||
on<GetLearningDevelopments>((event, emit) async {
|
||||
emit(LearningDevelopmentLoadingState());
|
||||
try {
|
||||
if (attachmentCategories.isEmpty) {
|
||||
attachmentCategories =
|
||||
await AttachmentServices.instance.getCategories();
|
||||
}
|
||||
List<LearningDevelopement> learnings = await LearningDevelopmentServices
|
||||
.instance
|
||||
.getLearningDevelopments(event.profileId, event.token);
|
||||
learningsAndDevelopments = learnings;
|
||||
emit(LearningDevelopmentLoadedState(
|
||||
learningsAndDevelopment: learningsAndDevelopments));
|
||||
learningsAndDevelopment: learningsAndDevelopments,attachmentCategory: attachmentCategories));
|
||||
} catch (e) {
|
||||
emit(LearningDevelopmentErrorState(message: e.toString()));
|
||||
}
|
||||
|
@ -50,7 +56,7 @@ class LearningDevelopmentBloc
|
|||
////load
|
||||
on<LoadLearniningDevelopment>((event, emit) {
|
||||
emit(LearningDevelopmentLoadedState(
|
||||
learningsAndDevelopment: learningsAndDevelopments));
|
||||
learningsAndDevelopment: learningsAndDevelopments,attachmentCategory: attachmentCategories));
|
||||
});
|
||||
//// show add form
|
||||
on<ShowAddLearningDevelopmentForm>((event, emit) async {
|
||||
|
@ -266,5 +272,58 @@ class LearningDevelopmentBloc
|
|||
on<CallErrorState>((event, emit) {
|
||||
emit(LearningDevelopmentErrorState(message: event.message));
|
||||
});
|
||||
////Add attachment
|
||||
on<AddALearningDevttachment>((event, emit) async {
|
||||
emit(LearningDevelopmentLoadingState());
|
||||
List<Attachment> attachments = [];
|
||||
LearningDevelopement learningDevelopement = learningsAndDevelopments.firstWhere((element) => element.conductedTraining!.id.toString () == event.attachmentModule);
|
||||
try {
|
||||
Map<dynamic, dynamic> status = await AttachmentServices.instance
|
||||
.attachment(
|
||||
categoryId: event.categoryId,
|
||||
module: event.attachmentModule,
|
||||
paths: event.filePaths,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
status['data'].forEach((element){
|
||||
Attachment newAttachment = Attachment.fromJson(element);
|
||||
attachments.add(newAttachment);
|
||||
});
|
||||
learningDevelopement.attachments == null? learningDevelopement.attachments = attachments:learningDevelopement.attachments = [...learningDevelopement.attachments!,...attachments];
|
||||
emit(LearningDevelopmentAddedState(response: status));
|
||||
} else {
|
||||
emit(LearningDevelopmentAddedState(response: status));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(LearningDevelopmentErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Delete Attachment
|
||||
on<DeleteLearningDevAttachment>((event, emit) async {
|
||||
emit(LearningDevelopmentLoadingState());
|
||||
try {
|
||||
final bool success = await AttachmentServices.instance.deleteAttachment(
|
||||
attachment: event.attachment,
|
||||
moduleId: event.moduleId,
|
||||
profileId: event.profileId.toString(),
|
||||
token: event.token);
|
||||
if (success) {
|
||||
final LearningDevelopement learningDevelopement =
|
||||
learningsAndDevelopments
|
||||
.firstWhere((element) => element.conductedTraining!.id == event.moduleId);
|
||||
learningDevelopement.attachments
|
||||
?.removeWhere((element) => element.id == event.attachment.id);
|
||||
learningsAndDevelopments
|
||||
.removeWhere((element) => element.conductedTraining!.id == event.moduleId);
|
||||
learningsAndDevelopments.add(learningDevelopement);
|
||||
emit(LearningDevAttachmentDeletedState(success: success));
|
||||
} else {
|
||||
emit(LearningDevAttachmentDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(LearningDevelopmentErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,3 +66,25 @@ class CallErrorState extends LearningDevelopmentEvent{
|
|||
final String message;
|
||||
const CallErrorState({required this.message});
|
||||
}
|
||||
|
||||
////Add Attachment
|
||||
class AddALearningDevttachment extends LearningDevelopmentEvent{
|
||||
final String categoryId;
|
||||
final String attachmentModule;
|
||||
final List<String> filePaths;
|
||||
final String token;
|
||||
final String profileId;
|
||||
const AddALearningDevttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
|
||||
}
|
||||
|
||||
//// Delete Attachment
|
||||
class DeleteLearningDevAttachment extends LearningDevelopmentEvent{
|
||||
final int moduleId;
|
||||
final Attachment attachment;
|
||||
final String token;
|
||||
final int profileId;
|
||||
const DeleteLearningDevAttachment({required this.attachment, required this.moduleId, required this.profileId, required this.token});
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,11 @@ abstract class LearningDevelopmentState extends Equatable {
|
|||
class LearningDevelopmentInitial extends LearningDevelopmentState {}
|
||||
|
||||
class LearningDevelopmentLoadedState extends LearningDevelopmentState {
|
||||
final List<AttachmentCategory> attachmentCategory;
|
||||
final List<LearningDevelopement> learningsAndDevelopment;
|
||||
const LearningDevelopmentLoadedState({required this.learningsAndDevelopment});
|
||||
const LearningDevelopmentLoadedState(
|
||||
{required this.learningsAndDevelopment,
|
||||
required this.attachmentCategory});
|
||||
@override
|
||||
List<Object> get props => [learningsAndDevelopment];
|
||||
}
|
||||
|
@ -112,3 +115,21 @@ class LearningDevelopmentErrorState extends LearningDevelopmentState {
|
|||
final String message;
|
||||
const LearningDevelopmentErrorState({required this.message});
|
||||
}
|
||||
|
||||
////Attachment AddedState
|
||||
class LearningDevAttachmentAddedState extends LearningDevelopmentState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const LearningDevAttachmentAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////Attachment Deleted State State
|
||||
class LearningDevAttachmentDeletedState extends LearningDevelopmentState {
|
||||
final bool success;
|
||||
const LearningDevAttachmentDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
|
|
@ -72,3 +72,13 @@ class DeleteVoluntaryWork extends VoluntaryWorkEvent {
|
|||
@override
|
||||
List<Object> get props => [profileId, token, work];
|
||||
}
|
||||
class AddAttachment extends VoluntaryWorkEvent{
|
||||
final String categoryId;
|
||||
final String attachmentModule;
|
||||
final List<String> filePaths;
|
||||
final String token;
|
||||
final String profileId;
|
||||
const AddAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ class EditVoluntaryWorks extends VoluntaryWorkState{
|
|||
|
||||
}
|
||||
|
||||
|
||||
////Adding State
|
||||
class AddVoluntaryWorkState extends VoluntaryWorkState{
|
||||
final List<Position> positions;
|
||||
|
@ -71,6 +72,11 @@ class AddVoluntaryWorkState extends VoluntaryWorkState{
|
|||
@override
|
||||
List<Object> get props => [positions,agencies,countries,regions];
|
||||
}
|
||||
////Add Attachment
|
||||
class AttachmentAddedState extends VoluntaryWorkState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const AttachmentAddedState({required this.response});
|
||||
}
|
||||
//// Deleted State
|
||||
class VoluntaryWorkDeletedState extends VoluntaryWorkState{
|
||||
final bool success;
|
||||
|
|
|
@ -8,7 +8,9 @@ import 'package:unit2/model/utils/position.dart';
|
|||
import 'package:unit2/sevices/profile/work_history_services.dart';
|
||||
import 'package:unit2/utils/profile_utilities.dart';
|
||||
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../model/utils/category.dart';
|
||||
import '../../../utils/attachment_services.dart';
|
||||
|
||||
part 'workHistory_event.dart';
|
||||
part 'workHistory_state.dart';
|
||||
|
@ -19,17 +21,24 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
|
|||
List<Agency> agencies = [];
|
||||
List<AppoinemtStatus> appointmentStatus = [];
|
||||
List<Category> agencyCategory = [];
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
WorkHistoryBloc() : super(EducationInitial()) {
|
||||
////GET WORK HISTORIES
|
||||
on<GetWorkHistories>((event, emit) async {
|
||||
emit(WorkHistoryLoadingState());
|
||||
try {
|
||||
if (attachmentCategories.isEmpty) {
|
||||
attachmentCategories =
|
||||
await AttachmentServices.instance.getCategories();
|
||||
}
|
||||
if (workExperiences.isEmpty) {
|
||||
List<WorkHistory> works = await WorkHistoryService.instance
|
||||
.getWorkExperiences(event.profileId, event.token);
|
||||
workExperiences = works;
|
||||
}
|
||||
emit(WorkHistoryLoaded(workExperiences: workExperiences));
|
||||
emit(WorkHistoryLoaded(
|
||||
workExperiences: workExperiences,
|
||||
attachmentCategory: attachmentCategories));
|
||||
} catch (e) {
|
||||
emit(WorkHistoryErrorState(message: e.toString()));
|
||||
}
|
||||
|
@ -37,7 +46,9 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
|
|||
///// LOAD WORK HISTORIES
|
||||
on<LoadWorkHistories>((event, emit) {
|
||||
emit(WorkHistoryLoadingState());
|
||||
emit(WorkHistoryLoaded(workExperiences: workExperiences));
|
||||
emit(WorkHistoryLoaded(
|
||||
workExperiences: workExperiences,
|
||||
attachmentCategory: attachmentCategories));
|
||||
});
|
||||
////DELETE
|
||||
on<DeleteWorkHistory>((event, emit) async {
|
||||
|
@ -182,5 +193,64 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
|
|||
emit(WorkHistoryErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Add Attachment
|
||||
on<AddWorkHistoryAttachment>((event, emit) async {
|
||||
emit(WorkHistoryLoadingState());
|
||||
List<Attachment> attachments = [];
|
||||
WorkHistory workHistory = workExperiences.firstWhere(
|
||||
(element) => element.id.toString() == event.attachmentModule);
|
||||
try {
|
||||
Map<dynamic, dynamic> status = await AttachmentServices.instance
|
||||
.attachment(
|
||||
categoryId: event.categoryId,
|
||||
module: event.attachmentModule,
|
||||
paths: event.filePaths,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
status['data'].forEach((element) {
|
||||
Attachment newAttachment = Attachment.fromJson(element);
|
||||
attachments.add(newAttachment);
|
||||
});
|
||||
workHistory.attachments == null
|
||||
? workHistory.attachments = attachments
|
||||
: workHistory.attachments = [
|
||||
...workHistory.attachments!,
|
||||
...attachments
|
||||
];
|
||||
emit(WorkHistoryDevAttachmentAddedState(response: status));
|
||||
} else {
|
||||
emit(WorkHistoryDevAttachmentAddedState(response: status));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(WorkHistoryErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Delete Attachment
|
||||
on<DeleteWorkHistoryAttachment>((event, emit) async {
|
||||
emit(WorkHistoryLoadingState());
|
||||
try {
|
||||
final bool success = await AttachmentServices.instance.deleteAttachment(
|
||||
attachment: event.attachment,
|
||||
moduleId: event.moduleId,
|
||||
profileId: event.profileId.toString(),
|
||||
token: event.token);
|
||||
if (success) {
|
||||
final WorkHistory workHistory =
|
||||
workExperiences
|
||||
.firstWhere((element) => element.id == event.moduleId);
|
||||
workHistory.attachments
|
||||
?.removeWhere((element) => element.id == event.attachment.id);
|
||||
workExperiences
|
||||
.removeWhere((element) => element.id == event.moduleId);
|
||||
workExperiences.add(workHistory);
|
||||
emit(WorkHistoryDevAttachmentDeletedState(success: success));
|
||||
} else {
|
||||
emit(WorkHistoryDevAttachmentDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(WorkHistoryErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,4 +61,26 @@ class AddWorkHostory extends WorkHistorytEvent{
|
|||
List<Object> get props => [workHistory,profileId,token,isPrivate];
|
||||
}
|
||||
|
||||
////Add Attachment
|
||||
class AddWorkHistoryAttachment extends WorkHistorytEvent{
|
||||
final String categoryId;
|
||||
final String attachmentModule;
|
||||
final List<String> filePaths;
|
||||
final String token;
|
||||
final String profileId;
|
||||
const AddWorkHistoryAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
|
||||
}
|
||||
|
||||
////Delete Attachment
|
||||
class DeleteWorkHistoryAttachment extends WorkHistorytEvent{
|
||||
final int moduleId;
|
||||
final Attachment attachment;
|
||||
final String token;
|
||||
final int profileId;
|
||||
const DeleteWorkHistoryAttachment({required this.attachment, required this.moduleId, required this.profileId, required this.token});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ class EducationInitial extends WorkHistoryState {}
|
|||
|
||||
class WorkHistoryLoaded extends WorkHistoryState{
|
||||
final List<WorkHistory> workExperiences;
|
||||
const WorkHistoryLoaded({required this.workExperiences});
|
||||
final List< AttachmentCategory> attachmentCategory;
|
||||
const WorkHistoryLoaded({required this.workExperiences,required this.attachmentCategory});
|
||||
@override
|
||||
List<Object> get props => [workExperiences];
|
||||
}
|
||||
|
@ -72,3 +73,22 @@ class WorkHistoryAddedState extends WorkHistoryState{
|
|||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
|
||||
////Attachment AddedState
|
||||
class WorkHistoryDevAttachmentAddedState extends WorkHistoryState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const WorkHistoryDevAttachmentAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////Attachment Deleted State State
|
||||
class WorkHistoryDevAttachmentDeletedState extends WorkHistoryState {
|
||||
final bool success;
|
||||
const WorkHistoryDevAttachmentDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
|
@ -1,24 +1,14 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:device_preview/device_preview.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/app_router.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
import 'package:path_provider/path_provider.dart' as path_provider;
|
||||
import './utils/router.dart';
|
||||
import './utils/global.dart';
|
||||
|
||||
|
||||
|
||||
Future main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
var appDirectory = await path_provider.getApplicationDocumentsDirectory();
|
||||
|
@ -92,4 +82,3 @@ class MyApp extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
import 'dart:convert';
|
||||
|
||||
Attachment attachmentFromJson(String str) =>
|
||||
Attachment.fromJson(json.decode(str));
|
||||
|
||||
String attachmentToJson(Attachment data) => json.encode(data.toJson());
|
||||
|
||||
class Attachment {
|
||||
final int? id;
|
||||
final String? source;
|
||||
final AttachmentCategory? category;
|
||||
final String? filename;
|
||||
final Subclass? subclass;
|
||||
final DateTime? createdAt;
|
||||
|
||||
Attachment({
|
||||
required this.id,
|
||||
required this.source,
|
||||
required this.category,
|
||||
required this.filename,
|
||||
required this.subclass,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
factory Attachment.fromJson(Map<String, dynamic> json) => Attachment(
|
||||
id: json["id"],
|
||||
source: json["source"],
|
||||
category: json['category'] == null
|
||||
? null
|
||||
: AttachmentCategory.fromJson(json["category"]),
|
||||
filename: json["filename"],
|
||||
subclass: json['subclass'] == null
|
||||
? null
|
||||
: Subclass.fromJson(json["subclass"]),
|
||||
createdAt: json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json["created_at"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"source": source,
|
||||
"category": category?.toJson(),
|
||||
"filename": filename,
|
||||
"subclass": subclass?.toJson(),
|
||||
"created_at": createdAt?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
class AttachmentCategory {
|
||||
final int? id;
|
||||
final Subclass? subclass;
|
||||
final String? description;
|
||||
|
||||
AttachmentCategory({
|
||||
required this.id,
|
||||
required this.subclass,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
factory AttachmentCategory.fromJson(Map<String, dynamic> json) => AttachmentCategory(
|
||||
id: json["id"],
|
||||
subclass:json['subclass'] == null? null: Subclass.fromJson(json["subclass"]),
|
||||
description: json["description"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"subclass": subclass?.toJson(),
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
|
||||
class Subclass {
|
||||
final int? id;
|
||||
final String? name;
|
||||
final AttachmentClass? attachmentClass;
|
||||
|
||||
Subclass({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.attachmentClass,
|
||||
});
|
||||
|
||||
factory Subclass.fromJson(Map<String, dynamic> json) => Subclass(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
attachmentClass: json['attachment_class'] == null? null: AttachmentClass.fromJson(json["attachment_class"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"attachment_class": attachmentClass?.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
class AttachmentClass {
|
||||
final int? id;
|
||||
final String? name;
|
||||
|
||||
AttachmentClass({
|
||||
required this.id,
|
||||
required this.name,
|
||||
});
|
||||
|
||||
factory AttachmentClass.fromJson(Map<String, dynamic> json) =>
|
||||
AttachmentClass(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
};
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/model/profile/attachment.dart';
|
||||
|
||||
EducationalBackground educationalBackgroundFromJson(String str) => EducationalBackground.fromJson(json.decode(str));
|
||||
|
||||
String educationalBackgroundToJson(EducationalBackground data) => json.encode(data.toJson());
|
||||
|
@ -24,7 +26,7 @@ class EducationalBackground {
|
|||
final List<Honor>? honors;
|
||||
final Education? education;
|
||||
final String? periodTo;
|
||||
final dynamic attachments;
|
||||
List<Attachment>? attachments;
|
||||
final String? periodFrom;
|
||||
final int? unitsEarned;
|
||||
final String? yearGraduated;
|
||||
|
@ -34,7 +36,7 @@ class EducationalBackground {
|
|||
honors: json["honors"] == null ? [] : List<Honor>.from(json["honors"]!.map((x) => Honor.fromJson(x))),
|
||||
education: json["education"] == null ? null : Education.fromJson(json["education"]),
|
||||
periodTo: json["period_to"],
|
||||
attachments: json["attachments"],
|
||||
attachments: json['attachments'] ==null?null: List<Attachment>.from(json["attachments"].map((x) => Attachment.fromJson(x))),
|
||||
periodFrom: json["period_from"],
|
||||
unitsEarned: json["units_earned"],
|
||||
yearGraduated: json["year_graduated"],
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:meta/meta.dart';
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/model/location/region.dart';
|
||||
import 'package:unit2/model/profile/attachment.dart';
|
||||
|
||||
import '../location/address_category.dart';
|
||||
import '../location/city.dart';
|
||||
|
@ -33,7 +34,8 @@ class EligibityCert {
|
|||
final int? id;
|
||||
final double? rating;
|
||||
final DateTime? examDate;
|
||||
final dynamic attachments;
|
||||
List<Attachment>? attachments;
|
||||
|
||||
final Eligibility? eligibility;
|
||||
final ExamAddress? examAddress;
|
||||
final DateTime? validityDate;
|
||||
|
@ -45,7 +47,7 @@ class EligibityCert {
|
|||
examDate: json['exam_date'] == null
|
||||
? null
|
||||
: DateTime.parse(json["exam_date"]),
|
||||
attachments: null,
|
||||
attachments: json['attachments'] ==null?null: List<Attachment>.from(json["attachments"].map((x) => Attachment.fromJson(x))),
|
||||
eligibility: json['eligibility'] == null
|
||||
? null
|
||||
: Eligibility.fromJson(json["eligibility"]),
|
||||
|
|
|
@ -10,6 +10,7 @@ import '../location/city.dart';
|
|||
import '../location/country.dart';
|
||||
import '../utils/agency.dart';
|
||||
import '../utils/industry_class.dart';
|
||||
import 'attachment.dart';
|
||||
|
||||
LearningDevelopement learningDevelopementFromJson(String str) => LearningDevelopement.fromJson(json.decode(str));
|
||||
|
||||
|
@ -23,13 +24,13 @@ class LearningDevelopement {
|
|||
this.totalHoursAttended,
|
||||
});
|
||||
|
||||
final dynamic attachments;
|
||||
List<Attachment>? attachments;
|
||||
final Agency? sponsoredBy;
|
||||
final ConductedTraining? conductedTraining;
|
||||
final double? totalHoursAttended;
|
||||
|
||||
factory LearningDevelopement.fromJson(Map<String, dynamic> json) => LearningDevelopement(
|
||||
attachments: json["attachments"],
|
||||
attachments: json['attachments'] ==null?null: List<Attachment>.from(json["attachments"].map((x) => Attachment.fromJson(x))),
|
||||
sponsoredBy: json["sponsored_by"] == null ? null : Agency.fromJson(json["sponsored_by"]),
|
||||
conductedTraining: json["conducted_training"] == null ? null : ConductedTraining.fromJson(json["conducted_training"]),
|
||||
totalHoursAttended: json["total_hours_attended"],
|
||||
|
|
|
@ -8,6 +8,7 @@ import '../utils/agency.dart';
|
|||
import '../utils/category.dart';
|
||||
import '../utils/industry_class.dart';
|
||||
import '../utils/position.dart';
|
||||
import 'attachment.dart';
|
||||
|
||||
WorkHistory workHistoryFromJson(String str) => WorkHistory.fromJson(json.decode(str));
|
||||
|
||||
|
@ -21,7 +22,7 @@ class WorkHistory {
|
|||
this.toDate,
|
||||
this.position,
|
||||
this.fromDate,
|
||||
// this.attachments,
|
||||
this.attachments,
|
||||
this.salaryGrade,
|
||||
this.monthlySalary,
|
||||
this.appointmentStatus,
|
||||
|
@ -33,7 +34,7 @@ class WorkHistory {
|
|||
final DateTime? toDate;
|
||||
final Position? position;
|
||||
final DateTime? fromDate;
|
||||
// final dynamic attachments;
|
||||
List<Attachment>? attachments;
|
||||
final int? salaryGrade;
|
||||
final double? monthlySalary;
|
||||
final String? appointmentStatus;
|
||||
|
@ -45,7 +46,7 @@ class WorkHistory {
|
|||
toDate: json["to_date"] == null ? null : DateTime.parse(json["to_date"]),
|
||||
position: json["position"] == null ? null : Position.fromJson(json["position"]),
|
||||
fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]),
|
||||
// attachments: json["attachments"],
|
||||
attachments: json['attachments'] ==null?null: List<Attachment>.from(json["attachments"].map((x) => Attachment.fromJson(x))),
|
||||
salaryGrade: json["salary_grade"],
|
||||
monthlySalary: json["monthly_salary"],
|
||||
appointmentStatus: json["appointment_status"],
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/profile/educational_background.dart';
|
||||
import 'package:unit2/screens/profile/components/education/add_modal.dart';
|
||||
|
@ -13,13 +20,25 @@ import 'package:unit2/widgets/Leadings/add_leading.dart';
|
|||
import 'package:unit2/widgets/empty_data.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
import '../../../bloc/profile/education/education_bloc.dart';
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../../../utils/global.dart';
|
||||
import '../../../widgets/Leadings/close_leading.dart';
|
||||
import '../shared/multiple_attachment.dart';
|
||||
import '../shared/single_attachment.dart';
|
||||
import 'education/edit_modal.dart';
|
||||
|
||||
class EducationScreen extends StatelessWidget {
|
||||
const EducationScreen({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final parent = context;
|
||||
|
||||
List<PlatformFile>? results = [];
|
||||
AttachmentCategory? selectedAttachmentCategory;
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
int profileId;
|
||||
String? token;
|
||||
return Scaffold(
|
||||
|
@ -99,6 +118,28 @@ class EducationScreen extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT ADDED STATE
|
||||
|
||||
if (state is EducationAttachmentAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
}
|
||||
}
|
||||
////EDITED STATE
|
||||
if (state is EditedEducationState) {
|
||||
if (state.response['success']) {
|
||||
|
@ -141,9 +182,35 @@ class EducationScreen extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT DELETED STATE
|
||||
if (state is EducationAttachmentDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Attachment has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting Attachment", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is EducationalBackgroundLoadedState) {
|
||||
for (var cat in state.attachmentCategory) {
|
||||
if (cat.subclass!.id == 1) {
|
||||
attachmentCategories.add(cat);
|
||||
}
|
||||
}
|
||||
if (state.educationalBackground.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
@ -182,54 +249,91 @@ class EducationScreen extends StatelessWidget {
|
|||
decoration: box1(),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
child: Row(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Row(
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(level,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall!)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
level,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall!)),
|
||||
Text(
|
||||
"$periodFrom - $periodTo",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$periodFrom - $periodTo",
|
||||
school,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.bodyMedium,
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
color:
|
||||
primary,
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
school,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
color: primary,
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w500),
|
||||
),
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.only(top: 8),
|
||||
child: honors
|
||||
.isNotEmpty
|
||||
? Column(
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.only(
|
||||
top: 8),
|
||||
child: honors
|
||||
.isNotEmpty
|
||||
? Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height:
|
||||
8,
|
||||
),
|
||||
const Text(
|
||||
" honors: ",
|
||||
style:
|
||||
TextStyle(fontWeight: FontWeight.w600),
|
||||
),
|
||||
Column(
|
||||
children: honors
|
||||
.map((Honor honor) => Text(
|
||||
"-${honor.name!.trim()}",
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const SizedBox()),
|
||||
program == null
|
||||
? const SizedBox()
|
||||
: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
|
@ -238,104 +342,420 @@ class EducationScreen extends StatelessWidget {
|
|||
.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
const Text(
|
||||
" honors: ",
|
||||
style: TextStyle(
|
||||
fontWeight:
|
||||
FontWeight.w600),
|
||||
),
|
||||
Column(
|
||||
children: honors
|
||||
.map((Honor honor) => Text(
|
||||
"-${honor.name!.trim()}",
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
))
|
||||
.toList(),
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
program),
|
||||
],
|
||||
)
|
||||
: const SizedBox()),
|
||||
program == null
|
||||
? const SizedBox()
|
||||
: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(program),
|
||||
],
|
||||
),
|
||||
]),
|
||||
]),
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset:
|
||||
const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete -= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context,
|
||||
() {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!
|
||||
.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<
|
||||
EducationBloc>()
|
||||
.add(DeleteEducation(
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index],
|
||||
profileId:
|
||||
profileId,
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit -= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<
|
||||
EducationBloc>()
|
||||
.add(ShowEditEducationForm(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token!,
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index]));
|
||||
}
|
||||
if (value == 3) {
|
||||
results.clear();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(BuildContext
|
||||
context) {
|
||||
return AlertDialog(
|
||||
contentPadding:
|
||||
const EdgeInsets
|
||||
.all(0),
|
||||
backgroundColor:
|
||||
Colors.grey
|
||||
.shade100,
|
||||
icon:
|
||||
const Icon(
|
||||
Icons
|
||||
.file_copy,
|
||||
size: 32,
|
||||
color:
|
||||
primary,
|
||||
),
|
||||
title: const Text(
|
||||
"File Attachment:"),
|
||||
content: StatefulBuilder(
|
||||
builder:
|
||||
(context,
|
||||
setState) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets
|
||||
.all(
|
||||
16.0),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize
|
||||
.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
Text(
|
||||
program ??
|
||||
level,
|
||||
style:
|
||||
Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
school,
|
||||
style: Theme.of(context).textTheme.titleSmall),
|
||||
const SizedBox(
|
||||
height:
|
||||
3,
|
||||
),
|
||||
Text(
|
||||
"$periodFrom - $periodTo",
|
||||
style: Theme.of(context).textTheme.titleSmall),
|
||||
const Divider(),
|
||||
FormBuilderDropdown(
|
||||
autovalidateMode: AutovalidateMode.always,
|
||||
decoration: normalTextFieldStyle("attachment category", "attachment category"),
|
||||
name: 'attachments_categorues',
|
||||
validator: FormBuilderValidators.required(errorText: "This field is required"),
|
||||
onChanged: (value) {
|
||||
selectedAttachmentCategory = value;
|
||||
},
|
||||
items: attachmentCategories.map((e) {
|
||||
return DropdownMenuItem(value: e, child: Text(e.description!));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height:
|
||||
8,
|
||||
),
|
||||
Text(
|
||||
"You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
"Acceptable Files: PDF, JPEG, PNG",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
Text(
|
||||
"Max File Size (per attachment): 1MB",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
const Divider(),
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
elevation: MaterialStateProperty.all(0),
|
||||
backgroundColor: MaterialStateProperty.all<Color>(Colors.white),
|
||||
),
|
||||
onPressed: () async {
|
||||
FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
|
||||
'jpg',
|
||||
'png',
|
||||
'jpeg',
|
||||
'pdf'
|
||||
]);
|
||||
setState(() {
|
||||
if (newResult != null) {
|
||||
newResult.files.forEach((element) {
|
||||
results.add(element);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Select Files",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.black),
|
||||
))),
|
||||
const Divider(),
|
||||
SingleChildScrollView(
|
||||
child:
|
||||
SizedBox(
|
||||
height: 100,
|
||||
width: double.maxFinite,
|
||||
child: results.isEmpty
|
||||
? const SizedBox()
|
||||
: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: results.length,
|
||||
itemBuilder: (BuildContext context, index) {
|
||||
final kb = results[index].size / 1024;
|
||||
final mb = kb / 1024;
|
||||
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
child: results[index].extension!.toLowerCase() == 'pdf'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/pdf.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'png'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/png.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: const SizedBox())),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(
|
||||
flex: 6,
|
||||
child: Text(
|
||||
results[index].name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
size,
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
|
||||
)),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
results.removeAt(index);
|
||||
});
|
||||
},
|
||||
))
|
||||
],
|
||||
)),
|
||||
const Divider()
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
12,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
double.maxFinite,
|
||||
height:
|
||||
50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
List<String> paths = [];
|
||||
|
||||
if (selectedAttachmentCategory != null && results.isNotEmpty) {
|
||||
for (var res in results) {
|
||||
paths.add(res.path!);
|
||||
}
|
||||
setState(() {
|
||||
results.clear();
|
||||
});
|
||||
Navigator.pop(context);
|
||||
parent.read<EducationBloc>().add(AddEducationAttachment(attachmentModule: state.educationalBackground[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString()));
|
||||
}
|
||||
},
|
||||
child: const Text("Submit")),
|
||||
)
|
||||
]),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 3,
|
||||
icon: Icons
|
||||
.attach_file),
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
],
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete -= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(DeleteEducation(
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index],
|
||||
|
||||
////Show Attachments
|
||||
SizedBox(
|
||||
child: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments ==
|
||||
null ||
|
||||
state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments!
|
||||
.isEmpty
|
||||
? const SizedBox()
|
||||
: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments !=
|
||||
null &&
|
||||
state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments!
|
||||
.length ==
|
||||
1
|
||||
?
|
||||
////Single Attachment view
|
||||
Column(
|
||||
children: [
|
||||
const Divider(),
|
||||
SingleAttachment(
|
||||
onpressed:
|
||||
() {
|
||||
confirmAlert(
|
||||
context,
|
||||
() {
|
||||
parent.read<EducationBloc>().add(DeleteEducationAttachment(
|
||||
attachment: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
moduleId: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.id!,
|
||||
profileId:
|
||||
profileId,
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
},
|
||||
attachment: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
),
|
||||
],
|
||||
)
|
||||
////Multiple Attachments View
|
||||
: MultipleAttachments(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit -= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(ShowEditEducationForm(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token!,
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index]));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 2,
|
||||
icon: Icons.attach_file),
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
token: token!,
|
||||
eligibilityName: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.education!
|
||||
.school!
|
||||
.name!,
|
||||
attachments: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.attachments!,
|
||||
educationBloc:
|
||||
BlocProvider.of<
|
||||
EducationBloc>(
|
||||
parent),
|
||||
eligibilityBloc:
|
||||
null,
|
||||
workHistoryBloc:
|
||||
null,
|
||||
learningDevelopmentBloc:
|
||||
null,
|
||||
blocId: 1,
|
||||
moduleId: state
|
||||
.educationalBackground[
|
||||
index]
|
||||
.id!,
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
import 'dart:io';
|
||||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/profile/attachment.dart';
|
||||
import 'package:unit2/model/profile/eligibility.dart';
|
||||
import 'package:unit2/screens/profile/components/eligibility/add_modal.dart';
|
||||
import 'package:unit2/screens/profile/components/eligibility/edit_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/btn-style.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
import 'package:unit2/widgets/Leadings/add_leading.dart';
|
||||
|
@ -19,21 +29,27 @@ import 'package:unit2/widgets/empty_data.dart';
|
|||
import 'package:unit2/widgets/error_state.dart';
|
||||
import '../../../bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../shared/multiple_attachment.dart';
|
||||
import '../shared/single_attachment.dart';
|
||||
|
||||
class EligibiltyScreen extends StatelessWidget {
|
||||
const EligibiltyScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
BuildContext parent = context;
|
||||
String? token;
|
||||
int? profileId;
|
||||
List<PlatformFile>? results = [];
|
||||
AttachmentCategory? selectedAttachmentCategory;
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return true;
|
||||
},
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
title: context.watch<EligibilityBloc>().state is AddEligibilityState
|
||||
? const Text("Add Eligiblity")
|
||||
|
@ -42,31 +58,37 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
: const Text(elibilityScreenTitle),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
actions: (context.watch<EligibilityBloc>().state is EligibilityLoaded)
|
||||
|
||||
? [
|
||||
AddLeading(onPressed: () {
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(ShowAddEligibilityForm());
|
||||
})
|
||||
]
|
||||
:(context.watch<EligibilityBloc>().state is AddEligibilityState || context.watch<EligibilityBloc>().state is EditEligibilityState)? [
|
||||
CloseLeading(onPressed: () {
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility());
|
||||
})
|
||||
]:[],
|
||||
actions:
|
||||
(context.watch<EligibilityBloc>().state is EligibilityLoaded)
|
||||
? [
|
||||
AddLeading(onPressed: () {
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(ShowAddEligibilityForm());
|
||||
})
|
||||
]
|
||||
: (context.watch<EligibilityBloc>().state
|
||||
is AddEligibilityState ||
|
||||
context.watch<EligibilityBloc>().state
|
||||
is EditEligibilityState)
|
||||
? [
|
||||
CloseLeading(onPressed: () {
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
})
|
||||
]
|
||||
: [],
|
||||
),
|
||||
body: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId =
|
||||
state.userData!.user!.login!.user!.profileId;
|
||||
profileId = state.userData!.user!.login!.user!.profileId;
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
if(state is ProfileLoaded){
|
||||
return ProgressHUD(
|
||||
builder: (context, state) {
|
||||
if (state is ProfileLoaded) {
|
||||
return ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
indicatorWidget: const SpinKitFadingCircle(
|
||||
color: Colors.white,
|
||||
|
@ -81,30 +103,53 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
if (state is EligibilityLoaded ||
|
||||
state is AddEligibilityState ||
|
||||
state is EditEligibilityState ||
|
||||
state is DeletedState ||
|
||||
state is EligibilityDeletedState ||
|
||||
state is EligibilityAddedState ||
|
||||
state is EligibilityEditedState ||
|
||||
state is EligibilityErrorState
|
||||
) {
|
||||
state is EligibilityErrorState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
////DELETED STATE
|
||||
if (state is DeletedState) {
|
||||
if (state is EligibilityDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Eligibility has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting eligibility", () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT ADDED STATE
|
||||
|
||||
if (state is EligibilityAttachmentAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -114,16 +159,18 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -133,16 +180,39 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
successAlert(context, "Update Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Update Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context.read<EligibilityBloc>().add(const LoadEligibility(
|
||||
));
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT DELETED STATE
|
||||
if (state is EligibilitytAttachmentDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Attachment has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting Attachment", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(const LoadEligibility());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +221,11 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
return BlocBuilder<EligibilityBloc, EligibilityState>(
|
||||
builder: (context, state) {
|
||||
if (state is EligibilityLoaded) {
|
||||
|
||||
for (var cat in state.attachmentCategory) {
|
||||
if (cat.subclass!.id == 3) {
|
||||
attachmentCategories.add(cat);
|
||||
}
|
||||
}
|
||||
if (state.eligibilities.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
@ -164,153 +238,466 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
.eligibility!
|
||||
.title;
|
||||
return Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: screenWidth,
|
||||
padding:
|
||||
const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 8),
|
||||
decoration: box1(),
|
||||
child: Row(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w500,color: primary),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w500,
|
||||
color:
|
||||
primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Text(
|
||||
"Rating : ${state.eligibilities[index].rating ?? 'N/A'}",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall),
|
||||
]),
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(
|
||||
-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete eligibilty-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(
|
||||
context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!
|
||||
.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider
|
||||
.of<EligibilityBloc>(
|
||||
context)
|
||||
.add(DeleteEligibility(
|
||||
eligibilityId: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.id!,
|
||||
profileId:
|
||||
profileId
|
||||
.toString(),
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit eligibilty-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!
|
||||
.showWithText(
|
||||
"Loading...");
|
||||
EligibityCert
|
||||
eligibityCert =
|
||||
state.eligibilities[
|
||||
index];
|
||||
bool overseas = eligibityCert
|
||||
.examAddress!
|
||||
.country!
|
||||
.id
|
||||
.toString() ==
|
||||
'175'
|
||||
? false
|
||||
: true;
|
||||
eligibityCert
|
||||
.overseas =
|
||||
overseas;
|
||||
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Text(
|
||||
"Rating : ${state.eligibilities[index].rating ?? 'N/A'}.",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall)
|
||||
]),
|
||||
eligibityCert
|
||||
.overseas =
|
||||
overseas;
|
||||
|
||||
context
|
||||
.read<
|
||||
EligibilityBloc>()
|
||||
.add(ShowEditEligibilityForm(
|
||||
eligibityCert:
|
||||
eligibityCert));
|
||||
}
|
||||
////Attachment
|
||||
if (value == 3) {
|
||||
results.clear();
|
||||
showDialog(
|
||||
context:
|
||||
context,
|
||||
builder:
|
||||
(BuildContext
|
||||
context) {
|
||||
return AlertDialog(
|
||||
contentPadding:
|
||||
const EdgeInsets
|
||||
.all(0),
|
||||
backgroundColor:
|
||||
Colors
|
||||
.grey
|
||||
.shade100,
|
||||
icon:
|
||||
const Icon(
|
||||
Icons
|
||||
.file_copy,
|
||||
size: 32,
|
||||
color:
|
||||
primary,
|
||||
),
|
||||
title: const Text(
|
||||
"File Attachment:"),
|
||||
content: StatefulBuilder(builder:
|
||||
(context,
|
||||
setState) {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text("$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", style: Theme.of(context).textTheme.titleSmall),
|
||||
const SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Text("Rating : ${state.eligibilities[index].rating ?? 'N/A'}", style: Theme.of(context).textTheme.titleSmall),
|
||||
const Divider(),
|
||||
FormBuilderDropdown(
|
||||
autovalidateMode: AutovalidateMode.always,
|
||||
decoration: normalTextFieldStyle("attachment category", "attachment category"),
|
||||
name: 'attachments_categorues',
|
||||
validator: FormBuilderValidators.required(errorText: "This field is required"),
|
||||
onChanged: (value) {
|
||||
selectedAttachmentCategory = value;
|
||||
},
|
||||
items: attachmentCategories.map((e) {
|
||||
return DropdownMenuItem(value: e, child: Text(e.description!));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
"You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.",
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"Acceptable Files: PDF, JPEG, PNG",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
Text(
|
||||
"Max File Size (per attachment): 1MB",
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
const Divider(),
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
elevation: MaterialStateProperty.all(0),
|
||||
backgroundColor: MaterialStateProperty.all<Color>(Colors.white),
|
||||
),
|
||||
onPressed: () async {
|
||||
FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
|
||||
'jpg',
|
||||
'png',
|
||||
'jpeg',
|
||||
'pdf'
|
||||
]);
|
||||
setState(() {
|
||||
FilePickerResult? x;
|
||||
if (newResult != null) {
|
||||
newResult.files.forEach((element) {
|
||||
results.add(element);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Select Files",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.black),
|
||||
))),
|
||||
const Divider(),
|
||||
SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
width: double.maxFinite,
|
||||
child: results.isEmpty
|
||||
? const SizedBox()
|
||||
: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: results.length,
|
||||
itemBuilder: (BuildContext context, index) {
|
||||
final kb = results[index].size / 1024;
|
||||
final mb = kb / 1024;
|
||||
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
child: results[index].extension!.toLowerCase() == 'pdf'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/pdf.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'png'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/png.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: const SizedBox())),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(
|
||||
flex: 6,
|
||||
child: Text(
|
||||
results[index].name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
size,
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
|
||||
)),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
results.removeAt(index);
|
||||
});
|
||||
},
|
||||
))
|
||||
],
|
||||
)),
|
||||
const Divider()
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: double.maxFinite,
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
List<String> paths = [];
|
||||
|
||||
if (selectedAttachmentCategory != null && results.isNotEmpty) {
|
||||
for (var res in results) {
|
||||
paths.add(res.path!);
|
||||
}
|
||||
setState(() {
|
||||
results.clear();
|
||||
});
|
||||
Navigator.pop(context);
|
||||
parent.read<EligibilityBloc>().add(AddEligibiltyAttachment(attachmentModule: state.eligibilities[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString()));
|
||||
}
|
||||
},
|
||||
child: const Text("Submit")),
|
||||
)
|
||||
]),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon:
|
||||
Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 3,
|
||||
icon: Icons
|
||||
.attach_file),
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
],
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset:
|
||||
const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
|
||||
////delete eligibilty-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
|
||||
confirmAlert(context,
|
||||
() {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<
|
||||
EligibilityBloc>(
|
||||
context)
|
||||
.add(DeleteEligibility(
|
||||
|
||||
|
||||
eligibilityId: state
|
||||
const Divider(),
|
||||
////Show Attachments
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.id!,
|
||||
.attachments ==
|
||||
null ||
|
||||
state
|
||||
.eligibilities[
|
||||
index]
|
||||
.attachments!
|
||||
.isEmpty
|
||||
? const SizedBox()
|
||||
: state.eligibilities[index].attachments !=
|
||||
null &&
|
||||
state
|
||||
.eligibilities[
|
||||
index]
|
||||
.attachments!
|
||||
.length ==
|
||||
1
|
||||
?
|
||||
////Single Attachment view
|
||||
SingleAttachment(
|
||||
onpressed:
|
||||
() {
|
||||
confirmAlert(
|
||||
context,
|
||||
() {
|
||||
parent.read<EligibilityBloc>().add(DeleteEligibyAttachment(
|
||||
attachment: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
moduleId: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.id
|
||||
.toString(),
|
||||
profileId: profileId
|
||||
.toString(),
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
},
|
||||
attachment: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
)
|
||||
////Multiple Attachments View
|
||||
: MultipleAttachments(
|
||||
profileId:
|
||||
profileId.toString(),
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit eligibilty-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
EligibityCert
|
||||
eligibityCert =
|
||||
state.eligibilities[
|
||||
index];
|
||||
bool overseas = eligibityCert
|
||||
.examAddress!
|
||||
.country!
|
||||
.id
|
||||
.toString() ==
|
||||
'175'
|
||||
? false
|
||||
: true;
|
||||
eligibityCert.overseas =
|
||||
overseas;
|
||||
|
||||
eligibityCert.overseas =
|
||||
overseas;
|
||||
|
||||
context
|
||||
.read<EligibilityBloc>()
|
||||
.add(ShowEditEligibilityForm(
|
||||
eligibityCert:
|
||||
eligibityCert));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 2,
|
||||
icon: Icons.attach_file),
|
||||
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
profileId!,
|
||||
token: token!,
|
||||
moduleId: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.eligibility!
|
||||
.id,
|
||||
educationBloc:
|
||||
null,
|
||||
learningDevelopmentBloc:
|
||||
null,
|
||||
workHistoryBloc:
|
||||
null,
|
||||
eligibilityBloc:
|
||||
BlocProvider.of<
|
||||
EligibilityBloc>(
|
||||
context),
|
||||
blocId: 2,
|
||||
eligibilityName: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.eligibility!
|
||||
.title,
|
||||
attachments: state
|
||||
.eligibilities[
|
||||
index]
|
||||
.attachments!,
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
@ -322,17 +709,25 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
}
|
||||
if (state is EditEligibilityState) {
|
||||
return EditEligibilityScreen(
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
eligibityCert: state.eligibityCert);
|
||||
}
|
||||
if (state is AddEligibilityState) {
|
||||
return AddEligibilityScreen(token: token!,profileId: profileId!,);
|
||||
return AddEligibilityScreen(
|
||||
token: token!,
|
||||
profileId: profileId!,
|
||||
);
|
||||
}
|
||||
if (state is EligibilityErrorState) {
|
||||
return SomethingWentWrong(message: state.message, onpressed: (){
|
||||
context.read<EligibilityBloc>().add(GetEligibilities(token: token!,profileId: profileId!));
|
||||
});
|
||||
return SomethingWentWrong(
|
||||
message: state.message,
|
||||
onpressed: () {
|
||||
context.read<EligibilityBloc>().add(
|
||||
GetEligibilities(
|
||||
token: token!,
|
||||
profileId: profileId!));
|
||||
});
|
||||
}
|
||||
return Container(
|
||||
color: Colors.grey.shade200,
|
||||
|
@ -342,11 +737,9 @@ class EligibiltyScreen extends StatelessWidget {
|
|||
},
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
return Container();
|
||||
}
|
||||
);
|
||||
return Container();
|
||||
});
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/profile/learning_development.dart';
|
||||
import 'package:unit2/screens/profile/components/learning_development/edit_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
|
@ -19,8 +22,13 @@ import 'package:unit2/widgets/Leadings/add_leading.dart';
|
|||
import 'package:unit2/widgets/empty_data.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
import '../../../bloc/profile/learningDevelopment/learning_development_bloc.dart';
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../../../widgets/Leadings/close_leading.dart';
|
||||
import '../shared/multiple_attachment.dart';
|
||||
import '../shared/single_attachment.dart';
|
||||
import 'learning_development/add_modal.dart';
|
||||
|
||||
class LearningAndDevelopmentScreen extends StatelessWidget {
|
||||
|
@ -32,7 +40,11 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
String token;
|
||||
int profileId;
|
||||
BuildContext parent = context;
|
||||
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
||||
List<PlatformFile>? results = [];
|
||||
AttachmentCategory? selectedAttachmentCategory;
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: context.watch<LearningDevelopmentBloc>().state
|
||||
|
@ -76,13 +88,11 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
backgroundColor: Colors.black87,
|
||||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token!;
|
||||
profileId = state.userData!.user!.login!.user!.profileId!;
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
|
||||
if (state is ProfileLoaded) {
|
||||
return BlocConsumer<LearningDevelopmentBloc,
|
||||
LearningDevelopmentState>(
|
||||
|
@ -121,6 +131,27 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
}
|
||||
////Attachment Added State
|
||||
if (state is LearningDevAttachmentAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<LearningDevelopmentBloc>()
|
||||
.add(LoadLearniningDevelopment());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<LearningDevelopmentBloc>()
|
||||
.add(LoadLearniningDevelopment());
|
||||
});
|
||||
}
|
||||
}
|
||||
////Updated State
|
||||
if (state is LearningDevelopmentUpdatedState) {
|
||||
if (state.response['success']) {
|
||||
|
@ -164,12 +195,36 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT DELETED STATE
|
||||
if (state is LearningDevAttachmentDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Attachment has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<LearningDevelopmentBloc>()
|
||||
.add(LoadLearniningDevelopment());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting Attachment", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<LearningDevelopmentBloc>()
|
||||
.add(LoadLearniningDevelopment());
|
||||
});
|
||||
}
|
||||
}
|
||||
// TODO: implement listener
|
||||
},
|
||||
builder: (context, state) {
|
||||
print(state);
|
||||
if (state is LearningDevelopmentLoadedState) {
|
||||
|
||||
for (var cat in state.attachmentCategory) {
|
||||
if (cat.subclass!.id == 2) {
|
||||
attachmentCategories.add(cat);
|
||||
}
|
||||
}
|
||||
if (state.learningsAndDevelopment.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
@ -208,66 +263,73 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
training,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w600,
|
||||
color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
provider,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$duration: $start to $end",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
]),
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete -= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<
|
||||
LearningDevelopmentBloc>(
|
||||
context)
|
||||
.add(DeleteLearningDevelopment(
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
training,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w600,
|
||||
color:
|
||||
primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
provider,
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.titleSmall,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$duration: $start to $end",
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.labelMedium,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
]),
|
||||
),
|
||||
AppPopupMenu<int>(
|
||||
offset:
|
||||
const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete -= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context,
|
||||
() {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!
|
||||
.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<LearningDevelopmentBloc>(context).add(DeleteLearningDevelopment(
|
||||
trainingId: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
|
@ -286,62 +348,394 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
|
|||
profileId:
|
||||
profileId,
|
||||
token: token));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
bool isOverseas;
|
||||
////edit = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
bool isOverseas;
|
||||
////edit = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
|
||||
if (state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.conductedTraining
|
||||
?.venue
|
||||
?.cityMunicipality ==
|
||||
null) {
|
||||
isOverseas = true;
|
||||
} else {
|
||||
isOverseas = false;
|
||||
}
|
||||
context
|
||||
.read<
|
||||
LearningDevelopmentBloc>()
|
||||
.add(ShowEditLearningDevelopmentForm(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token,
|
||||
learningDevelopment:
|
||||
state.learningsAndDevelopment[
|
||||
index],
|
||||
isOverseas:
|
||||
isOverseas));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 2,
|
||||
icon: Icons.attach_file),
|
||||
if (state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.conductedTraining
|
||||
?.venue
|
||||
?.cityMunicipality ==
|
||||
null) {
|
||||
isOverseas = true;
|
||||
} else {
|
||||
isOverseas = false;
|
||||
}
|
||||
context
|
||||
.read<
|
||||
LearningDevelopmentBloc>()
|
||||
.add(ShowEditLearningDevelopmentForm(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token,
|
||||
learningDevelopment:
|
||||
state.learningsAndDevelopment[
|
||||
index],
|
||||
isOverseas:
|
||||
isOverseas));
|
||||
}
|
||||
if (value == 3) {
|
||||
results.clear();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(BuildContext
|
||||
context) {
|
||||
return AlertDialog(
|
||||
contentPadding:
|
||||
const EdgeInsets
|
||||
.all(0),
|
||||
backgroundColor:
|
||||
Colors.grey
|
||||
.shade100,
|
||||
icon:
|
||||
const Icon(
|
||||
Icons
|
||||
.file_copy,
|
||||
size: 32,
|
||||
color:
|
||||
primary,
|
||||
),
|
||||
title: const Text(
|
||||
"File Attachment:"),
|
||||
content: StatefulBuilder(
|
||||
builder:
|
||||
(context,
|
||||
setState) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets
|
||||
.all(
|
||||
16.0),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize
|
||||
.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
Text(
|
||||
training,
|
||||
style:
|
||||
Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
provider,
|
||||
style: Theme.of(context).textTheme.titleSmall),
|
||||
const SizedBox(
|
||||
height:
|
||||
3,
|
||||
),
|
||||
Text(
|
||||
"$start TO $end",
|
||||
style: Theme.of(context).textTheme.titleSmall),
|
||||
const Divider(),
|
||||
FormBuilderDropdown(
|
||||
autovalidateMode: AutovalidateMode.always,
|
||||
decoration: normalTextFieldStyle("attachment category", "attachment category"),
|
||||
name: 'attachments_categorues',
|
||||
validator: FormBuilderValidators.required(errorText: "This field is required"),
|
||||
onChanged: (value) {
|
||||
selectedAttachmentCategory = value;
|
||||
},
|
||||
items: attachmentCategories.map((e) {
|
||||
return DropdownMenuItem(value: e, child: Text(e.description!));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height:
|
||||
8,
|
||||
),
|
||||
Text(
|
||||
"You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
"Acceptable Files: PDF, JPEG, PNG",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
Text(
|
||||
"Max File Size (per attachment): 1MB",
|
||||
style:
|
||||
Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
const Divider(),
|
||||
ElevatedButton(
|
||||
style: ButtonStyle(
|
||||
elevation: MaterialStateProperty.all(0),
|
||||
backgroundColor: MaterialStateProperty.all<Color>(Colors.white),
|
||||
),
|
||||
onPressed: () async {
|
||||
FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
|
||||
'jpg',
|
||||
'png',
|
||||
'jpeg',
|
||||
'pdf'
|
||||
]);
|
||||
setState(() {
|
||||
if (newResult != null) {
|
||||
newResult.files.forEach((element) {
|
||||
results.add(element);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Select Files",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.black),
|
||||
))),
|
||||
const Divider(),
|
||||
SingleChildScrollView(
|
||||
child:
|
||||
SizedBox(
|
||||
height: 100,
|
||||
width: double.maxFinite,
|
||||
child: results.isEmpty
|
||||
? const SizedBox()
|
||||
: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: results.length,
|
||||
itemBuilder: (BuildContext context, index) {
|
||||
final kb = results[index].size / 1024;
|
||||
final mb = kb / 1024;
|
||||
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: SizedBox(
|
||||
child: results[index].extension!.toLowerCase() == 'pdf'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/pdf.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'png'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/png.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: const SizedBox())),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(
|
||||
flex: 6,
|
||||
child: Text(
|
||||
results[index].name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
size,
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
|
||||
)),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
results.removeAt(index);
|
||||
});
|
||||
},
|
||||
))
|
||||
],
|
||||
)),
|
||||
const Divider()
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
12,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
double.maxFinite,
|
||||
height:
|
||||
50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
List<String> paths = [];
|
||||
|
||||
if (selectedAttachmentCategory != null && results.isNotEmpty) {
|
||||
for (var res in results) {
|
||||
paths.add(res.path!);
|
||||
}
|
||||
results.clear();
|
||||
Navigator.pop(context);
|
||||
parent.read<LearningDevelopmentBloc>().add(AddALearningDevttachment(attachmentModule: state.learningsAndDevelopment[index].conductedTraining!.id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token, profileId: profileId.toString()));
|
||||
}
|
||||
},
|
||||
child: const Text("Submit")),
|
||||
)
|
||||
]),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 3,
|
||||
icon: Icons
|
||||
.attach_file),
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
),
|
||||
SizedBox(
|
||||
child: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments ==
|
||||
null ||
|
||||
state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments!
|
||||
.isEmpty
|
||||
? const SizedBox()
|
||||
: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments !=
|
||||
null &&
|
||||
state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments!
|
||||
.length ==
|
||||
1
|
||||
?
|
||||
////Single Attachment view
|
||||
SingleAttachment(
|
||||
onpressed: () {
|
||||
confirmAlert(
|
||||
context,
|
||||
() {
|
||||
parent.read<LearningDevelopmentBloc>().add(DeleteLearningDevAttachment(
|
||||
attachment: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
moduleId: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.conductedTraining!
|
||||
.id!,
|
||||
profileId:
|
||||
profileId,
|
||||
token:
|
||||
token));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
},
|
||||
attachment: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
)
|
||||
////Multiple Attachments View
|
||||
: MultipleAttachments(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token,
|
||||
moduleId: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.conductedTraining!
|
||||
.title!
|
||||
.id!,
|
||||
educationBloc:
|
||||
null,
|
||||
eligibilityBloc:
|
||||
null,
|
||||
learningDevelopmentBloc:
|
||||
BlocProvider.of<
|
||||
LearningDevelopmentBloc>(
|
||||
context),
|
||||
workHistoryBloc:
|
||||
null,
|
||||
blocId: 4,
|
||||
eligibilityName: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.conductedTraining!
|
||||
.title!
|
||||
.title!,
|
||||
attachments: state
|
||||
.learningsAndDevelopment[
|
||||
index]
|
||||
.attachments!,
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import 'dart:io';
|
||||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/screens/profile/components/work_history/add_modal.dart';
|
||||
|
@ -17,11 +23,15 @@ import 'package:unit2/widgets/Leadings/add_leading.dart';
|
|||
import 'package:unit2/widgets/Leadings/close_leading.dart';
|
||||
import 'package:unit2/widgets/empty_data.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
import '../../../bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../model/profile/work_history.dart';
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../../../utils/global.dart';
|
||||
import '../shared/multiple_attachment.dart';
|
||||
import '../shared/single_attachment.dart';
|
||||
|
||||
class WorkHistoryScreen extends StatelessWidget {
|
||||
const WorkHistoryScreen({super.key});
|
||||
|
@ -29,8 +39,13 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
||||
|
||||
BuildContext parent = context;
|
||||
String? token;
|
||||
int profileId;
|
||||
int? profileId;
|
||||
List<PlatformFile>? results = [];
|
||||
AttachmentCategory? selectedAttachmentCategory;
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: context.watch<WorkHistoryBloc>().state is AddWorkHistoryState
|
||||
|
@ -95,7 +110,7 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
//DELETED STATE
|
||||
////DELETED STATE
|
||||
if (state is DeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
|
@ -136,6 +151,48 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
});
|
||||
}
|
||||
}
|
||||
if (state is WorkHistoryDevAttachmentAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<WorkHistoryBloc>()
|
||||
.add(LoadWorkHistories());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<WorkHistoryBloc>()
|
||||
.add(LoadWorkHistories());
|
||||
});
|
||||
}
|
||||
}
|
||||
////ATTACHMENT DELETED STATE
|
||||
if (state is WorkHistoryDevAttachmentDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Attachment has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<WorkHistoryBloc>()
|
||||
.add(LoadWorkHistories());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting Attachment", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<WorkHistoryBloc>()
|
||||
.add(LoadWorkHistories());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//// EDITED STATE
|
||||
if (state is WorkHistoryEditedState) {
|
||||
if (state.response['success']) {
|
||||
|
@ -160,6 +217,11 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
},
|
||||
builder: (context, state) {
|
||||
if (state is WorkHistoryLoaded) {
|
||||
for (var cat in state.attachmentCategory) {
|
||||
if (cat.subclass!.id == 4) {
|
||||
attachmentCategories.add(cat);
|
||||
}
|
||||
}
|
||||
if (state.workExperiences.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
@ -185,114 +247,467 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
width: screenWidth,
|
||||
decoration: box1(),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
child: Row(children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
position,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight.w600,
|
||||
color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
agency,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight.w500),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$from - $to ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium,
|
||||
),
|
||||
],
|
||||
)),
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete workhistory-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<
|
||||
WorkHistoryBloc>(
|
||||
context)
|
||||
.add(DeleteWorkHistory(
|
||||
profileId: profileId,
|
||||
token: token!,
|
||||
workHistory:
|
||||
state.workExperiences[
|
||||
child: Column(
|
||||
children: [
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
position,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w600,
|
||||
color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
agency,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.w500),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
"$from - $to ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium,
|
||||
),
|
||||
],
|
||||
)),
|
||||
AppPopupMenu<int>(
|
||||
offset:
|
||||
const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete workhistory-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<
|
||||
WorkHistoryBloc>(
|
||||
context)
|
||||
.add(
|
||||
DeleteWorkHistory(
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
workHistory: state
|
||||
.workExperiences[
|
||||
index],
|
||||
));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit eligibilty-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
WorkHistory workHistory =
|
||||
state.workExperiences[
|
||||
index];
|
||||
context
|
||||
.read<WorkHistoryBloc>()
|
||||
.add(
|
||||
ShowEditWorkHistoryForm(
|
||||
));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit eligibilty-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
WorkHistory workHistory =
|
||||
state.workExperiences[
|
||||
index];
|
||||
context
|
||||
.read<
|
||||
WorkHistoryBloc>()
|
||||
.add(ShowEditWorkHistoryForm(
|
||||
workHistory:
|
||||
workHistory));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 2,
|
||||
icon: Icons.attach_file),
|
||||
}
|
||||
////Attachment
|
||||
if (value == 3) {
|
||||
results.clear();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext
|
||||
context) {
|
||||
return AlertDialog(
|
||||
contentPadding:
|
||||
const EdgeInsets
|
||||
.all(0),
|
||||
backgroundColor:
|
||||
Colors.grey
|
||||
.shade100,
|
||||
icon: const Icon(
|
||||
Icons.file_copy,
|
||||
size: 32,
|
||||
color: primary,
|
||||
),
|
||||
title: const Text(
|
||||
"File Attachment:"),
|
||||
content: StatefulBuilder(
|
||||
builder: (context,
|
||||
setState) {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets
|
||||
.all(
|
||||
16.0),
|
||||
child: Column(
|
||||
mainAxisSize:
|
||||
MainAxisSize
|
||||
.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
const Divider(),
|
||||
Text(
|
||||
position,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(fontWeight: FontWeight.w600, color: primary),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
8,
|
||||
),
|
||||
Text(
|
||||
agency,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleSmall!
|
||||
.copyWith(fontWeight: FontWeight.w500),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
"$from - $to ",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelMedium,
|
||||
),
|
||||
const Divider(),
|
||||
FormBuilderDropdown(
|
||||
autovalidateMode: AutovalidateMode
|
||||
.always,
|
||||
decoration: normalTextFieldStyle(
|
||||
"attachment category", "attachment category"),
|
||||
name:
|
||||
'attachments_categorues',
|
||||
validator:
|
||||
FormBuilderValidators.required(errorText: "This field is required"),
|
||||
onChanged: (value) {
|
||||
selectedAttachmentCategory = value;
|
||||
},
|
||||
items: attachmentCategories.map((e) {
|
||||
return DropdownMenuItem(value: e, child: Text(e.description!));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height:
|
||||
8,
|
||||
),
|
||||
Text(
|
||||
"You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.black),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
5,
|
||||
),
|
||||
Text(
|
||||
"Acceptable Files: PDF, JPEG, PNG",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall,
|
||||
),
|
||||
Text(
|
||||
"Max File Size (per attachment): 1MB",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall,
|
||||
),
|
||||
const Divider(),
|
||||
ElevatedButton(
|
||||
style:
|
||||
ButtonStyle(
|
||||
elevation: MaterialStateProperty.all(0),
|
||||
backgroundColor: MaterialStateProperty.all<Color>(Colors.white),
|
||||
),
|
||||
onPressed:
|
||||
() async {
|
||||
FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
|
||||
'jpg',
|
||||
'png',
|
||||
'jpeg',
|
||||
'pdf'
|
||||
]);
|
||||
setState(() {
|
||||
if (newResult != null) {
|
||||
newResult.files.forEach((element) {
|
||||
results.add(element);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Select Files",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(color: Colors.black),
|
||||
))),
|
||||
const Divider(),
|
||||
SingleChildScrollView(
|
||||
child:
|
||||
SizedBox(
|
||||
height:
|
||||
100,
|
||||
width:
|
||||
double.maxFinite,
|
||||
child: results.isEmpty
|
||||
? const SizedBox()
|
||||
: Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: results.length,
|
||||
itemBuilder: (BuildContext context, index) {
|
||||
final kb = results[index].size / 1024;
|
||||
final mb = kb / 1024;
|
||||
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
child: results[index].extension!.toLowerCase() == 'pdf'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/pdf.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'png'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/png.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height: blockSizeVertical * 3,
|
||||
allowDrawingOutsideViewBox: true,
|
||||
)
|
||||
: const SizedBox())),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Flexible(
|
||||
flex: 6,
|
||||
child: Text(
|
||||
results[index].name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 6,
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
size,
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
|
||||
)),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
results.removeAt(index);
|
||||
});
|
||||
},
|
||||
))
|
||||
],
|
||||
)),
|
||||
const Divider()
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height:
|
||||
12,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
double.maxFinite,
|
||||
height:
|
||||
50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
List<String> paths = [];
|
||||
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
]),
|
||||
if (selectedAttachmentCategory != null && results.isNotEmpty) {
|
||||
for (var res in results) {
|
||||
paths.add(res.path!);
|
||||
}
|
||||
setState(() {
|
||||
results.clear();
|
||||
});
|
||||
Navigator.pop(context);
|
||||
parent.read<WorkHistoryBloc>().add(AddWorkHistoryAttachment(attachmentModule: state.workExperiences[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString()));
|
||||
}
|
||||
},
|
||||
child: const Text("Submit")),
|
||||
)
|
||||
]),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Update",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Remove",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attach",
|
||||
value: 3,
|
||||
icon:
|
||||
Icons.attach_file),
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
]),
|
||||
const Divider(),
|
||||
////Show Attachments
|
||||
SizedBox(
|
||||
child: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments ==
|
||||
null ||
|
||||
state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments!
|
||||
.isEmpty
|
||||
? const SizedBox()
|
||||
: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments !=
|
||||
null &&
|
||||
state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments!
|
||||
.length ==
|
||||
1
|
||||
?
|
||||
////Single Attachment view
|
||||
SingleAttachment(
|
||||
onpressed: () {
|
||||
confirmAlert(
|
||||
context,
|
||||
() {
|
||||
parent.read<WorkHistoryBloc>().add(DeleteWorkHistoryAttachment(
|
||||
attachment: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
moduleId: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.id!,
|
||||
profileId:
|
||||
profileId!,
|
||||
token:
|
||||
token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
},
|
||||
attachment: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments!
|
||||
.first,
|
||||
)
|
||||
////Multiple Attachments View
|
||||
: MultipleAttachments(
|
||||
profileId:
|
||||
profileId!,
|
||||
token: token!,
|
||||
moduleId: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.id!,
|
||||
educationBloc:
|
||||
null,
|
||||
workHistoryBloc:
|
||||
BlocProvider.of<WorkHistoryBloc>(context),
|
||||
eligibilityBloc:
|
||||
null,
|
||||
learningDevelopmentBloc:
|
||||
null,
|
||||
blocId: 3,
|
||||
eligibilityName: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.position!
|
||||
.title!,
|
||||
attachments: state
|
||||
.workExperiences[
|
||||
index]
|
||||
.attachments!,
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
|
@ -308,13 +723,13 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
}
|
||||
if (state is AddWorkHistoryState) {
|
||||
return AddWorkHistoryScreen(
|
||||
profileId: profileId,
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
);
|
||||
}
|
||||
if (state is EditWorkHistoryState) {
|
||||
return EditWorkHistoryScreen(
|
||||
profileId: profileId,
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
);
|
||||
}
|
||||
|
@ -324,7 +739,8 @@ class WorkHistoryScreen extends StatelessWidget {
|
|||
onpressed: () {
|
||||
context.read<WorkHistoryBloc>().add(
|
||||
GetWorkHistories(
|
||||
profileId: profileId, token: token!));
|
||||
profileId: profileId!,
|
||||
token: token!));
|
||||
});
|
||||
}
|
||||
return Container();
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:fluttericon/entypo_icons.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../theme-data.dart/box_shadow.dart';
|
||||
import '../../../theme-data.dart/colors.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../../../utils/global.dart';
|
||||
|
||||
class MultipleAttachments extends StatelessWidget {
|
||||
final List<Attachment> attachments;
|
||||
final String eligibilityName;
|
||||
final EducationBloc? educationBloc;
|
||||
final EligibilityBloc? eligibilityBloc;
|
||||
final LearningDevelopmentBloc? learningDevelopmentBloc;
|
||||
final WorkHistoryBloc? workHistoryBloc;
|
||||
final int blocId;
|
||||
final int moduleId;
|
||||
final int profileId;
|
||||
final String token;
|
||||
const MultipleAttachments(
|
||||
{super.key,
|
||||
required this.blocId,
|
||||
required this.educationBloc,
|
||||
required this.eligibilityBloc,
|
||||
required this.learningDevelopmentBloc,
|
||||
required this.workHistoryBloc,
|
||||
required this.attachments,
|
||||
required this.eligibilityName,
|
||||
required this.moduleId,
|
||||
required this.profileId,
|
||||
required this.token});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration:
|
||||
box1().copyWith(color: Colors.grey.shade300, boxShadow: []),
|
||||
child: AutoSizeText(
|
||||
|
||||
attachments.first.filename!,
|
||||
wrapWords: false,
|
||||
maxLines: 1,
|
||||
))),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
child: FittedBox(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(3),
|
||||
decoration:
|
||||
box1().copyWith(color: Colors.grey.shade300, boxShadow: []),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
"$eligibilityName Attachments",
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: attachments.map((e) {
|
||||
String ext = e.filename!
|
||||
.substring(e.filename!.lastIndexOf("."));
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
child: ext == '.pdf'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/pdf.svg',
|
||||
height: blockSizeVertical * 5,
|
||||
allowDrawingOutsideViewBox:
|
||||
true,
|
||||
)
|
||||
: ext == '.png'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/png.svg',
|
||||
height:
|
||||
blockSizeVertical *
|
||||
5.5,
|
||||
allowDrawingOutsideViewBox:
|
||||
true,
|
||||
)
|
||||
: ext == '.jpg'
|
||||
? SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height:
|
||||
blockSizeVertical *
|
||||
5,
|
||||
allowDrawingOutsideViewBox:
|
||||
true,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
'assets/svgs/jpg.svg',
|
||||
height:
|
||||
blockSizeVertical *
|
||||
5,
|
||||
allowDrawingOutsideViewBox:
|
||||
true,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
flex: 4,
|
||||
child: Tooltip(
|
||||
message: e.filename,
|
||||
child: Text(
|
||||
e.filename!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.delete,
|
||||
color: primary,
|
||||
),
|
||||
onPressed: () {
|
||||
confirmAlert(context, () {
|
||||
if (blocId == 1) {
|
||||
Navigator.pop(
|
||||
NavigationService
|
||||
.navigatorKey
|
||||
.currentContext!);
|
||||
educationBloc!.add(
|
||||
DeleteEducationAttachment(
|
||||
attachment: e,
|
||||
moduleId:
|
||||
moduleId,
|
||||
profileId:
|
||||
profileId,
|
||||
token: token));
|
||||
} else if (blocId == 2) {
|
||||
Navigator.pop(
|
||||
NavigationService
|
||||
.navigatorKey
|
||||
.currentContext!);
|
||||
eligibilityBloc!.add(
|
||||
DeleteEligibyAttachment(
|
||||
attachment: e,
|
||||
moduleId: moduleId
|
||||
.toString(),
|
||||
profileId: profileId
|
||||
.toString(),
|
||||
token: token));
|
||||
} else if (blocId == 3) {
|
||||
Navigator.pop(
|
||||
NavigationService
|
||||
.navigatorKey
|
||||
.currentContext!);
|
||||
workHistoryBloc!.add(
|
||||
DeleteWorkHistoryAttachment(
|
||||
attachment: e,
|
||||
moduleId:
|
||||
moduleId,
|
||||
profileId:
|
||||
profileId,
|
||||
token: token));
|
||||
} else {
|
||||
Navigator.pop(
|
||||
NavigationService
|
||||
.navigatorKey
|
||||
.currentContext!);
|
||||
learningDevelopmentBloc!.add(
|
||||
DeleteLearningDevAttachment(
|
||||
attachment: e,
|
||||
moduleId:
|
||||
moduleId,
|
||||
profileId:
|
||||
profileId,
|
||||
token: token));
|
||||
}
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider()
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
));
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: const [
|
||||
Text(" See more.."),
|
||||
Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../model/profile/attachment.dart';
|
||||
import '../../../theme-data.dart/box_shadow.dart';
|
||||
import '../../../theme-data.dart/colors.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
|
||||
class SingleAttachment extends StatelessWidget {
|
||||
final Function()? onpressed;
|
||||
final Attachment attachment;
|
||||
const SingleAttachment({
|
||||
required this.attachment,
|
||||
required this.onpressed,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
5),
|
||||
decoration: box1().copyWith(
|
||||
color: Colors
|
||||
.grey
|
||||
.shade300,
|
||||
boxShadow: []),
|
||||
child:
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
AutoSizeText(
|
||||
attachment.filename!,
|
||||
wrapWords: false,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width:
|
||||
8,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap:onpressed,
|
||||
child: const Icon(Icons.delete,color: primary,))
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/model/profile/attachment.dart';
|
||||
import 'package:unit2/model/profile/eligibility.dart';
|
||||
import 'package:unit2/utils/request.dart';
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
|
@ -9,32 +10,32 @@ class EligibilityService {
|
|||
static final EligibilityService _instance = EligibilityService();
|
||||
static EligibilityService get instance => _instance;
|
||||
|
||||
|
||||
Future<List<EligibityCert>> getEligibilities(int profileId, String token)async{
|
||||
List<EligibityCert> eligibilities = [];
|
||||
Future<List<EligibityCert>> getEligibilities(
|
||||
int profileId, String token) async {
|
||||
List<EligibityCert> eligibilities = [];
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getEligibilities()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
String path = "${Url.instance.getEligibilities()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
|
||||
};
|
||||
|
||||
try{
|
||||
http.Response response = await Request.instance.getRequest(path: path,headers: headers,param: {});
|
||||
if(response.statusCode == 200){
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data']!= null) {
|
||||
data['data'].forEach((var cert) {
|
||||
EligibityCert eligibility = EligibityCert.fromJson(cert);
|
||||
eligibilities.add(eligibility);
|
||||
});
|
||||
}
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(path: path, headers: headers, param: {});
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((var cert) {
|
||||
EligibityCert eligibility = EligibityCert.fromJson(cert);
|
||||
eligibilities.add(eligibility);
|
||||
});
|
||||
}
|
||||
}catch(e){
|
||||
throw e.toString();
|
||||
}
|
||||
return eligibilities;
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return eligibilities;
|
||||
}
|
||||
|
||||
Future<bool> delete(
|
||||
|
@ -50,18 +51,17 @@ class EligibilityService {
|
|||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authtoken
|
||||
};
|
||||
try{
|
||||
http.Response response = await Request.instance
|
||||
.deleteRequest(path: path, headers: headers, body: body, param: params);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
success = data['success'];
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
}catch(e){
|
||||
throw(e.toString());
|
||||
try {
|
||||
http.Response response = await Request.instance.deleteRequest(
|
||||
path: path, headers: headers, body: body, param: params);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
success = data['success'];
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
return success!;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class EligibilityService {
|
|||
{required EligibityCert eligibityCert,
|
||||
required String token,
|
||||
required int profileId}) async {
|
||||
Map<dynamic, dynamic>? _response={};
|
||||
Map<dynamic, dynamic>? _response = {};
|
||||
String authtoken = "Token $token";
|
||||
String path = '${Url.instance.addEligibility()}$profileId/';
|
||||
Map<String, String> headers = {
|
||||
|
@ -94,7 +94,7 @@ class EligibilityService {
|
|||
Map data = jsonDecode(response.body);
|
||||
_response = data;
|
||||
} else {
|
||||
_response.addAll({'success':false});
|
||||
_response.addAll({'success': false});
|
||||
}
|
||||
|
||||
return _response;
|
||||
|
@ -103,11 +103,12 @@ class EligibilityService {
|
|||
}
|
||||
}
|
||||
|
||||
Future<Map<dynamic, dynamic>> update(
|
||||
Future<Map<dynamic, dynamic>> update(
|
||||
{required EligibityCert eligibityCert,
|
||||
required String token,
|
||||
required int profileId, required int oldEligibility}) async {
|
||||
Map<dynamic, dynamic>? response={};
|
||||
required int profileId,
|
||||
required int oldEligibility}) async {
|
||||
Map<dynamic, dynamic>? response = {};
|
||||
String authtoken = "Token $token";
|
||||
String path = '${Url.instance.addEligibility()}$profileId/';
|
||||
Map<String, String> headers = {
|
||||
|
@ -132,7 +133,7 @@ class EligibilityService {
|
|||
Map data = jsonDecode(res.body);
|
||||
response = data;
|
||||
} else {
|
||||
response.addAll({'success':false});
|
||||
response.addAll({'success': false});
|
||||
}
|
||||
|
||||
return response;
|
||||
|
@ -140,4 +141,63 @@ class EligibilityService {
|
|||
throw e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<bool> deleteAttachment(
|
||||
{required Attachment attachment,
|
||||
required int moduleId,
|
||||
required String profileId,
|
||||
required String token}) async {
|
||||
bool? success;
|
||||
String authtoken = "Token $token";
|
||||
String path = "${Url.instance.attachments()}$profileId/";
|
||||
Map? body;
|
||||
try{
|
||||
body = {
|
||||
"attachment_module": moduleId,
|
||||
attachment: [
|
||||
{
|
||||
"id": attachment.id,
|
||||
"created_at": attachment.createdAt,
|
||||
"source": attachment.source,
|
||||
"filename": attachment.filename,
|
||||
"category": {
|
||||
"id": attachment.category?.id,
|
||||
"subclass": {
|
||||
"id": attachment.category?.subclass?.id,
|
||||
"name": attachment.category?.subclass?.name,
|
||||
"attachment_class": {
|
||||
"id": attachment.category?.subclass?.attachmentClass?.id,
|
||||
"name": attachment.category?.subclass?.attachmentClass?.name
|
||||
}
|
||||
},
|
||||
"description": attachment.category?.description
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}catch(e){
|
||||
print("body error"+e.toString());
|
||||
}
|
||||
|
||||
Map<String, dynamic> params = {"force_mode": "true"};
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authtoken
|
||||
};
|
||||
// try {
|
||||
http.Response response = await Request.instance
|
||||
.deleteRequest(path: path, headers: headers, body: body, param: params);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
success = data['success'];
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
// } catch (e) {
|
||||
// throw (e.toString());
|
||||
// }
|
||||
return success!;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/utils/request.dart';
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
|
||||
import '../model/profile/attachment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class AttachmentServices {
|
||||
static final AttachmentServices _instance = AttachmentServices();
|
||||
static AttachmentServices get instance => _instance;
|
||||
|
||||
Future<List<AttachmentCategory>> getCategories() async {
|
||||
List<AttachmentCategory> attachmentCategories = [];
|
||||
String path = Url.instance.attachmentCategories();
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
for (var cat in data['data']) {
|
||||
AttachmentCategory newCat = AttachmentCategory.fromJson(cat);
|
||||
attachmentCategories.add(newCat);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return attachmentCategories;
|
||||
}
|
||||
|
||||
Future<Map<dynamic, dynamic>> attachment(
|
||||
{required String categoryId,
|
||||
required String module,
|
||||
required List<String> paths,
|
||||
required String token,
|
||||
required String profileId}) async {
|
||||
String authtoken = "Token $token";
|
||||
Map<String, String> headers = {'Authorization': authtoken};
|
||||
String path = Url.instance.attachments();
|
||||
Map<dynamic, dynamic>? response = {};
|
||||
Map<String, String> body = {
|
||||
"attachment_category_id": categoryId.toString(),
|
||||
"attachment_module": module.toString()
|
||||
};
|
||||
|
||||
try {
|
||||
var request = http.MultipartRequest(
|
||||
'POST', Uri.parse('https://${Url.instance.host()}$path$profileId/'));
|
||||
request.fields.addAll(body);
|
||||
request.headers.addAll(headers);
|
||||
paths.forEach((element) async {
|
||||
request.files
|
||||
.add(await http.MultipartFile.fromPath('attachments', element));
|
||||
});
|
||||
|
||||
http.StreamedResponse res = await request.send();
|
||||
final steamResponse = await res.stream.bytesToString();
|
||||
Map data = jsonDecode(steamResponse);
|
||||
if (res.statusCode == 201) {
|
||||
response = data;
|
||||
} else {
|
||||
String message = data['response']['details'];
|
||||
response.addAll({'message': message});
|
||||
response.addAll(
|
||||
{'success': false},
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<bool> deleteAttachment(
|
||||
{required Attachment attachment,
|
||||
required int moduleId,
|
||||
required String profileId,
|
||||
required String token}) async {
|
||||
bool? success;
|
||||
String authtoken = "Token $token";
|
||||
String path = "${Url.instance.attachments()}$profileId/";
|
||||
Map? body;
|
||||
body = {
|
||||
"attachment_module": moduleId,
|
||||
"attachments": [
|
||||
{
|
||||
"id": attachment.id,
|
||||
"created_at": attachment.createdAt?.toString(),
|
||||
"source": attachment.source,
|
||||
"filename": attachment.filename,
|
||||
"category": {
|
||||
"id": attachment.category?.id,
|
||||
"subclass": {
|
||||
"id": attachment.category?.subclass?.id,
|
||||
"name": attachment.category?.subclass?.name,
|
||||
"attachment_class": {
|
||||
"id": attachment.category?.subclass?.attachmentClass?.id,
|
||||
"name": attachment.category?.subclass?.attachmentClass?.name
|
||||
}
|
||||
},
|
||||
"description": attachment.category?.description
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Map<String, dynamic> params = {"force_mode": "true"};
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authtoken
|
||||
};
|
||||
// try {
|
||||
http.Response response = await Request.instance.deleteRequest(
|
||||
path: path, headers: headers, body: body, param: params);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
success = data['success'];
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
// } catch (e) {
|
||||
// throw (e.toString());
|
||||
// }
|
||||
return success!;
|
||||
}
|
||||
}
|
|
@ -6,9 +6,9 @@ class Url {
|
|||
String host() {
|
||||
// return '192.168.10.183:3000';
|
||||
// return 'agusandelnorte.gov.ph';
|
||||
// return "192.168.10.219:3000";
|
||||
// return "192.168.10.241";
|
||||
return "192.168.10.221:3004";
|
||||
return "192.168.10.219:3000";
|
||||
// // return "192.168.10.241";
|
||||
// return "192.168.10.221:3004";
|
||||
// return "playweb.agusandelnorte.gov.ph";
|
||||
// return 'devapi.agusandelnorte.gov.ph:3004';
|
||||
}
|
||||
|
@ -167,6 +167,9 @@ class Url {
|
|||
String getServiceTypes() {
|
||||
return "/api/jobnet_app/comm_service_type/";
|
||||
}
|
||||
String attachments(){
|
||||
return "/api/jobnet_app/profile/attachment/";
|
||||
}
|
||||
|
||||
//// address path
|
||||
String addressPath() {
|
||||
|
@ -319,4 +322,7 @@ class Url {
|
|||
String getAddressCategory() {
|
||||
return "/api/jobnet_app/address_categories/";
|
||||
}
|
||||
String attachmentCategories(){
|
||||
return "/api/jobnet_app/attachment_categories/";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,6 +449,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "9d6e95ec73abbd31ec54d0e0df8a961017e165aba1395e462e5b31ea0c165daf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.3.1"
|
||||
file_utils:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -86,6 +86,7 @@ dependencies:
|
|||
flutter_staggered_animations: ^1.1.1
|
||||
group_list_view: ^1.1.1
|
||||
search_page: ^2.3.0
|
||||
file_picker: ^5.3.1
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Reference in New Issue