Adding attachments feature for profile

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
PGAN-MIS 2023-08-07 14:33:38 +08:00
parent c32ed51198
commit 018f3760a5
28 changed files with 1741 additions and 963 deletions

View File

@ -4,7 +4,7 @@ import 'package:unit2/model/profile/educational_background.dart';
import 'package:unit2/sevices/profile/education_services.dart'; import 'package:unit2/sevices/profile/education_services.dart';
import '../../../model/profile/attachment.dart'; import '../../../model/profile/attachment.dart';
import '../../../utils/attachment_categories.dart'; import '../../../utils/attachment_services.dart';
part 'education_event.dart'; part 'education_event.dart';
part 'education_state.dart'; part 'education_state.dart';
@ -14,12 +14,12 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
List<School> schools = []; List<School> schools = [];
List<Course> programs = []; List<Course> programs = [];
List<Honor> honors = []; List<Honor> honors = [];
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
EducationBloc() : super(EducationInitial()) { EducationBloc() : super(EducationInitial()) {
on<GetEducationalBackground>((event, emit) async { on<GetEducationalBackground>((event, emit) async {
emit(EducationalBackgroundLoadingState()); emit(EducationalBackgroundLoadingState());
try { try {
if (attachmentCategories.isEmpty) { if (attachmentCategories.isEmpty) {
attachmentCategories = attachmentCategories =
await AttachmentServices.instance.getCategories(); await AttachmentServices.instance.getCategories();
} }
@ -28,11 +28,13 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
.instace .instace
.getEducationalBackground(event.profileId, event.token); .getEducationalBackground(event.profileId, event.token);
educationalBackgrounds = educations; educationalBackgrounds = educations;
emit(EducationalBackgroundLoadedState( emit(EducationalBackgroundLoadedState(
educationalBackground: educationalBackgrounds, attachmentCategory: attachmentCategories)); educationalBackground: educationalBackgrounds,
attachmentCategory: attachmentCategories));
} else { } else {
emit(EducationalBackgroundLoadedState( emit(EducationalBackgroundLoadedState(
educationalBackground: educationalBackgrounds,attachmentCategory: attachmentCategories)); educationalBackground: educationalBackgrounds,
attachmentCategory: attachmentCategories));
} }
} catch (e) { } catch (e) {
emit(EducationalBackgroundErrorState(message: e.toString())); emit(EducationalBackgroundErrorState(message: e.toString()));
@ -85,7 +87,8 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
token: event.token, token: event.token,
profileId: event.profileId); profileId: event.profileId);
if (status['success']) { if (status['success']) {
educationalBackgrounds.removeWhere((element) => event.educationalBackground.id == element.id); educationalBackgrounds.removeWhere(
(element) => event.educationalBackground.id == element.id);
EducationalBackground educationalBackground = EducationalBackground educationalBackground =
EducationalBackground.fromJson(status['data']); EducationalBackground.fromJson(status['data']);
educationalBackgrounds.add(educationalBackground); educationalBackgrounds.add(educationalBackground);
@ -97,7 +100,8 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
////LOAD ////LOAD
on<LoadEducations>((event, emit) { on<LoadEducations>((event, emit) {
emit(EducationalBackgroundLoadedState( emit(EducationalBackgroundLoadedState(
educationalBackground: educationalBackgrounds,attachmentCategory: attachmentCategories)); educationalBackground: educationalBackgrounds,
attachmentCategory: attachmentCategories));
}); });
//// SHOW EDIT FORM //// SHOW EDIT FORM
on<ShowEditEducationForm>((event, emit) async { on<ShowEditEducationForm>((event, emit) async {
@ -143,8 +147,12 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
} }
}); });
////Add attachment ////Add attachment
on<AddAttachment>((event, emit) async { on<AddEducationAttachment>((event, emit) async {
emit(EducationalBackgroundLoadingState()); emit(EducationalBackgroundLoadingState());
EducationalBackground educationalBackground =
educationalBackgrounds.firstWhere(
(element) => element.id.toString() == event.attachmentModule);
List<Attachment> attachments = [];
try { try {
Map<dynamic, dynamic> status = await AttachmentServices.instance Map<dynamic, dynamic> status = await AttachmentServices.instance
.attachment( .attachment(
@ -153,7 +161,18 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
paths: event.filePaths, paths: event.filePaths,
token: event.token, token: event.token,
profileId: event.profileId); profileId: event.profileId);
if (status['success']) { 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)); emit(EducationAddedState(response: status));
} else { } else {
emit(EducationAddedState(response: status)); emit(EducationAddedState(response: status));
@ -162,5 +181,30 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
emit(EducationalBackgroundErrorState(message: e.toString())); 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()));
}
});
} }
} }

View File

@ -64,13 +64,22 @@ class DeleteEducation extends EducationEvent{
List<Object> get props => [educationalBackground, profileId, token]; List<Object> get props => [educationalBackground, profileId, token];
} }
////Add attachment ////Add attachment
class AddAttachment extends EducationEvent{ class AddEducationAttachment extends EducationEvent{
final String categoryId; final String categoryId;
final String attachmentModule; final String attachmentModule;
final List<String> filePaths; final List<String> filePaths;
final String token; final String token;
final String profileId; final String profileId;
const AddAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token}); const AddEducationAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
@override @override
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId]; 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});
}

View File

@ -10,9 +10,10 @@ abstract class EducationState extends Equatable {
class EducationInitial extends EducationState {} class EducationInitial extends EducationState {}
class EducationalBackgroundLoadedState extends EducationState { class EducationalBackgroundLoadedState extends EducationState {
final List< AttachmentCategory> attachmentCategory; final List<AttachmentCategory> attachmentCategory;
final List<EducationalBackground> educationalBackground; final List<EducationalBackground> educationalBackground;
const EducationalBackgroundLoadedState({required this.educationalBackground, required this.attachmentCategory}); const EducationalBackgroundLoadedState(
{required this.educationalBackground, required this.attachmentCategory});
@override @override
List<Object> get props => [educationalBackground]; List<Object> get props => [educationalBackground];
} }
@ -58,6 +59,8 @@ class EducationAddedState extends EducationState {
@override @override
List<Object> get props => [response]; List<Object> get props => [response];
} }
//// Edited State //// Edited State
class EditedEducationState extends EducationState { class EditedEducationState extends EducationState {
final Map<dynamic, dynamic> response; final Map<dynamic, dynamic> response;
@ -73,3 +76,17 @@ class EducationDeletedState extends EducationState {
@override @override
List<Object> get props => [success]; 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];
}

View File

@ -1,6 +1,6 @@
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:unit2/utils/attachment_categories.dart'; import 'package:unit2/utils/attachment_services.dart';
import '../../../model/location/city.dart'; import '../../../model/location/city.dart';
import '../../../model/location/country.dart'; import '../../../model/location/country.dart';
import '../../../model/location/provinces.dart'; import '../../../model/location/provinces.dart';
@ -39,11 +39,11 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
if (success) { if (success) {
eligibilities.removeWhere( eligibilities.removeWhere(
((EligibityCert element) => element.id == event.eligibilityId)); ((EligibityCert element) => element.id == event.eligibilityId));
emit(DeletedState( emit(EligibilityDeletedState(
success: success, success: success,
)); ));
} else { } else {
emit(DeletedState(success: success)); emit(EligibilityDeletedState(success: success));
} }
} catch (e) { } catch (e) {
emit(EligibilityErrorState(message: e.toString())); emit(EligibilityErrorState(message: e.toString()));
@ -222,8 +222,11 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
message: "Something went wrong. Please try again")); message: "Something went wrong. Please try again"));
}); });
////Add attachment ////Add attachment
on<AddAttachment>((event, emit) async { on<AddEligibiltyAttachment>((event, emit) async {
emit(EligibilityLoadingState()); emit(EligibilityLoadingState());
List<Attachment> attachments = [];
EligibityCert eligibityCert = eligibilities.firstWhere(
(element) => element.id.toString() == event.attachmentModule);
try { try {
Map<dynamic, dynamic> status = await AttachmentServices.instance Map<dynamic, dynamic> status = await AttachmentServices.instance
.attachment( .attachment(
@ -233,32 +236,44 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
token: event.token, token: event.token,
profileId: event.profileId); profileId: event.profileId);
if (status['success']) { if (status['success']) {
emit(EligibilityAddedState(response: status)); 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 { } else {
emit(EligibilityAddedState(response: status)); emit(EligibilityAttachmentAddedState(response: status));
} }
} catch (e) { } catch (e) {
emit(EligibilityErrorState(message: e.toString())); emit(EligibilityErrorState(message: e.toString()));
} }
}); });
on<DeleteAttachment>((event, emit) async { on<DeleteEligibyAttachment>((event, emit) async {
emit(EligibilityLoadingState());
// try { // try {
final bool success = await EligibilityService.instance.deleteAttachment( final bool success = await AttachmentServices.instance.deleteAttachment(
moduleId: int.parse(event.moduleId),
attachment: event.attachment, attachment: event.attachment,
profileId: event.profileId, moduleId: int.parse(event.moduleId),
profileId: event.profileId.toString(),
token: event.token); token: event.token);
if (success) { if (success) {
EligibityCert eligibityCert = eligibilities.firstWhere((element) =>element.id.toString() == event.moduleId); final EligibityCert eligibityCert = eligibilities
eligibityCert.attachments!.removeWhere((element){ .firstWhere((element) => element.id.toString() == event.moduleId);
return event.attachment.id == element.id; eligibityCert.attachments
}); ?.removeWhere((element) => element.id == event.attachment.id);
emit(DeletedState( eligibilities.removeWhere(
success: success, (element) => element.id.toString() == event.moduleId);
)); eligibilities.add(eligibityCert);
emit(EligibilitytAttachmentDeletedState(success: success));
} else { } else {
emit(DeletedState(success: success)); emit(EligibilitytAttachmentDeletedState(success: success));
} }
// } catch (e) { // } catch (e) {
// emit(EligibilityErrorState(message: e.toString())); // emit(EligibilityErrorState(message: e.toString()));

View File

@ -68,24 +68,25 @@ class DeleteEligibility extends EligibilityEvent {
class CallErrorState extends EligibilityEvent{ class CallErrorState extends EligibilityEvent{
} }
////Add Attachment
class AddAttachment extends EligibilityEvent{ class AddEligibiltyAttachment extends EligibilityEvent{
final String categoryId; final String categoryId;
final String attachmentModule; final String attachmentModule;
final List<String> filePaths; final List<String> filePaths;
final String token; final String token;
final String profileId; final String profileId;
const AddAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token}); const AddEligibiltyAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
@override @override
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId]; List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId];
} }
class DeleteAttachment extends EligibilityEvent{ ////Delete Attachment
class DeleteEligibyAttachment extends EligibilityEvent{
final String profileId; final String profileId;
final String token; final String token;
final Attachment attachment; final Attachment attachment;
final String moduleId; final String moduleId;
const DeleteAttachment({required this.attachment,required this.moduleId, required this.profileId, required this.token}); const DeleteEligibyAttachment({required this.attachment,required this.moduleId, required this.profileId, required this.token});
} }

View File

@ -42,9 +42,9 @@ class EditEligibilityState extends EligibilityState {
[isOverseas, eligibityCert, eligibilities, regions, countries]; [isOverseas, eligibityCert, eligibilities, regions, countries];
} }
class DeletedState extends EligibilityState { class EligibilityDeletedState extends EligibilityState {
final bool success; final bool success;
const DeletedState({required this.success}); const EligibilityDeletedState({required this.success});
@override @override
List<Object> get props => [success]; List<Object> get props => [success];
} }
@ -93,3 +93,17 @@ class EligibilityLoaded extends EligibilityState {
@override @override
List<Object> get props => [eligibilities]; 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];
}

View File

@ -10,7 +10,7 @@ import '../../../model/profile/attachment.dart';
import '../../../model/profile/learning_development.dart'; import '../../../model/profile/learning_development.dart';
import '../../../model/utils/agency.dart'; import '../../../model/utils/agency.dart';
import '../../../model/utils/category.dart'; import '../../../model/utils/category.dart';
import '../../../utils/attachment_categories.dart'; import '../../../utils/attachment_services.dart';
import '../../../utils/location_utilities.dart'; import '../../../utils/location_utilities.dart';
import '../../../utils/profile_utilities.dart'; import '../../../utils/profile_utilities.dart';
part 'learning_development_event.dart'; part 'learning_development_event.dart';
@ -273,8 +273,10 @@ class LearningDevelopmentBloc
emit(LearningDevelopmentErrorState(message: event.message)); emit(LearningDevelopmentErrorState(message: event.message));
}); });
////Add attachment ////Add attachment
on<AddAttachment>((event, emit) async { on<AddALearningDevttachment>((event, emit) async {
emit(LearningDevelopmentLoadingState()); emit(LearningDevelopmentLoadingState());
List<Attachment> attachments = [];
LearningDevelopement learningDevelopement = learningsAndDevelopments.firstWhere((element) => element.conductedTraining!.id.toString () == event.attachmentModule);
try { try {
Map<dynamic, dynamic> status = await AttachmentServices.instance Map<dynamic, dynamic> status = await AttachmentServices.instance
.attachment( .attachment(
@ -284,6 +286,11 @@ class LearningDevelopmentBloc
token: event.token, token: event.token,
profileId: event.profileId); profileId: event.profileId);
if (status['success']) { 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)); emit(LearningDevelopmentAddedState(response: status));
} else { } else {
emit(LearningDevelopmentAddedState(response: status)); emit(LearningDevelopmentAddedState(response: status));
@ -292,5 +299,31 @@ class LearningDevelopmentBloc
emit(LearningDevelopmentErrorState(message: e.toString())); 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()));
}
});
} }
} }

View File

@ -67,13 +67,24 @@ class CallErrorState extends LearningDevelopmentEvent{
const CallErrorState({required this.message}); const CallErrorState({required this.message});
} }
class AddAttachment extends LearningDevelopmentEvent{ ////Add Attachment
class AddALearningDevttachment extends LearningDevelopmentEvent{
final String categoryId; final String categoryId;
final String attachmentModule; final String attachmentModule;
final List<String> filePaths; final List<String> filePaths;
final String token; final String token;
final String profileId; final String profileId;
const AddAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token}); const AddALearningDevttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
@override @override
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId]; 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});
}

View File

@ -10,9 +10,11 @@ abstract class LearningDevelopmentState extends Equatable {
class LearningDevelopmentInitial extends LearningDevelopmentState {} class LearningDevelopmentInitial extends LearningDevelopmentState {}
class LearningDevelopmentLoadedState extends LearningDevelopmentState { class LearningDevelopmentLoadedState extends LearningDevelopmentState {
final List< AttachmentCategory> attachmentCategory; final List<AttachmentCategory> attachmentCategory;
final List<LearningDevelopement> learningsAndDevelopment; final List<LearningDevelopement> learningsAndDevelopment;
const LearningDevelopmentLoadedState({required this.learningsAndDevelopment, required this.attachmentCategory}); const LearningDevelopmentLoadedState(
{required this.learningsAndDevelopment,
required this.attachmentCategory});
@override @override
List<Object> get props => [learningsAndDevelopment]; List<Object> get props => [learningsAndDevelopment];
} }
@ -113,3 +115,21 @@ class LearningDevelopmentErrorState extends LearningDevelopmentState {
final String message; final String message;
const LearningDevelopmentErrorState({required this.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];
}

View File

@ -60,6 +60,7 @@ class EditVoluntaryWorks extends VoluntaryWorkState{
} }
////Adding State ////Adding State
class AddVoluntaryWorkState extends VoluntaryWorkState{ class AddVoluntaryWorkState extends VoluntaryWorkState{
final List<Position> positions; final List<Position> positions;
@ -71,6 +72,11 @@ class AddVoluntaryWorkState extends VoluntaryWorkState{
@override @override
List<Object> get props => [positions,agencies,countries,regions]; 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 //// Deleted State
class VoluntaryWorkDeletedState extends VoluntaryWorkState{ class VoluntaryWorkDeletedState extends VoluntaryWorkState{
final bool success; final bool success;

View File

@ -10,7 +10,7 @@ import 'package:unit2/utils/profile_utilities.dart';
import '../../../model/profile/attachment.dart'; import '../../../model/profile/attachment.dart';
import '../../../model/utils/category.dart'; import '../../../model/utils/category.dart';
import '../../../utils/attachment_categories.dart'; import '../../../utils/attachment_services.dart';
part 'workHistory_event.dart'; part 'workHistory_event.dart';
part 'workHistory_state.dart'; part 'workHistory_state.dart';
@ -21,13 +21,13 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
List<Agency> agencies = []; List<Agency> agencies = [];
List<AppoinemtStatus> appointmentStatus = []; List<AppoinemtStatus> appointmentStatus = [];
List<Category> agencyCategory = []; List<Category> agencyCategory = [];
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
WorkHistoryBloc() : super(EducationInitial()) { WorkHistoryBloc() : super(EducationInitial()) {
////GET WORK HISTORIES ////GET WORK HISTORIES
on<GetWorkHistories>((event, emit) async { on<GetWorkHistories>((event, emit) async {
emit(WorkHistoryLoadingState()); emit(WorkHistoryLoadingState());
try { try {
if (attachmentCategories.isEmpty) { if (attachmentCategories.isEmpty) {
attachmentCategories = attachmentCategories =
await AttachmentServices.instance.getCategories(); await AttachmentServices.instance.getCategories();
} }
@ -36,7 +36,9 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
.getWorkExperiences(event.profileId, event.token); .getWorkExperiences(event.profileId, event.token);
workExperiences = works; workExperiences = works;
} }
emit(WorkHistoryLoaded(workExperiences: workExperiences, attachmentCategory: attachmentCategories)); emit(WorkHistoryLoaded(
workExperiences: workExperiences,
attachmentCategory: attachmentCategories));
} catch (e) { } catch (e) {
emit(WorkHistoryErrorState(message: e.toString())); emit(WorkHistoryErrorState(message: e.toString()));
} }
@ -44,7 +46,9 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
///// LOAD WORK HISTORIES ///// LOAD WORK HISTORIES
on<LoadWorkHistories>((event, emit) { on<LoadWorkHistories>((event, emit) {
emit(WorkHistoryLoadingState()); emit(WorkHistoryLoadingState());
emit(WorkHistoryLoaded(workExperiences: workExperiences,attachmentCategory: attachmentCategories)); emit(WorkHistoryLoaded(
workExperiences: workExperiences,
attachmentCategory: attachmentCategories));
}); });
////DELETE ////DELETE
on<DeleteWorkHistory>((event, emit) async { on<DeleteWorkHistory>((event, emit) async {
@ -190,8 +194,11 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
} }
}); });
////Add Attachment ////Add Attachment
on<AddAttachment>((event, emit) async { on<AddWorkHistoryAttachment>((event, emit) async {
emit(WorkHistoryLoadingState()); emit(WorkHistoryLoadingState());
List<Attachment> attachments = [];
WorkHistory workHistory = workExperiences.firstWhere(
(element) => element.id.toString() == event.attachmentModule);
try { try {
Map<dynamic, dynamic> status = await AttachmentServices.instance Map<dynamic, dynamic> status = await AttachmentServices.instance
.attachment( .attachment(
@ -201,9 +208,45 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
token: event.token, token: event.token,
profileId: event.profileId); profileId: event.profileId);
if (status['success']) { if (status['success']) {
emit(WorkHistoryAddedState(response: status)); 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 { } else {
emit(WorkHistoryAddedState(response: status)); 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) { } catch (e) {
emit(WorkHistoryErrorState(message: e.toString())); emit(WorkHistoryErrorState(message: e.toString()));

View File

@ -60,15 +60,27 @@ class AddWorkHostory extends WorkHistorytEvent{
@override @override
List<Object> get props => [workHistory,profileId,token,isPrivate]; List<Object> get props => [workHistory,profileId,token,isPrivate];
} }
class AddAttachment extends WorkHistorytEvent{
////Add Attachment
class AddWorkHistoryAttachment extends WorkHistorytEvent{
final String categoryId; final String categoryId;
final String attachmentModule; final String attachmentModule;
final List<String> filePaths; final List<String> filePaths;
final String token; final String token;
final String profileId; final String profileId;
const AddAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token}); const AddWorkHistoryAttachment({required this.attachmentModule, required this.filePaths, required this.categoryId, required this.profileId, required this.token});
@override @override
List<Object> get props => [categoryId,attachmentModule,filePaths, token,profileId]; 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});
}

View File

@ -73,3 +73,22 @@ class WorkHistoryAddedState extends WorkHistoryState{
@override @override
List<Object> get props => [response]; 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];
}

View File

@ -1,24 +1,14 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:device_preview/device_preview.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_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/app_router.dart';
import 'package:unit2/utils/global_context.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 'package:path_provider/path_provider.dart' as path_provider;
import './utils/router.dart';
import './utils/global.dart'; import './utils/global.dart';
Future main() async { Future main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
var appDirectory = await path_provider.getApplicationDocumentsDirectory(); var appDirectory = await path_provider.getApplicationDocumentsDirectory();
@ -92,4 +82,3 @@ class MyApp extends StatelessWidget {
); );
} }
} }

View File

@ -1,8 +1,4 @@
// To parse this JSON data, do
//
// final attachment = attachmentFromJson(jsonString);
import 'package:meta/meta.dart';
import 'dart:convert'; import 'dart:convert';
Attachment attachmentFromJson(String str) => Attachment attachmentFromJson(String str) =>
@ -53,9 +49,9 @@ class Attachment {
} }
class AttachmentCategory { class AttachmentCategory {
final int id; final int? id;
final Subclass subclass; final Subclass? subclass;
final String description; final String? description;
AttachmentCategory({ AttachmentCategory({
required this.id, required this.id,
@ -65,21 +61,21 @@ class AttachmentCategory {
factory AttachmentCategory.fromJson(Map<String, dynamic> json) => AttachmentCategory( factory AttachmentCategory.fromJson(Map<String, dynamic> json) => AttachmentCategory(
id: json["id"], id: json["id"],
subclass: Subclass.fromJson(json["subclass"]), subclass:json['subclass'] == null? null: Subclass.fromJson(json["subclass"]),
description: json["description"], description: json["description"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"subclass": subclass.toJson(), "subclass": subclass?.toJson(),
"description": description, "description": description,
}; };
} }
class Subclass { class Subclass {
final int id; final int? id;
final String name; final String? name;
final AttachmentClass attachmentClass; final AttachmentClass? attachmentClass;
Subclass({ Subclass({
required this.id, required this.id,
@ -90,19 +86,19 @@ class Subclass {
factory Subclass.fromJson(Map<String, dynamic> json) => Subclass( factory Subclass.fromJson(Map<String, dynamic> json) => Subclass(
id: json["id"], id: json["id"],
name: json["name"], name: json["name"],
attachmentClass: AttachmentClass.fromJson(json["attachment_class"]), attachmentClass: json['attachment_class'] == null? null: AttachmentClass.fromJson(json["attachment_class"]),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"name": name, "name": name,
"attachment_class": attachmentClass.toJson(), "attachment_class": attachmentClass?.toJson(),
}; };
} }
class AttachmentClass { class AttachmentClass {
final int id; final int? id;
final String name; final String? name;
AttachmentClass({ AttachmentClass({
required this.id, required this.id,

View File

@ -26,7 +26,7 @@ class EducationalBackground {
final List<Honor>? honors; final List<Honor>? honors;
final Education? education; final Education? education;
final String? periodTo; final String? periodTo;
final List<Attachment>? attachments; List<Attachment>? attachments;
final String? periodFrom; final String? periodFrom;
final int? unitsEarned; final int? unitsEarned;
final String? yearGraduated; final String? yearGraduated;

View File

@ -34,7 +34,7 @@ class EligibityCert {
final int? id; final int? id;
final double? rating; final double? rating;
final DateTime? examDate; final DateTime? examDate;
final List<Attachment>? attachments; List<Attachment>? attachments;
final Eligibility? eligibility; final Eligibility? eligibility;
final ExamAddress? examAddress; final ExamAddress? examAddress;

View File

@ -24,7 +24,7 @@ class LearningDevelopement {
this.totalHoursAttended, this.totalHoursAttended,
}); });
final List<Attachment>? attachments; List<Attachment>? attachments;
final Agency? sponsoredBy; final Agency? sponsoredBy;
final ConductedTraining? conductedTraining; final ConductedTraining? conductedTraining;
final double? totalHoursAttended; final double? totalHoursAttended;

View File

@ -34,7 +34,7 @@ class WorkHistory {
final DateTime? toDate; final DateTime? toDate;
final Position? position; final Position? position;
final DateTime? fromDate; final DateTime? fromDate;
final List<Attachment>? attachments; List<Attachment>? attachments;
final int? salaryGrade; final int? salaryGrade;
final double? monthlySalary; final double? monthlySalary;
final String? appointmentStatus; final String? appointmentStatus;

View File

@ -7,7 +7,10 @@ import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:form_builder_validators/form_builder_validators.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/profile_bloc.dart';
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/model/profile/educational_background.dart'; import 'package:unit2/model/profile/educational_background.dart';
import 'package:unit2/screens/profile/components/education/add_modal.dart'; import 'package:unit2/screens/profile/components/education/add_modal.dart';
@ -16,7 +19,6 @@ import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/Leadings/add_leading.dart';
import 'package:unit2/widgets/empty_data.dart'; import 'package:unit2/widgets/empty_data.dart';
import 'package:unit2/widgets/error_state.dart'; import 'package:unit2/widgets/error_state.dart';
import '../../../bloc/profile/education/education_bloc.dart'; import '../../../bloc/profile/education/education_bloc.dart';
import '../../../model/profile/attachment.dart'; import '../../../model/profile/attachment.dart';
import '../../../theme-data.dart/btn-style.dart'; import '../../../theme-data.dart/btn-style.dart';
@ -33,7 +35,8 @@ class EducationScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final parent = context; final parent = context;
FilePickerResult? result;
List<PlatformFile>? results = [];
AttachmentCategory? selectedAttachmentCategory; AttachmentCategory? selectedAttachmentCategory;
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
int profileId; int profileId;
@ -115,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 ////EDITED STATE
if (state is EditedEducationState) { if (state is EditedEducationState) {
if (state.response['success']) { if (state.response['success']) {
@ -157,11 +182,32 @@ 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) { builder: (context, state) {
if (state is EducationalBackgroundLoadedState) { if (state is EducationalBackgroundLoadedState) {
for (var cat in state.attachmentCategory) { for (var cat in state.attachmentCategory) {
if (cat.subclass.id == 1) { if (cat.subclass!.id == 1) {
attachmentCategories.add(cat); attachmentCategories.add(cat);
} }
} }
@ -352,6 +398,7 @@ class EducationScreen extends StatelessWidget {
index])); index]));
} }
if (value == 3) { if (value == 3) {
results.clear();
showDialog( showDialog(
context: context, context: context,
builder: builder:
@ -423,7 +470,7 @@ class EducationScreen extends StatelessWidget {
selectedAttachmentCategory = value; selectedAttachmentCategory = value;
}, },
items: attachmentCategories.map((e) { items: attachmentCategories.map((e) {
return DropdownMenuItem(value: e, child: Text(e.description)); return DropdownMenuItem(value: e, child: Text(e.description!));
}).toList()), }).toList()),
const SizedBox( const SizedBox(
height: height:
@ -463,7 +510,9 @@ class EducationScreen extends StatelessWidget {
]); ]);
setState(() { setState(() {
if (newResult != null) { if (newResult != null) {
result = newResult; newResult.files.forEach((element) {
results.add(element);
});
} }
}); });
}, },
@ -479,13 +528,13 @@ class EducationScreen extends StatelessWidget {
SizedBox( SizedBox(
height: 100, height: 100,
width: double.maxFinite, width: double.maxFinite,
child: result == null child: results.isEmpty
? const SizedBox() ? const SizedBox()
: Expanded( : Expanded(
child: ListView.builder( child: ListView.builder(
itemCount: result!.files.length, itemCount: results.length,
itemBuilder: (BuildContext context, index) { itemBuilder: (BuildContext context, index) {
final kb = result!.files[index].size / 1024; final kb = results[index].size / 1024;
final mb = kb / 1024; final mb = kb / 1024;
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB'; final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
return Column( return Column(
@ -497,19 +546,19 @@ class EducationScreen extends StatelessWidget {
children: [ children: [
Flexible( Flexible(
child: SizedBox( child: SizedBox(
child: result!.files[index].extension!.toLowerCase() == 'pdf' child: results[index].extension!.toLowerCase() == 'pdf'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/pdf.svg', 'assets/svgs/pdf.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'png' : results[index].extension!.toLowerCase() == 'png'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/png.svg', 'assets/svgs/png.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'jpg' || result!.files[index].extension!.toLowerCase() == 'jpeg' : results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/jpg.svg', 'assets/svgs/jpg.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
@ -519,18 +568,36 @@ class EducationScreen extends StatelessWidget {
const SizedBox( const SizedBox(
width: 12, width: 12,
), ),
Flexible( Flexible(
flex: 4, flex: 6,
child: Text( child: Text(
result!.files[index].name, results[index].name,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2), 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,
), ),
const SizedBox(width: 12,), onPressed: () {
Flexible( setState(() {
flex: 2, results.removeAt(index);
child: Text(size)) });
},
))
], ],
)), )),
const Divider() const Divider()
@ -554,12 +621,15 @@ class EducationScreen extends StatelessWidget {
onPressed: () { onPressed: () {
List<String> paths = []; List<String> paths = [];
if (selectedAttachmentCategory != null) { if (selectedAttachmentCategory != null && results.isNotEmpty) {
for (var res in result!.files) { for (var res in results) {
paths.add(res.path!); paths.add(res.path!);
} }
setState(() {
results.clear();
});
Navigator.pop(context); Navigator.pop(context);
parent.read<EducationBloc>().add(AddAttachment(attachmentModule: state.educationalBackground[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString())); 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")), child: const Text("Submit")),
@ -594,6 +664,7 @@ class EducationScreen extends StatelessWidget {
) )
], ],
), ),
////Show Attachments ////Show Attachments
SizedBox( SizedBox(
child: state child: state
@ -620,22 +691,45 @@ class EducationScreen extends StatelessWidget {
1 1
? ?
////Single Attachment view ////Single Attachment view
SingleAttachment( Column(
onpressed: () { children: [
confirmAlert( const Divider(),
context, SingleAttachment(
() {}, onpressed:
"Delete?", () {
"Confirm Delete?"); confirmAlert(
}, context,
attachment: state () {
.educationalBackground[ parent.read<EducationBloc>().add(DeleteEducationAttachment(
index] attachment: state
.attachments! .educationalBackground[
.first, index]
.attachments!
.first,
moduleId: state
.educationalBackground[
index]
.id!,
profileId:
profileId,
token:
token!));
}, "Delete?",
"Confirm Delete?");
},
attachment: state
.educationalBackground[
index]
.attachments!
.first,
),
],
) )
////Multiple Attachments View ////Multiple Attachments View
: MultipleAttachments( : MultipleAttachments(
profileId:
profileId,
token: token!,
eligibilityName: state eligibilityName: state
.educationalBackground[ .educationalBackground[
index] index]
@ -646,6 +740,21 @@ class EducationScreen extends StatelessWidget {
.educationalBackground[ .educationalBackground[
index] index]
.attachments!, .attachments!,
educationBloc:
BlocProvider.of<
EducationBloc>(
parent),
eligibilityBloc:
null,
workHistoryBloc:
null,
learningDevelopmentBloc:
null,
blocId: 1,
moduleId: state
.educationalBackground[
index]
.id!,
)) ))
], ],
), ),

View File

@ -1,5 +1,4 @@
import 'dart:io'; import 'dart:io';
import 'package:app_popup_menu/app_popup_menu.dart'; import 'package:app_popup_menu/app_popup_menu.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -9,7 +8,10 @@ import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:form_builder_validators/form_builder_validators.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/profile_bloc.dart';
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/model/profile/attachment.dart'; import 'package:unit2/model/profile/attachment.dart';
import 'package:unit2/model/profile/eligibility.dart'; import 'package:unit2/model/profile/eligibility.dart';
@ -38,7 +40,7 @@ class EligibiltyScreen extends StatelessWidget {
BuildContext parent = context; BuildContext parent = context;
String? token; String? token;
int? profileId; int? profileId;
FilePickerResult? result; List<PlatformFile>? results = [];
AttachmentCategory? selectedAttachmentCategory; AttachmentCategory? selectedAttachmentCategory;
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
@ -101,7 +103,7 @@ class EligibiltyScreen extends StatelessWidget {
if (state is EligibilityLoaded || if (state is EligibilityLoaded ||
state is AddEligibilityState || state is AddEligibilityState ||
state is EditEligibilityState || state is EditEligibilityState ||
state is DeletedState || state is EligibilityDeletedState ||
state is EligibilityAddedState || state is EligibilityAddedState ||
state is EligibilityEditedState || state is EligibilityEditedState ||
state is EligibilityErrorState) { state is EligibilityErrorState) {
@ -109,7 +111,7 @@ class EligibiltyScreen extends StatelessWidget {
progress!.dismiss(); progress!.dismiss();
} }
////DELETED STATE ////DELETED STATE
if (state is DeletedState) { if (state is EligibilityDeletedState) {
if (state.success) { if (state.success) {
successAlert(context, "Deletion Successfull", successAlert(context, "Deletion Successfull",
"Eligibility has been deleted successfully", "Eligibility has been deleted successfully",
@ -129,6 +131,28 @@ class EligibiltyScreen extends StatelessWidget {
}); });
} }
} }
////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());
});
}
}
////ADDED STATE ////ADDED STATE
if (state is EligibilityAddedState) { if (state is EligibilityAddedState) {
if (state.response['success']) { if (state.response['success']) {
@ -171,13 +195,34 @@ class EligibiltyScreen extends StatelessWidget {
}); });
} }
} }
////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());
});
}
}
}, },
builder: (context, state) { builder: (context, state) {
return BlocBuilder<EligibilityBloc, EligibilityState>( return BlocBuilder<EligibilityBloc, EligibilityState>(
builder: (context, state) { builder: (context, state) {
if (state is EligibilityLoaded) { if (state is EligibilityLoaded) {
for (var cat in state.attachmentCategory) { for (var cat in state.attachmentCategory) {
if (cat.subclass.id == 3) { if (cat.subclass!.id == 3) {
attachmentCategories.add(cat); attachmentCategories.add(cat);
} }
} }
@ -193,410 +238,460 @@ class EligibiltyScreen extends StatelessWidget {
.eligibility! .eligibility!
.title; .title;
return Column( return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Container( Container(
width: screenWidth,
padding: padding:
const EdgeInsets.symmetric( const EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 8), vertical: 8),
decoration: box1(), decoration: box1(),
child: Row( child: Column(
children: [ children: [
Expanded( Row(
child: Column( children: [
mainAxisSize: Expanded(
MainAxisSize.min, child: Column(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment MainAxisAlignment
.start, .start,
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment CrossAxisAlignment
.start, .start,
children: [ children: [
Text( Text(
title, title,
style: Theme.of( style: Theme.of(
context) context)
.textTheme .textTheme
.titleMedium! .titleMedium!
.copyWith( .copyWith(
fontWeight: fontWeight:
FontWeight FontWeight
.w500, .w500,
color: color:
primary), primary),
), ),
const SizedBox( const SizedBox(
height: 5, height: 5,
), ),
Text( Text(
"$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", "$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}",
style: Theme.of( style: Theme.of(
context) context)
.textTheme .textTheme
.titleSmall), .titleSmall),
const SizedBox( const SizedBox(
height: 3, height: 3,
), ),
Text( Text(
"Rating : ${state.eligibilities[index].rating ?? 'N/A'}", "Rating : ${state.eligibilities[index].rating ?? 'N/A'}",
style: Theme.of( style: Theme.of(
context) context)
.textTheme .textTheme
.titleSmall), .titleSmall),
const Divider(), ]),
////Show Attachments ),
SizedBox( AppPopupMenu<int>(
child: state.eligibilities[index].attachments == offset: const Offset(
null || -10, -10),
state 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[ .eligibilities[
index] index]
.attachments! .id!,
.isEmpty profileId:
? const SizedBox() profileId
: state.eligibilities[index].attachments != .toString(),
null && token:
state.eligibilities[index].attachments!.length == token!));
1 }, "Delete?",
? "Confirm Delete?");
////Single Attachment view }
SingleAttachment( if (value == 1) {
onpressed: ////edit eligibilty-= = = = = = = = =>>
() { final progress =
confirmAlert(context, ProgressHUD.of(
() { context);
parent.read<EligibilityBloc>().add(DeleteAttachment(attachment: state.eligibilities[index].attachments!.first, moduleId: state.eligibilities[index].attachments!.first.id.toString(), profileId: profileId.toString(), token: token!)); progress!
}, "Delete?", .showWithText(
"Confirm Delete?"); "Loading...");
}, EligibityCert
attachment: state eligibityCert =
.eligibilities[index] state.eligibilities[
.attachments! index];
.first, bool overseas = eligibityCert
) .examAddress!
////Multiple Attachments View .country!
: MultipleAttachments( .id
eligibilityName: state .toString() ==
.eligibilities[index] '175'
.eligibility! ? false
.title, : true;
attachments: state eligibityCert
.eligibilities[index] .overseas =
.attachments!, overseas;
))
]),
),
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;
eligibityCert.overseas = eligibityCert
overseas; .overseas =
overseas;
context context
.read< .read<
EligibilityBloc>() EligibilityBloc>()
.add(ShowEditEligibilityForm( .add(ShowEditEligibilityForm(
eligibityCert: eligibityCert:
eligibityCert)); eligibityCert));
} }
////Attachment ////Attachment
if (value == 3) { if (value == 3) {
showDialog( results.clear();
context: context, showDialog(
builder: context:
(BuildContext context,
context) { builder:
return AlertDialog( (BuildContext
contentPadding: context) {
const EdgeInsets return AlertDialog(
.all(0), contentPadding:
backgroundColor: const EdgeInsets
Colors.grey .all(0),
.shade100, backgroundColor:
icon: Colors
const Icon( .grey
Icons .shade100,
.file_copy, icon:
size: 32, const Icon(
color: Icons
primary, .file_copy,
), size: 32,
title: const Text( color:
"File Attachment:"), primary,
content: StatefulBuilder( ),
builder: title: const Text(
"File Attachment:"),
content: StatefulBuilder(builder:
(context, (context,
setState) { setState) {
return Padding( return Padding(
padding: const EdgeInsets padding:
.all( const EdgeInsets.all(16.0),
16.0), child: Column(
child: Column( mainAxisSize:
mainAxisSize: MainAxisSize.min,
MainAxisSize mainAxisAlignment: MainAxisAlignment.start,
.min, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: children: [
MainAxisAlignment const Divider(),
.start, Text(
crossAxisAlignment: title,
CrossAxisAlignment.start, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary),
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 { const SizedBox(
FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [ height: 5,
'jpg', ),
'png', Text("$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", style: Theme.of(context).textTheme.titleSmall),
'jpeg', const SizedBox(
'pdf' height: 3,
]); ),
setState(() { Text("Rating : ${state.eligibilities[index].rating ?? 'N/A'}", style: Theme.of(context).textTheme.titleSmall),
if (newResult != null) { const Divider(),
result = newResult; FormBuilderDropdown(
} autovalidateMode: AutovalidateMode.always,
}); decoration: normalTextFieldStyle("attachment category", "attachment category"),
}, name: 'attachments_categorues',
child: const Center( validator: FormBuilderValidators.required(errorText: "This field is required"),
child: Text( onChanged: (value) {
"Select Files", selectedAttachmentCategory = value;
textAlign: TextAlign.center, },
style: TextStyle(color: Colors.black), items: attachmentCategories.map((e) {
))), return DropdownMenuItem(value: e, child: Text(e.description!));
const Divider(), }).toList()),
SingleChildScrollView( const SizedBox(
child: height: 8,
SizedBox( ),
height: 100, Text(
width: double.maxFinite, "You may attach necessary documents such as Transcript of Records (TOR), diploma, and the likes.",
child: result == null style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.black),
? const SizedBox() ),
: Expanded( const SizedBox(
child: ListView.builder( height: 5,
itemCount: result!.files.length, ),
itemBuilder: (BuildContext context, index) { Text(
final kb = result!.files[index].size / 1024; "Acceptable Files: PDF, JPEG, PNG",
final mb = kb / 1024; style: Theme.of(context).textTheme.bodySmall,
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB'; ),
return Column( Text(
mainAxisSize: MainAxisSize.min, "Max File Size (per attachment): 1MB",
children: [ style: Theme.of(context).textTheme.bodySmall,
SizedBox( ),
width: double.infinity, const Divider(),
child: Row( ElevatedButton(
children: [ style: ButtonStyle(
Flexible( elevation: MaterialStateProperty.all(0),
child: SizedBox( backgroundColor: MaterialStateProperty.all<Color>(Colors.white),
child: result!.files[index].extension!.toLowerCase() == 'pdf' ),
? SvgPicture.asset( onPressed: () async {
'assets/svgs/pdf.svg', FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
height: blockSizeVertical * 3, 'jpg',
allowDrawingOutsideViewBox: true, 'png',
) 'jpeg',
: result!.files[index].extension!.toLowerCase() == 'png' '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( ? SvgPicture.asset(
'assets/svgs/png.svg', 'assets/svgs/pdf.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'jpg' || result!.files[index].extension!.toLowerCase() == 'jpeg' : results[index].extension!.toLowerCase() == 'png'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/jpg.svg', 'assets/svgs/png.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: const SizedBox())), : results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
const SizedBox( ? SvgPicture.asset(
width: 12, 'assets/svgs/jpg.svg',
), height: blockSizeVertical * 3,
Flexible( allowDrawingOutsideViewBox: true,
flex: 4, )
child: Text( : const SizedBox())),
result!.files[index].name, const SizedBox(
overflow: TextOverflow.ellipsis, width: 12,
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2), ),
), 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( const SizedBox(
width: 8,
),
Flexible(
flex: 2, flex: 2,
child: Text(size)) child: Text(
], size,
)), style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
const Divider() )),
], Flexible(
); flex: 1,
}), child: IconButton(
), icon: const Icon(
), Icons.close,
), color: Colors.grey,
const SizedBox( ),
height: onPressed: () {
12, setState(() {
), results.removeAt(index);
SizedBox( });
width: },
double.maxFinite, ))
height: ],
50, )),
child: ElevatedButton( const Divider()
style: mainBtnStyle(primary, Colors.transparent, second), ],
onPressed: () { );
List<String> paths = []; }),
),
),
),
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) { if (selectedAttachmentCategory != null && results.isNotEmpty) {
for (var res in result!.files) { for (var res in results) {
paths.add(res.path!); paths.add(res.path!);
} }
Navigator.pop(context); setState(() {
parent.read<EligibilityBloc>().add(AddAttachment(attachmentModule: state.eligibilities[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString())); results.clear();
} });
}, Navigator.pop(context);
child: const Text("Submit")), 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(
menuItems: [ text: "Update",
popMenuItem( value: 1,
text: "Update", icon: Icons.edit),
value: 1, popMenuItem(
icon: Icons.edit), text: "Remove",
popMenuItem( value: 2,
text: "Remove", icon:
value: 2, Icons.delete),
icon: Icons.delete), popMenuItem(
popMenuItem( text: "Attach",
text: "Attach", value: 3,
value: 3, icon: Icons
icon: Icons .attach_file),
.attach_file), ],
icon: const Icon(
Icons.more_vert,
color: Colors.grey,
),
tooltip: "Options",
)
], ],
icon: const Icon( ),
Icons.more_vert, const Divider(),
color: Colors.grey, ////Show Attachments
), SizedBox(
tooltip: "Options", width: screenWidth,
) child: state
.eligibilities[
index]
.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!,
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!,
))
], ],
), ),
), ),

View File

@ -1,19 +1,18 @@
import 'package:app_popup_menu/app_popup_menu.dart'; import 'package:app_popup_menu/app_popup_menu.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.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_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:fluttericon/font_awesome_icons.dart';
import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:intl/intl.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/profile_bloc.dart';
import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart';
import 'package:unit2/bloc/user/user_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/screens/profile/components/learning_development/edit_modal.dart';
import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart';
import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/theme-data.dart/colors.dart';
@ -41,9 +40,9 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
String token; String token;
int profileId; int profileId;
BuildContext parent = context; BuildContext parent = context;
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
FilePickerResult? result; List<PlatformFile>? results = [];
AttachmentCategory? selectedAttachmentCategory; AttachmentCategory? selectedAttachmentCategory;
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
return Scaffold( return Scaffold(
@ -89,13 +88,11 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
backgroundColor: Colors.black87, backgroundColor: Colors.black87,
child: BlocBuilder<UserBloc, UserState>( child: BlocBuilder<UserBloc, UserState>(
builder: (context, state) { builder: (context, state) {
if (state is UserLoggedIn) { if (state is UserLoggedIn) {
token = state.userData!.user!.login!.token!; token = state.userData!.user!.login!.token!;
profileId = state.userData!.user!.login!.user!.profileId!; profileId = state.userData!.user!.login!.user!.profileId!;
return BlocBuilder<ProfileBloc, ProfileState>( return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) { builder: (context, state) {
if (state is ProfileLoaded) { if (state is ProfileLoaded) {
return BlocConsumer<LearningDevelopmentBloc, return BlocConsumer<LearningDevelopmentBloc,
LearningDevelopmentState>( LearningDevelopmentState>(
@ -134,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 ////Updated State
if (state is LearningDevelopmentUpdatedState) { if (state is LearningDevelopmentUpdatedState) {
if (state.response['success']) { if (state.response['success']) {
@ -177,16 +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 // TODO: implement listener
}, },
builder: (context, state) { builder: (context, state) {
if (state is LearningDevelopmentLoadedState) { if (state is LearningDevelopmentLoadedState) {
for (var cat in state.attachmentCategory) { for (var cat in state.attachmentCategory) {
if (cat.subclass.id == 2) { if (cat.subclass!.id == 2) {
attachmentCategories.add(cat); attachmentCategories.add(cat);
} }
} }
if (state.learningsAndDevelopment.isNotEmpty) { if (state.learningsAndDevelopment.isNotEmpty) {
return ListView.builder( return ListView.builder(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
@ -232,28 +270,32 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
Expanded( Expanded(
child: Column( child: Column(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.start, MainAxisAlignment
.start,
crossAxisAlignment: crossAxisAlignment:
CrossAxisAlignment CrossAxisAlignment
.start, .start,
children: [ children: [
Text( Text(
training, training,
style: Theme.of(context) style: Theme.of(
context)
.textTheme .textTheme
.titleMedium! .titleMedium!
.copyWith( .copyWith(
fontWeight: fontWeight:
FontWeight FontWeight
.w600, .w600,
color: primary), color:
primary),
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
Text( Text(
provider, provider,
style: Theme.of(context) style: Theme.of(
context)
.textTheme .textTheme
.titleSmall, .titleSmall,
), ),
@ -262,7 +304,8 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
), ),
Text( Text(
"$duration: $start to $end", "$duration: $start to $end",
style: Theme.of(context) style: Theme.of(
context)
.textTheme .textTheme
.labelMedium, .labelMedium,
), ),
@ -272,39 +315,39 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
]), ]),
), ),
AppPopupMenu<int>( AppPopupMenu<int>(
offset: const Offset(-10, -10), offset:
const Offset(-10, -10),
elevation: 3, elevation: 3,
onSelected: (value) { onSelected: (value) {
////delete -= = = = = = = = =>> ////delete -= = = = = = = = =>>
if (value == 2) { if (value == 2) {
confirmAlert(context, () { confirmAlert(context,
() {
final progress = final progress =
ProgressHUD.of( ProgressHUD.of(
context); context);
progress!.showWithText( progress!
"Loading..."); .showWithText(
BlocProvider.of< "Loading...");
LearningDevelopmentBloc>( BlocProvider.of<LearningDevelopmentBloc>(context).add(DeleteLearningDevelopment(
context) trainingId: state
.add(DeleteLearningDevelopment( .learningsAndDevelopment[
trainingId: state index]
.learningsAndDevelopment[ .conductedTraining!
index] .id!,
.conductedTraining! hours: state
.id!, .learningsAndDevelopment[
hours: state index]
.learningsAndDevelopment[ .conductedTraining!
index] .totalHours!,
.conductedTraining! sponsorId: state
.totalHours!, .learningsAndDevelopment[
sponsorId: state index]
.learningsAndDevelopment[ .sponsoredBy
index] ?.id,
.sponsoredBy profileId:
?.id, profileId,
profileId: token: token));
profileId,
token: token));
}, "Delete?", }, "Delete?",
"Confirm Delete?"); "Confirm Delete?");
} }
@ -312,7 +355,8 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
bool isOverseas; bool isOverseas;
////edit = = = = = = = =>> ////edit = = = = = = = =>>
final progress = final progress =
ProgressHUD.of(context); ProgressHUD.of(
context);
progress!.showWithText( progress!.showWithText(
"Loading..."); "Loading...");
@ -340,225 +384,246 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
isOverseas: isOverseas:
isOverseas)); isOverseas));
} }
if(value == 3){ if (value == 3) {
showDialog( results.clear();
context: context, showDialog(
builder: context: context,
(BuildContext builder:
context) { (BuildContext
return AlertDialog( context) {
contentPadding: return AlertDialog(
const EdgeInsets contentPadding:
.all(0), const EdgeInsets
backgroundColor: .all(0),
Colors.grey backgroundColor:
.shade100, Colors.grey
icon: .shade100,
const Icon( icon:
Icons const Icon(
.file_copy, Icons
size: 32, .file_copy,
color: size: 32,
primary, color:
), primary,
title: const Text( ),
"File Attachment:"), title: const Text(
content: StatefulBuilder( "File Attachment:"),
builder: content: StatefulBuilder(
(context, builder:
setState) { (context,
return Padding( setState) {
padding: const EdgeInsets return Padding(
.all( padding: const EdgeInsets
16.0), .all(
child: Column( 16.0),
mainAxisSize: child: Column(
MainAxisSize mainAxisSize:
.min, MainAxisSize
mainAxisAlignment: .min,
MainAxisAlignment mainAxisAlignment:
.start, MainAxisAlignment
crossAxisAlignment: .start,
CrossAxisAlignment.start, crossAxisAlignment:
children: [ CrossAxisAlignment.start,
const Divider(), children: [
Text( const Divider(),
training, Text(
style: training,
Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary), 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),
), ),
const SizedBox( onPressed: () async {
height: FilePickerResult? newResult = await FilePicker.platform.pickFiles(allowMultiple: true, type: FileType.custom, allowedExtensions: [
5, 'jpg',
), 'png',
Text( 'jpeg',
provider, 'pdf'
style: Theme.of(context).textTheme.titleSmall), ]);
const SizedBox( setState(() {
height: if (newResult != null) {
3, newResult.files.forEach((element) {
), results.add(element);
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) {
result = newResult;
}
}); });
}, }
child: const Center( });
child: Text( },
"Select Files", child: const Center(
textAlign: TextAlign.center, child: Text(
style: TextStyle(color: Colors.black), "Select Files",
))), textAlign: TextAlign.center,
const Divider(), style: TextStyle(color: Colors.black),
SingleChildScrollView( ))),
child: const Divider(),
SizedBox( SingleChildScrollView(
height: 100, child:
width: double.maxFinite, SizedBox(
child: result == null height: 100,
? const SizedBox() width: double.maxFinite,
: Expanded( child: results.isEmpty
child: ListView.builder( ? const SizedBox()
itemCount: result!.files.length, : Expanded(
itemBuilder: (BuildContext context, index) { child: ListView.builder(
final kb = result!.files[index].size / 1024; itemCount: results.length,
final mb = kb / 1024; itemBuilder: (BuildContext context, index) {
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB'; final kb = results[index].size / 1024;
return Column( final mb = kb / 1024;
mainAxisSize: MainAxisSize.min, final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
children: [ return Column(
SizedBox( mainAxisSize: MainAxisSize.min,
children: [
width: double.infinity, SizedBox(
child: Row( width: double.infinity,
children: [ child: Row(
Flexible( children: [
flex: 1, Flexible(
child: SizedBox( flex: 1,
child: result!.files[index].extension!.toLowerCase() == 'pdf' 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( ? SvgPicture.asset(
'assets/svgs/pdf.svg', 'assets/svgs/png.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'png' : results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/png.svg', 'assets/svgs/jpg.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'jpg' || result!.files[index].extension!.toLowerCase() == 'jpeg' : const SizedBox())),
? SvgPicture.asset( const SizedBox(
'assets/svgs/jpg.svg', width: 12,
height: blockSizeVertical * 3, ),
allowDrawingOutsideViewBox: true, Flexible(
) flex: 6,
: const SizedBox())), child: Text(
const SizedBox( results[index].name,
width: 12, overflow: TextOverflow.ellipsis,
), style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2),
Flexible( ),
flex: 4, ),
child: Text( const SizedBox(
result!.files[index].name, width: 8,
overflow: TextOverflow.ellipsis, ),
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2), Flexible(
), flex: 2,
), child: Text(
const SizedBox(width: 12,), size,
Flexible( style: Theme.of(context).textTheme.bodySmall!.copyWith(color: Colors.grey),
flex: 2, )),
child: Text(size)) Flexible(
], flex: 1,
)), child: IconButton(
const Divider() icon: const Icon(
], Icons.close,
); color: Colors.grey,
}), ),
), onPressed: () {
), setState(() {
), results.removeAt(index);
const SizedBox( });
height: },
12, ))
), ],
SizedBox( )),
width: const Divider()
double.maxFinite, ],
height: );
50, }),
child: ElevatedButton( ),
style: mainBtnStyle(primary, Colors.transparent, second), ),
onPressed: () { ),
List<String> paths = []; 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) { if (selectedAttachmentCategory != null && results.isNotEmpty) {
for (var res in result!.files) { for (var res in results) {
paths.add(res.path!); paths.add(res.path!);
} }
Navigator.pop(context); results.clear();
parent.read<LearningDevelopmentBloc>().add(AddAttachment(attachmentModule: state.learningsAndDevelopment[index].conductedTraining!.id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString())); 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")), },
) child: const Text("Submit")),
]), )
); ]),
}),
); );
}); }),
);
});
} }
}, },
menuItems: [ menuItems: [
@ -573,7 +638,8 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
popMenuItem( popMenuItem(
text: "Attach", text: "Attach",
value: 3, value: 3,
icon: Icons.attach_file), icon: Icons
.attach_file),
], ],
icon: const Icon( icon: const Icon(
Icons.more_vert, Icons.more_vert,
@ -584,44 +650,92 @@ class LearningAndDevelopmentScreen extends StatelessWidget {
], ],
), ),
SizedBox( SizedBox(
child: state.learningsAndDevelopment[index].attachments == child: state
null || .learningsAndDevelopment[
state 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[ .learningsAndDevelopment[
index] index]
.attachments! .attachments!
.isEmpty .first,
? const SizedBox() moduleId: state
: state.learningsAndDevelopment[index].attachments != .learningsAndDevelopment[
null && index]
state.learningsAndDevelopment[index].attachments!.length == .conductedTraining!
1 .id!,
? profileId:
////Single Attachment view profileId,
SingleAttachment( token:
onpressed: token));
() { }, "Delete?",
confirmAlert(context, "Confirm Delete?");
() { },
attachment: state
}, "Delete?", .learningsAndDevelopment[
"Confirm Delete?"); index]
}, .attachments!
attachment: state .first,
.learningsAndDevelopment[index] )
.attachments! ////Multiple Attachments View
.first, : MultipleAttachments(
) profileId:
////Multiple Attachments View profileId,
: MultipleAttachments( token: token,
eligibilityName: state moduleId: state
.learningsAndDevelopment[index] .learningsAndDevelopment[
.conductedTraining!.title!.title!, index]
.conductedTraining!
attachments: state .title!
.learningsAndDevelopment[index] .id!,
.attachments!, 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!,
))
], ],
), ),
), ),

View File

@ -7,9 +7,11 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:fluttericon/font_awesome_icons.dart';
import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:intl/intl.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/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/screens/profile/components/work_history/add_modal.dart'; import 'package:unit2/screens/profile/components/work_history/add_modal.dart';
@ -21,7 +23,6 @@ import 'package:unit2/widgets/Leadings/add_leading.dart';
import 'package:unit2/widgets/Leadings/close_leading.dart'; import 'package:unit2/widgets/Leadings/close_leading.dart';
import 'package:unit2/widgets/empty_data.dart'; import 'package:unit2/widgets/empty_data.dart';
import 'package:unit2/widgets/error_state.dart'; import 'package:unit2/widgets/error_state.dart';
import '../../../bloc/profile/workHistory/workHistory_bloc.dart'; import '../../../bloc/profile/workHistory/workHistory_bloc.dart';
import '../../../model/profile/attachment.dart'; import '../../../model/profile/attachment.dart';
import '../../../model/profile/work_history.dart'; import '../../../model/profile/work_history.dart';
@ -38,10 +39,11 @@ class WorkHistoryScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
BuildContext parent = context; BuildContext parent = context;
String? token; String? token;
int? profileId; int? profileId;
FilePickerResult? result; List<PlatformFile>? results = [];
AttachmentCategory? selectedAttachmentCategory; AttachmentCategory? selectedAttachmentCategory;
List<AttachmentCategory> attachmentCategories = []; List<AttachmentCategory> attachmentCategories = [];
return Scaffold( return Scaffold(
@ -108,7 +110,7 @@ class WorkHistoryScreen extends StatelessWidget {
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
progress!.dismiss(); progress!.dismiss();
} }
//DELETED STATE ////DELETED STATE
if (state is DeletedState) { if (state is DeletedState) {
if (state.success) { if (state.success) {
successAlert(context, "Deletion Successfull", successAlert(context, "Deletion Successfull",
@ -149,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 //// EDITED STATE
if (state is WorkHistoryEditedState) { if (state is WorkHistoryEditedState) {
if (state.response['success']) { if (state.response['success']) {
@ -174,7 +218,7 @@ class WorkHistoryScreen extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
if (state is WorkHistoryLoaded) { if (state is WorkHistoryLoaded) {
for (var cat in state.attachmentCategory) { for (var cat in state.attachmentCategory) {
if (cat.subclass.id == 4) { if (cat.subclass!.id == 4) {
attachmentCategories.add(cat); attachmentCategories.add(cat);
} }
} }
@ -201,14 +245,8 @@ class WorkHistoryScreen extends StatelessWidget {
.workExperiences[index] .workExperiences[index]
.toDate!); .toDate!);
return Column( return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Container( Container(
width: screenWidth,
decoration: box1(), decoration: box1(),
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8), horizontal: 12, vertical: 8),
@ -303,6 +341,7 @@ class WorkHistoryScreen extends StatelessWidget {
} }
////Attachment ////Attachment
if (value == 3) { if (value == 3) {
results.clear();
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext builder: (BuildContext
@ -383,7 +422,7 @@ class WorkHistoryScreen extends StatelessWidget {
selectedAttachmentCategory = value; selectedAttachmentCategory = value;
}, },
items: attachmentCategories.map((e) { items: attachmentCategories.map((e) {
return DropdownMenuItem(value: e, child: Text(e.description)); return DropdownMenuItem(value: e, child: Text(e.description!));
}).toList()), }).toList()),
const SizedBox( const SizedBox(
height: height:
@ -429,7 +468,9 @@ class WorkHistoryScreen extends StatelessWidget {
]); ]);
setState(() { setState(() {
if (newResult != null) { if (newResult != null) {
result = newResult; newResult.files.forEach((element) {
results.add(element);
});
} }
}); });
}, },
@ -447,13 +488,13 @@ class WorkHistoryScreen extends StatelessWidget {
100, 100,
width: width:
double.maxFinite, double.maxFinite,
child: result == null child: results.isEmpty
? const SizedBox() ? const SizedBox()
: Expanded( : Expanded(
child: ListView.builder( child: ListView.builder(
itemCount: result!.files.length, itemCount: results.length,
itemBuilder: (BuildContext context, index) { itemBuilder: (BuildContext context, index) {
final kb = result!.files[index].size / 1024; final kb = results[index].size / 1024;
final mb = kb / 1024; final mb = kb / 1024;
final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB'; final size = mb >= 1 ? '${mb.toStringAsFixed(2)}MB' : '${kb.toStringAsFixed(2)}KB';
return Column( return Column(
@ -465,19 +506,19 @@ class WorkHistoryScreen extends StatelessWidget {
children: [ children: [
Flexible( Flexible(
child: SizedBox( child: SizedBox(
child: result!.files[index].extension!.toLowerCase() == 'pdf' child: results[index].extension!.toLowerCase() == 'pdf'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/pdf.svg', 'assets/svgs/pdf.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'png' : results[index].extension!.toLowerCase() == 'png'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/png.svg', 'assets/svgs/png.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
) )
: result!.files[index].extension!.toLowerCase() == 'jpg' || result!.files[index].extension!.toLowerCase() == 'jpeg' : results[index].extension!.toLowerCase() == 'jpg' || results[index].extension!.toLowerCase() == 'jpeg'
? SvgPicture.asset( ? SvgPicture.asset(
'assets/svgs/jpg.svg', 'assets/svgs/jpg.svg',
height: blockSizeVertical * 3, height: blockSizeVertical * 3,
@ -487,18 +528,36 @@ class WorkHistoryScreen extends StatelessWidget {
const SizedBox( const SizedBox(
width: 12, width: 12,
), ),
Flexible( Flexible(
flex: 4, flex: 6,
child: Text( child: Text(
result!.files[index].name, results[index].name,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.headlineLarge!.copyWith(fontSize: blockSizeVertical * 2), 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,
), ),
const SizedBox(width: 12,), onPressed: () {
Flexible( setState(() {
flex: 2, results.removeAt(index);
child: Text(size)) });
},
))
], ],
)), )),
const Divider() const Divider()
@ -522,12 +581,15 @@ class WorkHistoryScreen extends StatelessWidget {
onPressed: () { onPressed: () {
List<String> paths = []; List<String> paths = [];
if (selectedAttachmentCategory != null) { if (selectedAttachmentCategory != null && results.isNotEmpty) {
for (var res in result!.files) { for (var res in results) {
paths.add(res.path!); paths.add(res.path!);
} }
setState(() {
results.clear();
});
Navigator.pop(context); Navigator.pop(context);
parent.read<WorkHistoryBloc>().add(AddAttachment(attachmentModule: state.workExperiences[index].id.toString(), filePaths: paths, categoryId: selectedAttachmentCategory!.id.toString(), token: token!, profileId: profileId.toString())); 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")), child: const Text("Submit")),
@ -592,8 +654,22 @@ class WorkHistoryScreen extends StatelessWidget {
onpressed: () { onpressed: () {
confirmAlert( confirmAlert(
context, context,
() {}, () {
"Delete?", parent.read<WorkHistoryBloc>().add(DeleteWorkHistoryAttachment(
attachment: state
.workExperiences[
index]
.attachments!
.first,
moduleId: state
.workExperiences[
index]
.id!,
profileId:
profileId!,
token:
token!));
}, "Delete?",
"Confirm Delete?"); "Confirm Delete?");
}, },
attachment: state attachment: state
@ -604,6 +680,22 @@ class WorkHistoryScreen extends StatelessWidget {
) )
////Multiple Attachments View ////Multiple Attachments View
: MultipleAttachments( : 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 eligibilityName: state
.workExperiences[ .workExperiences[
index] index]

View File

@ -1,150 +1,234 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:fluttericon/entypo_icons.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 '../../../model/profile/attachment.dart';
import '../../../theme-data.dart/box_shadow.dart'; import '../../../theme-data.dart/box_shadow.dart';
import '../../../theme-data.dart/colors.dart'; import '../../../theme-data.dart/colors.dart';
import '../../../utils/alerts.dart';
import '../../../utils/global.dart'; import '../../../utils/global.dart';
class MultipleAttachments extends StatelessWidget { class MultipleAttachments extends StatelessWidget {
final List<Attachment> attachments; final List<Attachment> attachments;
final String eligibilityName; final String eligibilityName;
const MultipleAttachments({ final EducationBloc? educationBloc;
super.key, final EligibilityBloc? eligibilityBloc;
required this.attachments, final LearningDevelopmentBloc? learningDevelopmentBloc;
required this.eligibilityName 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
Flexible( Flexible(
flex: flex: 3,
2, child: Container(
child: Container( padding: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5), decoration:
decoration: box1().copyWith(color: Colors.grey.shade300, boxShadow: []), box1().copyWith(color: Colors.grey.shade300, boxShadow: []),
child: Text( child: AutoSizeText(
attachments.first.filename!,
overflow: TextOverflow.ellipsis, attachments.first.filename!,
))), wrapWords: false,
const SizedBox( maxLines: 1,
width: ))),
8, const SizedBox(
), width: 8,
Flexible( ),
child: Flexible(
FittedBox( child: FittedBox(
child: child: Container(
Container( padding: const EdgeInsets.all(3),
padding: decoration:
const EdgeInsets.all(3), box1().copyWith(color: Colors.grey.shade300, boxShadow: []),
decoration: child: InkWell(
box1().copyWith(color: Colors.grey.shade300, boxShadow: []), onTap: () {
child: showDialog(
InkWell( context: context,
onTap: () { builder: (BuildContext context) {
showDialog( return AlertDialog(
context: context, title: Text(
builder: (BuildContext context) { "$eligibilityName Attachments",
return AlertDialog( textAlign: TextAlign.center,
title: Text("$eligibilityName Attachments",textAlign: TextAlign.center,), ),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: attachments.map((e) { children: attachments.map((e) {
String ext = e.filename!.substring(e.filename!.lastIndexOf(".")); String ext = e.filename!
.substring(e.filename!.lastIndexOf("."));
return Column(
children: [ return Column(
Row( children: [
children: [ Row(
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: [ children: [
Flexible(
child: IconButton(
icon: const Icon(
Entypo.right_open_mini,
color: Colors.black87,
),
onPressed: () {},
),
),
const SizedBox(width: 8,),
Flexible( Flexible(
child: IconButton( child: SizedBox(
icon: const Icon( child: ext == '.pdf'
Icons.delete, ? SvgPicture.asset(
color: primary, 'assets/svgs/pdf.svg',
), height: blockSizeVertical * 5,
onPressed: () {}, 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()
], ],
), );
const Divider() }).toList(),
], ));
); });
}).toList(), },
)); child: Row(
}); children: const [
}, Text(" See more.."),
child: Row( Icon(
children: const [ Icons.keyboard_arrow_right,
Text(" See more.."), color: Colors.black54,
Icon( ),
Icons.keyboard_arrow_right, ],
color: Colors.black54,
),
],
),
), ),
), ),
)), ),
], )),
); ],
);
} }
} }

View File

@ -1,3 +1,4 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -31,9 +32,10 @@ class SingleAttachment extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: child:
Text( AutoSizeText(
attachment.filename!, attachment.filename!,
overflow: TextOverflow.ellipsis, wrapWords: false,
maxLines: 1,
), ),
), ),
const SizedBox( const SizedBox(

View File

@ -165,11 +165,11 @@ class EligibilityService {
"category": { "category": {
"id": attachment.category?.id, "id": attachment.category?.id,
"subclass": { "subclass": {
"id": attachment.category?.subclass.id, "id": attachment.category?.subclass?.id,
"name": attachment.category?.subclass.name, "name": attachment.category?.subclass?.name,
"attachment_class": { "attachment_class": {
"id": attachment.category?.subclass.attachmentClass.id, "id": attachment.category?.subclass?.attachmentClass?.id,
"name": attachment.category?.subclass.attachmentClass.name "name": attachment.category?.subclass?.attachmentClass?.name
} }
}, },
"description": attachment.category?.description "description": attachment.category?.description

View File

@ -32,7 +32,7 @@ class AttachmentServices {
return attachmentCategories; return attachmentCategories;
} }
Future<Map<dynamic, dynamic>> attachment( Future<Map<dynamic, dynamic>> attachment(
{required String categoryId, {required String categoryId,
required String module, required String module,
required List<String> paths, required List<String> paths,
@ -74,4 +74,57 @@ class AttachmentServices {
} }
return response; 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!;
}
} }

View File

@ -6,9 +6,9 @@ class Url {
String host() { String host() {
// return '192.168.10.183:3000'; // return '192.168.10.183:3000';
// return 'agusandelnorte.gov.ph'; // return 'agusandelnorte.gov.ph';
// return "192.168.10.219:3000"; return "192.168.10.219:3000";
// return "192.168.10.241"; // // return "192.168.10.241";
return "192.168.10.221:3004"; // return "192.168.10.221:3004";
// return "playweb.agusandelnorte.gov.ph"; // return "playweb.agusandelnorte.gov.ph";
// return 'devapi.agusandelnorte.gov.ph:3004'; // return 'devapi.agusandelnorte.gov.ph:3004';
} }