diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..e6a0ac0 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,93 @@ +PODS: + - barcode_scan2 (0.0.1): + - Flutter + - MTBBarcodeScanner + - SwiftProtobuf + - easy_app_installer (0.0.1): + - Flutter + - Flutter (1.0.0) + - fluttertoast (0.0.2): + - Flutter + - Toast + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - modal_progress_hud_nsn (0.0.1): + - Flutter + - MTBBarcodeScanner (5.0.11) + - package_info_plus (0.4.5): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - permission_handler_apple (9.0.4): + - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite (0.0.2): + - Flutter + - FMDB (>= 2.7.5) + - SwiftProtobuf (1.20.3) + - Toast (4.0.0) + +DEPENDENCIES: + - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) + - easy_app_installer (from `.symlinks/plugins/easy_app_installer/ios`) + - Flutter (from `Flutter`) + - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - modal_progress_hud_nsn (from `.symlinks/plugins/modal_progress_hud_nsn/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) + +SPEC REPOS: + trunk: + - FMDB + - MTBBarcodeScanner + - SwiftProtobuf + - Toast + +EXTERNAL SOURCES: + barcode_scan2: + :path: ".symlinks/plugins/barcode_scan2/ios" + easy_app_installer: + :path: ".symlinks/plugins/easy_app_installer/ios" + Flutter: + :path: Flutter + fluttertoast: + :path: ".symlinks/plugins/fluttertoast/ios" + modal_progress_hud_nsn: + :path: ".symlinks/plugins/modal_progress_hud_nsn/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" + +SPEC CHECKSUMS: + barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 + easy_app_installer: 29abe397da7d86721fee853281202f414373f45c + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde + MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb + package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e + path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce + shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca + sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 + Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 65a38e0..4cf4c30 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,11 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 28FEB91C01FFFF1F3AF03958 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2946B4F99A9B9A85D9A4DC4F /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; @@ -31,7 +32,11 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 24CA4A0209E683A311335098 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 2946B4F99A9B9A85D9A4DC4F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74181747FCF55E0339265087 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 7435055C04EA907D4DF9DEFB /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -49,12 +54,23 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 28FEB91C01FFFF1F3AF03958 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 53E3B75A4BA5D03DDDC74903 /* Pods */ = { + isa = PBXGroup; + children = ( + 74181747FCF55E0339265087 /* Pods-Runner.debug.xcconfig */, + 7435055C04EA907D4DF9DEFB /* Pods-Runner.release.xcconfig */, + 24CA4A0209E683A311335098 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +88,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 53E3B75A4BA5D03DDDC74903 /* Pods */, + B81885F5B040F93E6F30E902 /* Frameworks */, ); sourceTree = ""; }; @@ -98,6 +116,14 @@ path = Runner; sourceTree = ""; }; + B81885F5B040F93E6F30E902 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2946B4F99A9B9A85D9A4DC4F /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -105,12 +131,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 961512EDE7FE1573CFAF92FB /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + CC94AAA4981E9E5E5B1BC9E4 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -171,6 +199,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -183,8 +212,31 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 961512EDE7FE1573CFAF92FB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -197,6 +249,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + CC94AAA4981E9E5E5B1BC9E4 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -288,13 +357,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2WLSMMLG6W; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.unit2; + PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -416,13 +486,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2WLSMMLG6W; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.unit2; + PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -438,13 +509,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 2WLSMMLG6W; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.unit2; + PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 48a1080..097b297 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -24,6 +26,8 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -43,9 +47,5 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/lib/bloc/bloc/user_bloc.dart b/lib/bloc/bloc/user_bloc.dart deleted file mode 100644 index 71dd9eb..0000000 --- a/lib/bloc/bloc/user_bloc.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:barcode_scan2/barcode_scan2.dart'; -import 'package:bloc/bloc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:unit2/model/login_data/user_info/user_data.dart'; -import 'package:unit2/model/login_data/version_info.dart'; -import 'package:unit2/screens/unit2/login/functions/get_app_version.dart'; -import 'package:unit2/sevices/login_service/auth_service.dart'; - -import '../../utils/scanner.dart'; - -part 'user_event.dart'; -part 'user_state.dart'; - -class UserBloc extends Bloc { - UserData? _userData; - VersionInfo? _versionInfo; - UserBloc() : super(UserInitial()) { - // this event is called when opening the app to check if - // there is new app version - on((event, emit) async { - try { - emit(SplashScreen()); - VersionInfo versionInfo = await AuthService.instance.getVersionInfo(); - _versionInfo = versionInfo; - String apkVersion = await getAppVersion(); - emit(VersionLoaded(versionInfo: _versionInfo,apkVersion: apkVersion)); - } catch (e) { - emit(UserError( - message: e.toString(), - )); - } - }); - on((event, emit) { - emit(VersionLoaded(versionInfo: _versionInfo)); - }); - on((event, emit) async { - try { - UserData? userData = await AuthService.instance - .webLogin(username: event.username, password: event.password); - _userData = userData; - emit(UserLoggedIn(userData: _userData)); - } catch (e) { - emit(UserError(message: e.toString())); - } - }); - on((event, emit) async { - try { - UserData? userData = await AuthService.instance - .qrLogin(uuid: event.uuid, password: event.password); - _userData = userData; - emit(UserLoggedIn(userData: _userData)); - } catch (e) { - emit(UserError(message: e.toString())); - } - }); - on((event, emit) { - emit(UserLoggedIn(userData: _userData)); - }); - on((event, emit) async { - ScanResult result = await QRCodeBarCodeScanner.instance.scanner(); - if (result.rawContent.toString().isNotEmpty) { - emit(UuidLoaded(uuid: result.rawContent.toString())); - } - }); - } -} diff --git a/lib/bloc/profile/education/education_bloc.dart b/lib/bloc/profile/education/education_bloc.dart new file mode 100644 index 0000000..bb19420 --- /dev/null +++ b/lib/bloc/profile/education/education_bloc.dart @@ -0,0 +1,25 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/profile/educational_background.dart'; +import 'package:unit2/sevices/profile/education_services.dart'; + +part 'education_event.dart'; +part 'education_state.dart'; + +class EducationBloc extends Bloc { + List educationalBackgrounds = []; + EducationBloc() : super(EducationInitial()) { + on((event, emit) async { + emit(EducationalBackgroundLoadingState()); + try { + List educations = await EducationService.instace + .getEducationalBackground(event.profileId, event.token); + educationalBackgrounds = educations; + emit(EducationalBackgroundLoadedState( + educationalBackground: educationalBackgrounds)); + } catch (e) { + emit(EducationalBackgroundErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/education/education_event.dart b/lib/bloc/profile/education/education_event.dart new file mode 100644 index 0000000..cfe1db7 --- /dev/null +++ b/lib/bloc/profile/education/education_event.dart @@ -0,0 +1,15 @@ +part of 'education_bloc.dart'; + +abstract class EducationEvent extends Equatable { + const EducationEvent(); + + @override + List get props => []; +} +class GetEducationalBackground extends EducationEvent{ + final int profileId; + final String token; + const GetEducationalBackground({required this.profileId, required this.token}); + @override + List get props => [profileId,token]; +} diff --git a/lib/bloc/profile/education/education_state.dart b/lib/bloc/profile/education/education_state.dart new file mode 100644 index 0000000..cc75963 --- /dev/null +++ b/lib/bloc/profile/education/education_state.dart @@ -0,0 +1,29 @@ +part of 'education_bloc.dart'; + +abstract class EducationState extends Equatable { + const EducationState(); + + @override + List get props => []; +} + +class EducationInitial extends EducationState {} + + + +class EducationalBackgroundLoadedState extends EducationState{ + final List educationalBackground; + const EducationalBackgroundLoadedState({required this.educationalBackground}); + @override + List get props => [educationalBackground]; +} + +class EducationalBackgroundErrorState extends EducationState{ + final String message; + const EducationalBackgroundErrorState({required this.message}); + @override + List get props => [message]; +} +class EducationalBackgroundLoadingState extends EducationState{ + +} diff --git a/lib/bloc/profile/eligibility/eligibility_bloc.dart b/lib/bloc/profile/eligibility/eligibility_bloc.dart new file mode 100644 index 0000000..28c0627 --- /dev/null +++ b/lib/bloc/profile/eligibility/eligibility_bloc.dart @@ -0,0 +1,213 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import '../../../model/location/city.dart'; +import '../../../model/location/country.dart'; +import '../../../model/location/provinces.dart'; +import '../../../model/location/region.dart'; +import '../../../model/profile/eligibility.dart'; +import '../../../model/utils/eligibility.dart'; +import '../../../sevices/profile/eligibility_services.dart'; +import '../../../utils/location_utilities.dart'; +import '../../../utils/profile_utilities.dart'; +part 'eligibility_event.dart'; +part 'eligibility_state.dart'; + +class EligibilityBloc extends Bloc { + EligibilityBloc() : super(EligibilityInitial()) { + List? globalCountries; + List? globalRegions; + List globalEligibilities = []; + List eligibilities = []; +//// LOAD ELIGIBILTY + on((event, emit) { + emit(EligibilityLoadingState()); + if (eligibilities.isEmpty) { + GetEligibilities(profileId: event.profileId!, token: event.token!); + } else { + emit(EligibilityLoaded(eligibilities: eligibilities)); + } + }); + + //// DELETE + on((event, emit) async { + try { + final bool success = await EligibilityService.instance.delete( + eligibilityId: event.eligibilityId, + profileId: int.parse(event.profileId), + token: event.token); + if (success) { + eligibilities.removeWhere( + ((EligibityCert element) => element.id == event.eligibilityId)); + emit(DeletedState( + success: success, + )); + } else { + emit(DeletedState(success: success)); + } + } catch (e) { + emit(EligibilityErrorState(message: e.toString())); + } + }); + +//// GET ELIGIBILITY + on((event, emit) async { + try { + if (eligibilities.isNotEmpty) { + emit(EligibilityLoaded(eligibilities: eligibilities)); + } else { + emit(EligibilityLoadingState()); + eligibilities = await EligibilityService.instance + .getEligibilities(event.profileId, event.token); + emit(EligibilityLoaded(eligibilities: eligibilities)); + } + } catch (e) { + emit(EligibilityErrorState(message: e.toString())); + } + }); +//// SHOW EDIT FORM + on((event, emit) async { + try { + if (globalCountries == null) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + if (globalRegions == null) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalEligibilities.isEmpty) { + List eligibilities = + await ProfileUtilities.instance.getEligibilities(); + globalEligibilities = eligibilities; + } + Eligibility currentEligibility = globalEligibilities.firstWhere( + (Eligibility eligibility) => + event.eligibityCert.eligibility!.id == eligibility.id); + bool? isOverseas = event.eligibityCert.overseas; + Country currentCountry = globalCountries!.firstWhere( + (Country country) => + event.eligibityCert.examAddress!.country!.code == country.code); + if (event.eligibityCert.examAddress?.cityMunicipality?.province + ?.region != + null) { + Region currrentRegion = globalRegions!.firstWhere((Region region) => + event.eligibityCert.examAddress!.cityMunicipality!.province! + .region!.code == + region.code); + List provinces = await LocationUtils.instance + .getProvinces(regionCode: currrentRegion.code.toString()); + Province currentProvince = provinces.firstWhere((Province province) => + event.eligibityCert.examAddress!.cityMunicipality!.province! + .code == + province.code); + List cities = await LocationUtils.instance + .getCities(code: currentProvince.code.toString()); + CityMunicipality currentCity = cities.firstWhere( + (CityMunicipality cityMunicipality) => + event.eligibityCert.examAddress!.cityMunicipality!.code == + cityMunicipality.code); + + emit(EditEligibilityState( + currentCity: currentCity, + selectedCountry: currentCountry, + currentProvince: currentProvince, + currentRegion: currrentRegion, + currentEligibility: currentEligibility, + provinces: provinces, + cities: cities, + isOverseas: isOverseas!, + eligibityCert: event.eligibityCert, + countries: globalCountries!, + regions: globalRegions!, + eligibilities: globalEligibilities)); + } else { + emit(EditEligibilityState( + selectedCountry: currentCountry, + currentCity: null, + currentProvince: null, + currentRegion: null, + provinces: null, + cities: null, + currentEligibility: currentEligibility, + isOverseas: isOverseas!, + eligibityCert: event.eligibityCert, + countries: globalCountries!, + regions: globalRegions!, + eligibilities: globalEligibilities)); + } + } catch (e) { + emit(EligibilityErrorState(message: e.toString())); + } + }); + + //// UPDATE + on((event, emit) async { + try { + Map status = await EligibilityService.instance.update( + eligibityCert: event.eligibityCert, + token: event.token, + profileId: int.parse(event.profileId), + oldEligibility: event.oldEligibility); + if (status['success']) { + EligibityCert newEligibility = EligibityCert.fromJson(status['data']); + eligibilities.removeWhere( + (EligibityCert element) => element.id == event.eligibityCert.id); + eligibilities.add(newEligibility); + emit(EligibilityEditedState(response: status)); + } else { + emit(EligibilityEditedState(response: status)); + } + } catch (e) { + emit(EligibilityErrorState(message: e.toString())); + } + }); + //// SHOW ADD FORM + on((event, emit) async { + emit(EligibilityLoadingState()); + if (globalRegions == null) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalEligibilities.isEmpty) { + List eligibilities = + await ProfileUtilities.instance.getEligibilities(); + globalEligibilities = eligibilities; + } + if (globalCountries == null) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + + emit(AddEligibilityState( + eligibilities: globalEligibilities, + regions: globalRegions!, + countries: globalCountries!)); + }); + + //// ADD + on( + (event, emit) async { + try { + Map status = await EligibilityService.instance.add( + eligibityCert: event.eligibityCert, + token: event.token, + profileId: int.parse(event.profileId)); + if (status['success']) { + EligibityCert? eligibityCert = + EligibityCert.fromJson(status['data']); + eligibilities.add(eligibityCert); + emit(EligibilityAddedState(response: status)); + } else { + emit(EligibilityAddedState(response: status)); + } + } catch (e) { + emit(EligibilityErrorState(message: e.toString())); + } + }, + ); + on((event, emit) { + emit(const EligibilityErrorState( + message: "Something went wrong. Please try again")); + }); + } +} diff --git a/lib/bloc/profile/eligibility/eligibility_event.dart b/lib/bloc/profile/eligibility/eligibility_event.dart new file mode 100644 index 0000000..6b83a27 --- /dev/null +++ b/lib/bloc/profile/eligibility/eligibility_event.dart @@ -0,0 +1,72 @@ +part of 'eligibility_bloc.dart'; + +abstract class EligibilityEvent extends Equatable { + const EligibilityEvent(); + + @override + List get props => []; +} + +class ShowAddEligibilityForm extends EligibilityEvent { + +} + +class GetEligibilities extends EligibilityEvent{ + final int profileId; + final String token; + const GetEligibilities({required this.profileId, required this.token}); + @override + List get props => [profileId,token]; +} + +class AddEligibility extends EligibilityEvent{ + final EligibityCert eligibityCert; + final String profileId; + final String token; + const AddEligibility({required this.eligibityCert, required this.profileId, required this.token}); + @override + List get props => [eligibityCert, profileId, token]; +} +class UpdateEligibility extends EligibilityEvent{ + final EligibityCert eligibityCert; + final String profileId; + final String token; + final int oldEligibility; + const UpdateEligibility({required this.eligibityCert, required this.oldEligibility,required this.profileId, required this.token}); + + @override + List get props =>[eligibityCert,profileId,token,oldEligibility]; +} +class LoadEligibility extends EligibilityEvent { + final int? profileId; + final String? token; + const LoadEligibility({ this.profileId, this.token}); + @override + List get props => []; +} + +class ShowEditEligibilityForm extends EligibilityEvent { + final EligibityCert eligibityCert; + const ShowEditEligibilityForm({required this.eligibityCert}); + @override + List get props => []; +} + +class DeleteEligibility extends EligibilityEvent { + final String profileId; + final int eligibilityId; + final String token; + const DeleteEligibility( + { + required this.eligibilityId, + required this.profileId, + required this.token}); + @override + List get props => [ profileId, eligibilityId, token]; +} + +class CallErrorState extends EligibilityEvent{ + +} + + diff --git a/lib/bloc/profile/eligibility/eligibility_state.dart b/lib/bloc/profile/eligibility/eligibility_state.dart new file mode 100644 index 0000000..3b57f6d --- /dev/null +++ b/lib/bloc/profile/eligibility/eligibility_state.dart @@ -0,0 +1,93 @@ +part of 'eligibility_bloc.dart'; + +abstract class EligibilityState extends Equatable { + const EligibilityState(); + + @override + List get props => []; +} + +class EligibilityInitial extends EligibilityState {} + + +class EditEligibilityState extends EligibilityState { + final EligibityCert eligibityCert; + final List eligibilities; + final List countries; + final List regions; + final List? provinces; + final List? cities; + final bool isOverseas; + final Eligibility currentEligibility; + final Region? currentRegion; + final Province? currentProvince; + final CityMunicipality? currentCity; + final Country selectedCountry; + const EditEligibilityState({ + required this.provinces, + required this.cities, + required this.currentProvince, + required this.currentCity, + required this.currentRegion, + required this.currentEligibility, + required this.isOverseas, + required this.eligibityCert, + required this.eligibilities, + required this.countries, + required this.regions, + required this.selectedCountry, + }); + @override + List get props => + [isOverseas, eligibityCert, eligibilities, regions, countries]; +} + +class DeletedState extends EligibilityState { + final bool success; + const DeletedState({required this.success}); + @override + List get props => [success]; +} + +class AddEligibilityState extends EligibilityState { + final List eligibilities; + final List countries; + final List regions; + const AddEligibilityState({ + required this.eligibilities, + required this.countries, + required this.regions, + }); + @override + List get props => [eligibilities,countries,regions]; +} +class EligibilityEditedState extends EligibilityState{ + final Map response; + const EligibilityEditedState({required this.response}); + @override + List get props =>[ response]; +} + +class EligibilityAddedState extends EligibilityState{ + final Map response; + + const EligibilityAddedState({ required this.response}); + @override + List get props =>[response]; +} +class EligibilityLoadingState extends EligibilityState{ + +} +class EligibilityErrorState extends EligibilityState{ + final String message; + const EligibilityErrorState({required this.message}); + @override + List get props =>[message]; +} + +class EligibilityLoaded extends EligibilityState { + final List eligibilities; + const EligibilityLoaded({required this.eligibilities}); + @override + List get props => [eligibilities]; +} diff --git a/lib/bloc/profile/family/family_bloc.dart b/lib/bloc/profile/family/family_bloc.dart new file mode 100644 index 0000000..30db4da --- /dev/null +++ b/lib/bloc/profile/family/family_bloc.dart @@ -0,0 +1,24 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/profile/family_services.dart'; + +import '../../../model/profile/family_backround.dart'; + +part 'family_event.dart'; +part 'family_state.dart'; + +class FamilyBloc extends Bloc { + FamilyBloc() : super(FamilyInitial()) { + List families = []; + on((event, emit) async{ + emit(FamilyLoadingState()); + try{ + List family = await FamilyService.instance.getFamilies(event.profileId, event.token); + families = family; + emit(FamilyLoaded(families: families)); + }catch(e){ + emit(FamilyErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/family/family_event.dart b/lib/bloc/profile/family/family_event.dart new file mode 100644 index 0000000..366091c --- /dev/null +++ b/lib/bloc/profile/family/family_event.dart @@ -0,0 +1,17 @@ +part of 'family_bloc.dart'; + +abstract class FamilyEvent extends Equatable { + const FamilyEvent(); + + @override + List get props => []; +} + +class GetFamilies extends FamilyEvent{ + final int profileId; + final String token; + const GetFamilies({required this.profileId, required this.token}); + + @override + List get props => [profileId,token]; +} diff --git a/lib/bloc/profile/family/family_state.dart b/lib/bloc/profile/family/family_state.dart new file mode 100644 index 0000000..7ac4003 --- /dev/null +++ b/lib/bloc/profile/family/family_state.dart @@ -0,0 +1,28 @@ +part of 'family_bloc.dart'; + +abstract class FamilyState extends Equatable { + const FamilyState(); + + @override + List get props => []; +} + +class FamilyInitial extends FamilyState {} + +class FamilyLoaded extends FamilyState{ + final List families; + const FamilyLoaded({required this.families}); + + @override + List get props => [families]; +} + +class FamilyErrorState extends FamilyState{ + final String message; + const FamilyErrorState({required this.message}); + @override + List get props => [message]; +} +class FamilyLoadingState extends FamilyState{ + +} diff --git a/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart b/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart new file mode 100644 index 0000000..de39dac --- /dev/null +++ b/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart @@ -0,0 +1,28 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/profile/learningDevelopment_service.dart'; + +import '../../../model/profile/learning_development.dart'; + +part 'learning_development_event.dart'; +part 'learning_development_state.dart'; + +class LearningDevelopmentBloc + extends Bloc { + LearningDevelopmentBloc() : super(LearningDevelopmentInitial()) { + List learningsAndDevelopments; + on((event, emit) async { + // try { + emit(LearningDevelopmentLoadingState()); + List learnings = await LearningDevelopmentServices + .instance + .getLearningDevelopments(event.profileId, event.token); + learningsAndDevelopments = learnings; + emit(LearningDevelopmentLoadedState( + learningsAndDevelopment: learningsAndDevelopments)); + // } catch (e) { + // emit(LeaningDevelopmentErrorState(message: e.toString())); + // } + }); + } +} diff --git a/lib/bloc/profile/learningDevelopment/learning_development_event.dart b/lib/bloc/profile/learningDevelopment/learning_development_event.dart new file mode 100644 index 0000000..9aedc7d --- /dev/null +++ b/lib/bloc/profile/learningDevelopment/learning_development_event.dart @@ -0,0 +1,17 @@ +part of 'learning_development_bloc.dart'; + +abstract class LearningDevelopmentEvent extends Equatable { + const LearningDevelopmentEvent(); + + @override + List get props => []; +} + +class GetLearningDevelopments extends LearningDevelopmentEvent { + final int profileId; + final String token; + const GetLearningDevelopments({required this.profileId, required this.token}); + + @override + List get props => [profileId, token]; +} diff --git a/lib/bloc/profile/learningDevelopment/learning_development_state.dart b/lib/bloc/profile/learningDevelopment/learning_development_state.dart new file mode 100644 index 0000000..c4b2337 --- /dev/null +++ b/lib/bloc/profile/learningDevelopment/learning_development_state.dart @@ -0,0 +1,28 @@ +part of 'learning_development_bloc.dart'; + +abstract class LearningDevelopmentState extends Equatable { + const LearningDevelopmentState(); + + @override + List get props => []; +} + +class LearningDevelopmentInitial extends LearningDevelopmentState {} + +class LearningDevelopmentLoadedState extends LearningDevelopmentState{ + final List learningsAndDevelopment; + const LearningDevelopmentLoadedState({required this.learningsAndDevelopment}); + @override + List get props => [learningsAndDevelopment]; +} + +class LeaningDevelopmentErrorState extends LearningDevelopmentState{ + final String message; + const LeaningDevelopmentErrorState({required this.message}); + @override + List get props => [message]; +} + +class LearningDevelopmentLoadingState extends LearningDevelopmentState{ + +} diff --git a/lib/bloc/profile/other_information/hobbies/hoobies_bloc.dart b/lib/bloc/profile/other_information/hobbies/hoobies_bloc.dart new file mode 100644 index 0000000..fd8d923 --- /dev/null +++ b/lib/bloc/profile/other_information/hobbies/hoobies_bloc.dart @@ -0,0 +1,116 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/skillshobbies_services.dart'; + +import '../../../../model/profile/other_information/skills_and_hobbies.dart'; + +part 'hoobies_event.dart'; +part 'hoobies_state.dart'; + +class HoobiesBloc extends Bloc { + HoobiesBloc() : super(HoobiesInitial()) { + List skillsAndHobbies = []; + List allSkillsAndHobbies = []; + List mySkillsAndHobbies = []; + on((event, emit) async { + emit(HobbiesLoadingState()); + try { + List hobbies = await SkillsHobbiesServices.instance + .getSkillsHobbies(event.profileId, event.token); + skillsAndHobbies = hobbies; + emit(HobbiesLoadedState(skillsAndHobbies: skillsAndHobbies)); + } catch (e) { + emit(HobbiesErrorState(message: e.toString())); + } + }); + on((event,emit){ + skillsAndHobbies = event.skillsHobbies; + emit(HobbiesLoadedState(skillsAndHobbies: skillsAndHobbies)); + }); + ////SHOW ADD FORM + on((event, emit) async { + emit(HobbiesLoadingState()); + try { + ////get all skills and hobbies + if (allSkillsAndHobbies.isEmpty) { + allSkillsAndHobbies = + await SkillsHobbiesServices.instance.getAllSkillsHobbies(); + } + for (var element in skillsAndHobbies) { + mySkillsAndHobbies.add(element.name!); + } + allSkillsAndHobbies.sort((a, b) => a.name!.compareTo(b.name!)); + emit(AddHobbySkillState( + mySkillsAndHobbiesString: mySkillsAndHobbies, + allSkillsAndHobbies: allSkillsAndHobbies, + mySkillsAndHobbiesObject: skillsAndHobbies)); + } catch (e) { + emit(HobbiesErrorState(message: e.toString())); + } + }); + ////GET ADDED SKILLS HOBBIES + on((event, emit) { + emit(HobbiesLoadingState()); + List added = event.addedHobbiesSkills.split(","); + + for (var element in added) { + if (element.isNotEmpty) { + SkillsHobbies newSkillsHobbies = + SkillsHobbies(id: null, name: element.toUpperCase()); + skillsAndHobbies.add(newSkillsHobbies); + allSkillsAndHobbies.add(newSkillsHobbies); + } + } + for (var element in skillsAndHobbies) { + mySkillsAndHobbies.add(element.name!); + } + allSkillsAndHobbies.sort((a, b) => a.name!.compareTo(b.name!)); + emit(AddHobbySkillState( + mySkillsAndHobbiesString: mySkillsAndHobbies, + allSkillsAndHobbies: allSkillsAndHobbies, + mySkillsAndHobbiesObject: skillsAndHobbies)); + }); + ////SHOW ADD MODAL + on((event, emit) { + emit(ShowAddModalState()); + }); + + //// ADD + on((event, emit) async { + emit(HobbiesLoadingState()); + Map response = await SkillsHobbiesServices.instance.add( + skillsHobbies: event.skillsHobbies, + profileId: event.profileId, + token: event.token); + List newSkillsHobbies = []; + if (response['success']) { + if (response['data']['skill_hobby'] != null) { + for (var element in response['data']['skill_hobby']) { + newSkillsHobbies.add(SkillsHobbies.fromJson(element)); + } + } + skillsAndHobbies = newSkillsHobbies; + emit(HobbiesAndSkillsAddedState( + mySkillsAndHobbies: skillsAndHobbies, status: response)); + } else { + emit(HobbiesAndSkillsAddedState( + mySkillsAndHobbies: skillsAndHobbies, status: response)); + } + }); + ////DELETE + on((event,emit)async{ + emit(HobbiesLoadingState()); + // try{ + bool success = await SkillsHobbiesServices.instance.delete(profileId: event.profileId, token: event.token, skillsHobbies: event.skillsHobbies); + if(success){ + skillsAndHobbies.removeWhere((element) => element.id == event.skillsHobbies[0].id); + emit(HobbiesAndSkillsDeletedState(skillsHobbies: skillsAndHobbies, success: success)); + }else{ + emit(HobbiesAndSkillsDeletedState(skillsHobbies: skillsAndHobbies, success: success)); + } + // }catch(e){ + // emit (HobbiesErrorState(message: e.toString())); + // } + }); + } +} diff --git a/lib/bloc/profile/other_information/hobbies/hoobies_event.dart b/lib/bloc/profile/other_information/hobbies/hoobies_event.dart new file mode 100644 index 0000000..7a9abb5 --- /dev/null +++ b/lib/bloc/profile/other_information/hobbies/hoobies_event.dart @@ -0,0 +1,52 @@ +part of 'hoobies_bloc.dart'; + +abstract class HobbiesEvent extends Equatable { + const HobbiesEvent(); + + @override + List get props => []; +} + +class GetSkillsHobbies extends HobbiesEvent{ + final int profileId; + final String token; + const GetSkillsHobbies({required this.profileId, required this.token}); + @override + List get props => [profileId,token]; +} +class ShowHobbySkillAddForm extends HobbiesEvent{ + + const ShowHobbySkillAddForm(); + +} +class AddHobbyAndSkills extends HobbiesEvent{ + final int profileId; + final String token; + final List skillsHobbies; + const AddHobbyAndSkills({required this.profileId,required this.token, required this.skillsHobbies}); + @override + List get props => [profileId,token]; +} + +class GetAddedHobbiesSkills extends HobbiesEvent{ + final String addedHobbiesSkills; + + + const GetAddedHobbiesSkills({required this.addedHobbiesSkills}); + @override + List get props => [addedHobbiesSkills]; +} +class ShowAddModal extends HobbiesEvent{ + +} + +class LoadHobbiesSkills extends HobbiesEvent{ + final List skillsHobbies; + const LoadHobbiesSkills({required this.skillsHobbies}); +} +class DeleteSkillHobbies extends HobbiesEvent{ + final int profileId; + final String token; + final List skillsHobbies; + const DeleteSkillHobbies({required this.profileId, required this.skillsHobbies, required this.token}); +} \ No newline at end of file diff --git a/lib/bloc/profile/other_information/hobbies/hoobies_state.dart b/lib/bloc/profile/other_information/hobbies/hoobies_state.dart new file mode 100644 index 0000000..858fd3a --- /dev/null +++ b/lib/bloc/profile/other_information/hobbies/hoobies_state.dart @@ -0,0 +1,58 @@ +part of 'hoobies_bloc.dart'; + +abstract class HobbiesState extends Equatable { + const HobbiesState(); + + @override + List get props => []; +} + +class HoobiesInitial extends HobbiesState {} + +class HobbiesLoadedState extends HobbiesState{ + final List skillsAndHobbies; + const HobbiesLoadedState({required this.skillsAndHobbies}); + @override + List get props => [skillsAndHobbies]; +} +class HobbiesErrorState extends HobbiesState{ + final String message; + const HobbiesErrorState({required this.message}); + + @override + List get props => [message]; + +} +class AddHobbySkillState extends HobbiesState{ + final List mySkillsAndHobbiesString; + final List allSkillsAndHobbies; + final List mySkillsAndHobbiesObject; + + const AddHobbySkillState({required this.mySkillsAndHobbiesString,required this.allSkillsAndHobbies,required this.mySkillsAndHobbiesObject}); + @override + List get props => [mySkillsAndHobbiesString,allSkillsAndHobbies,mySkillsAndHobbiesObject]; +} + +class HobbiesLoadingState extends HobbiesState{ + +} + +//// show add modal for adding new skills and hobbies +class ShowAddModalState extends HobbiesState{ + +} +//// hobbies and skills already added +class HobbiesAndSkillsAddedState extends HobbiesState{ + final List mySkillsAndHobbies; + final Map status; + const HobbiesAndSkillsAddedState({required this.mySkillsAndHobbies, required this.status}); + @override + List get props => [mySkillsAndHobbies,status]; +} +class HobbiesAndSkillsDeletedState extends HobbiesState{ + final bool success; + final List skillsHobbies; + const HobbiesAndSkillsDeletedState({required this.skillsHobbies,required this.success}); +} + + diff --git a/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart new file mode 100644 index 0000000..83a5c1e --- /dev/null +++ b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart @@ -0,0 +1,170 @@ +import 'dart:math'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/profile/non_academic_services.dart'; + +import '../../../../model/profile/other_information/non_acedimic_recognition.dart'; +import '../../../../model/utils/agency.dart'; +import '../../../../model/utils/category.dart'; +import '../../../../utils/profile_utilities.dart'; + +part 'non_academic_recognition_event.dart'; +part 'non_academic_recognition_state.dart'; + +class NonAcademicRecognitionBloc + extends Bloc { + NonAcademicRecognitionBloc() : super(NonAcademicRecognitionInitial()) { + List nonAcademicRecognitions = []; + List agencies = []; + List agencyCategory = []; + ////GET + on((event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + if (nonAcademicRecognitions.isEmpty) { + List recognitions = + await NonAcademicRecognitionServices.instance + .getNonAcademicRecognition(event.profileId!, event.token!); + nonAcademicRecognitions = recognitions; + emit(NonAcademicRecognitionLoadedState( + nonAcademicRecognition: nonAcademicRecognitions)); + } else { + emit(NonAcademicRecognitionLoadedState( + nonAcademicRecognition: nonAcademicRecognitions)); + } + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }); + + ////LOAD + on((event,emit){ + nonAcademicRecognitions = event.nonAcademicRecognitions; + emit(NonAcademicRecognitionLoadedState(nonAcademicRecognition: nonAcademicRecognitions)); + }); +////SHOW ADD FORM + on( + (event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + if (agencyCategory.isEmpty) { + List newAgencyCategories = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = newAgencyCategories; + } + emit(AddNonAcademeRecognitionState( + agencies: agencies, agencyCategories: agencyCategory)); + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }, + ); + ////SHOW EDIT FORM + on((event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + if (agencyCategory.isEmpty) { + List newAgencyCategories = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = newAgencyCategories; + } + emit(EditNonAcademeRecognitionState( + agencies: agencies, + agencyCategories: agencyCategory, + nonAcademicRecognition: event.nonAcademicRecognition)); + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }); + ////ADD + on((event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + Map status = + await NonAcademicRecognitionServices.instance.add( + token: event.token, + profileId: event.profileId, + nonAcademicRecognition: event.nonAcademicRecognition); + if (status['success']) { + NonAcademicRecognition nonAcademicRecognition = + NonAcademicRecognition.fromJson(status['data']); + nonAcademicRecognitions.add(nonAcademicRecognition); + emit(NonAcademeRecognitionAddedState( + response: status, + nonAcademicRecognition: nonAcademicRecognitions)); + } else { + emit(NonAcademeRecognitionAddedState( + response: status, + nonAcademicRecognition: nonAcademicRecognitions)); + } + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }); +////EDIT + on((event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + Map status = + await NonAcademicRecognitionServices.instance.update( + nonAcademicRecognition: event.nonAcademicRecognition, + profileId: event.profileId, + token: event.token); + if (status['success']) { + NonAcademicRecognition newNonAcademeRecognition = + NonAcademicRecognition.fromJson(status['data']); + nonAcademicRecognitions.removeWhere( + (element) => element.id == event.nonAcademicRecognition.id); + nonAcademicRecognitions.add(newNonAcademeRecognition); + emit(NonAcademeRecognitionEditedState( + nonAcademicRecognitions: nonAcademicRecognitions, + response: status)); + }else{ + emit(NonAcademeRecognitionEditedState( + nonAcademicRecognitions: nonAcademicRecognitions, + response: status)); + } + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }); + + ////DELETE + on((event, emit) async { + emit(NonAcademicRecognitionLoadingState()); + try { + final bool success = await NonAcademicRecognitionServices.instance + .delete( + title: event.nonAcademicRecognition.title!, + id: event.nonAcademicRecognition.id!, + token: event.token, + profileId: event.profileId); + if (success) { + event.nonAcademicRecognitions.removeWhere( + (element) => element.id == event.nonAcademicRecognition.id); + nonAcademicRecognitions = event.nonAcademicRecognitions; + emit(NonAcademeRecognitionDeletedState( + nonAcademicRecognitions: nonAcademicRecognitions, + success: success)); + } else { + emit(NonAcademeRecognitionDeletedState( + nonAcademicRecognitions: nonAcademicRecognitions, + success: success)); + } + } catch (e) { + emit(NonAcademicRecognitionErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_event.dart b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_event.dart new file mode 100644 index 0000000..fdb2c6d --- /dev/null +++ b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_event.dart @@ -0,0 +1,67 @@ +part of 'non_academic_recognition_bloc.dart'; + +abstract class NonAcademicRecognitionEvent extends Equatable { + const NonAcademicRecognitionEvent(); + + @override + List get props => []; +} +//// GET EVENT +class GetNonAcademicRecognition extends NonAcademicRecognitionEvent{ + final int? profileId; + final String? token; + const GetNonAcademicRecognition({ this.profileId, this.token}); +} +////LOAD EVENT +class LoadNonAcademeRecognition extends NonAcademicRecognitionEvent{ + final List nonAcademicRecognitions; + const LoadNonAcademeRecognition({required this.nonAcademicRecognitions}); + @override + List get props => [nonAcademicRecognitions]; +} + +////SHOW ADD FORM EVENT +class ShowAddNonAcademeRecognitionForm extends NonAcademicRecognitionEvent{ + +} + +//// SHOW EDIT FORM +class ShowEditNonAcademicRecognitionForm extends NonAcademicRecognitionEvent{ + final NonAcademicRecognition nonAcademicRecognition; + const ShowEditNonAcademicRecognitionForm({required this.nonAcademicRecognition}); + @override + List get props => [nonAcademicRecognition]; +} + +//// ADD EVENT +class AddNonAcademeRecognition extends NonAcademicRecognitionEvent{ + final int profileId; + final String token; + final NonAcademicRecognition nonAcademicRecognition; + const AddNonAcademeRecognition({required this.nonAcademicRecognition, required this.profileId, required this.token}); + @override + List get props => [nonAcademicRecognition,profileId,token]; +} + +//// EDIT EVENT +class EditNonAcademeRecognition extends NonAcademicRecognitionEvent{ + final NonAcademicRecognition nonAcademicRecognition; + final String token; + final int profileId; + const EditNonAcademeRecognition({required this.nonAcademicRecognition, required this.profileId, required this.token}); + @override + List get props => [nonAcademicRecognition,profileId,token]; +} + +//// DELETE EVENT +class DeleteNonAcademeRecognition extends NonAcademicRecognitionEvent{ + final int profileId; + final String token; + final List nonAcademicRecognitions; + final NonAcademicRecognition nonAcademicRecognition; + const DeleteNonAcademeRecognition({required this.nonAcademicRecognitions, required this.nonAcademicRecognition,required this.profileId,required this.token}); + @override + List get props => [profileId,token,nonAcademicRecognition,nonAcademicRecognitions]; + +} + diff --git a/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_state.dart b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_state.dart new file mode 100644 index 0000000..f09e17e --- /dev/null +++ b/lib/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_state.dart @@ -0,0 +1,79 @@ +part of 'non_academic_recognition_bloc.dart'; + +abstract class NonAcademicRecognitionState extends Equatable { + const NonAcademicRecognitionState(); + + @override + List get props => []; +} + +class NonAcademicRecognitionInitial extends NonAcademicRecognitionState {} + +////LOADING STATE +class NonAcademicRecognitionLoadingState extends NonAcademicRecognitionState {} + +////LOADED STATE +class NonAcademicRecognitionLoadedState extends NonAcademicRecognitionState { + final List nonAcademicRecognition; + const NonAcademicRecognitionLoadedState( + {required this.nonAcademicRecognition}); + @override + List get props => []; +} + +////DELETED STATE +class NonAcademeRecognitionDeletedState extends NonAcademicRecognitionState { + final List nonAcademicRecognitions; + final bool success; + const NonAcademeRecognitionDeletedState( + {required this.nonAcademicRecognitions, required this.success}); + @override + List get props => [nonAcademicRecognitions, success]; +} + +class NonAcademeRecognitionEditedState extends NonAcademicRecognitionState{ + final List nonAcademicRecognitions; + final Map response; + const NonAcademeRecognitionEditedState( + {required this.nonAcademicRecognitions, required this.response}); + @override + List get props => [nonAcademicRecognitions, response]; +} + +////ADDED STATE +class NonAcademeRecognitionAddedState extends NonAcademicRecognitionState { + final List nonAcademicRecognition; + final Map response; + const NonAcademeRecognitionAddedState( + {required this.nonAcademicRecognition, required this.response}); + @override + List get props => [nonAcademicRecognition, response]; +} + +////ADDING STATE +class AddNonAcademeRecognitionState extends NonAcademicRecognitionState { + final List agencies; + final List agencyCategories; + const AddNonAcademeRecognitionState( + {required this.agencies, required this.agencyCategories}); + @override + List get props => [agencies, agencyCategories]; +} + +class EditNonAcademeRecognitionState extends NonAcademicRecognitionState { + final List agencies; + final List agencyCategories; + final NonAcademicRecognition nonAcademicRecognition; + const EditNonAcademeRecognitionState({required this.agencies, required this.agencyCategories,required this.nonAcademicRecognition}); + @override + List get props => [agencies, agencyCategories,nonAcademicRecognition]; +} + +////ERROR STATE +class NonAcademicRecognitionErrorState extends NonAcademicRecognitionState { + final String message; + const NonAcademicRecognitionErrorState({required this.message}); + + @override + List get props => []; +} diff --git a/lib/bloc/profile/other_information/org_membership/organization_membership_bloc.dart b/lib/bloc/profile/other_information/org_membership/organization_membership_bloc.dart new file mode 100644 index 0000000..fee8447 --- /dev/null +++ b/lib/bloc/profile/other_information/org_membership/organization_membership_bloc.dart @@ -0,0 +1,83 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/category.dart'; +import 'package:unit2/sevices/profile/orgmembership_services.dart'; +import 'package:unit2/utils/profile_utilities.dart'; + +import '../../../../model/profile/other_information/organization_memberships.dart'; + +part 'organization_membership_event.dart'; +part 'organization_membership_state.dart'; + +class OrganizationMembershipBloc extends Bloc { + List agencies = []; + List agencyCategory = []; + OrganizationMembershipBloc() : super(OrganizationMembershipInitial()) { + List organizationMemberships=[]; + on((event, emit) async{ + emit(OrgmembershipLoadingState()); + try{ + if(organizationMemberships.isEmpty){ + List orgs = await OrganizationMembershipServices.instance.getOrgMemberships(event.profileId!, event.token!); + organizationMemberships = orgs; + } + + emit(OrganizationMembershipLoaded(orgMemberships: organizationMemberships)); + }catch(e){ + OrganizationMembershipErrorState(message: e.toString()); + } + }); + on((event,emit){ + emit(OrganizationMembershipLoaded(orgMemberships: organizationMemberships)); + }); + + ////SHOW ADD ORG MEMBERSHIP FORM + on((event,emit)async{ + emit(OrgmembershipLoadingState()); + try{ + if(agencies.isEmpty){ + List newAgencies = await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + if(agencyCategory.isEmpty){ + ListnewAgencyCategories = await ProfileUtilities.instance.agencyCategory(); + agencyCategory = newAgencyCategories; + } + emit(AddOrgMembershipState(agencies: agencies, agencyCategories: agencyCategory)); + }catch(e){ + emit(OrganizationMembershipErrorState(message: e.toString())); + } + }); + //// ADD ORGMEMBERSHIP + on((event,emit)async{ + try{ + Map status= await OrganizationMembershipServices.instance.add(agency: event.agency, token: event.token, profileId: event.profileId.toString()); + if(status["success"]){ + OrganizationMembership organizationMembership = OrganizationMembership.fromJson(status["data"]); + organizationMemberships.add(organizationMembership); + emit(OrgMembershipAddedState( response: status)); + }else{ + emit(OrgMembershipAddedState( response: status)); + } + }catch(e){ + emit(OrganizationMembershipErrorState(message: e.toString())); + } + }); + ////DELETE ORGMEMBERSHIP + on((event,emit)async{ + emit(OrgmembershipLoadingState()); + try{ + final bool success = await OrganizationMembershipServices.instance.delete(agency: event.org.agency!, profileId: event.profileId, token: event.token); + if(success){ + organizationMemberships.removeWhere((element) => element.agency!.id == event.org.agency!.id ); + emit(OrgMembershipDeletedState(success: success)); + }else{ + emit(OrgMembershipDeletedState(success: success)); + } + }catch(e){ + emit(OrganizationMembershipErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/other_information/org_membership/organization_membership_event.dart b/lib/bloc/profile/other_information/org_membership/organization_membership_event.dart new file mode 100644 index 0000000..a85a91a --- /dev/null +++ b/lib/bloc/profile/other_information/org_membership/organization_membership_event.dart @@ -0,0 +1,43 @@ +part of 'organization_membership_bloc.dart'; + +abstract class OrganizationMembershipEvent extends Equatable { + const OrganizationMembershipEvent(); + + @override + List get props => []; +} + +class LoadOrganizationMemberships extends OrganizationMembershipEvent{ + + @override + List get props => []; +} + +class GetOrganizationMembership extends OrganizationMembershipEvent{ + final int? profileId; + final String? token; + const GetOrganizationMembership({this.profileId, this.token}); + +} +class ShowAddOrgMembershipForm extends OrganizationMembershipEvent{ + +} +class AddOrgMembership extends OrganizationMembershipEvent{ + final int profileId; + final String token; + final Agency agency; + const AddOrgMembership({required this.agency, required this.profileId, required this.token}); + @override + List get props => [profileId,token,agency]; +} + +class DeleteOrgMemberShip extends OrganizationMembershipEvent{ + final int profileId; + final String token; + final OrganizationMembership org; + + const DeleteOrgMemberShip({required this.profileId, required this.token, required this.org,}); + @override + List get props => [profileId,token,org]; + +} diff --git a/lib/bloc/profile/other_information/org_membership/organization_membership_state.dart b/lib/bloc/profile/other_information/org_membership/organization_membership_state.dart new file mode 100644 index 0000000..0680c75 --- /dev/null +++ b/lib/bloc/profile/other_information/org_membership/organization_membership_state.dart @@ -0,0 +1,46 @@ +part of 'organization_membership_bloc.dart'; + +abstract class OrganizationMembershipState extends Equatable { + const OrganizationMembershipState(); + + @override + List get props => []; +} + +class OrganizationMembershipInitial extends OrganizationMembershipState {} + +class OrganizationMembershipLoaded extends OrganizationMembershipState{ + final ListorgMemberships; + const OrganizationMembershipLoaded({required this.orgMemberships}); + @override + List get props => [orgMemberships]; +} + +class OrganizationMembershipErrorState extends OrganizationMembershipState{ + final String message; + const OrganizationMembershipErrorState({required this.message}); + @override + List get props => [message]; +} + +class OrgmembershipLoadingState extends OrganizationMembershipState{ + +} +class OrgMembershipDeletedState extends OrganizationMembershipState{ + final bool success; + const OrgMembershipDeletedState({ required this.success}); + @override + List get props => [success]; +} +class OrgMembershipAddedState extends OrganizationMembershipState{ + final Map response; + const OrgMembershipAddedState({required this.response}); + @override + List get props => [response]; +} + +class AddOrgMembershipState extends OrganizationMembershipState{ +final List agencies; +final List agencyCategories; +const AddOrgMembershipState({required this.agencies, required this.agencyCategories}); +} diff --git a/lib/bloc/profile/primary_information/address/address_bloc.dart b/lib/bloc/profile/primary_information/address/address_bloc.dart new file mode 100644 index 0000000..30195bc --- /dev/null +++ b/lib/bloc/profile/primary_information/address/address_bloc.dart @@ -0,0 +1,22 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; + +import '../../../../model/profile/basic_information/adress.dart'; + +part 'address_event.dart'; +part 'address_state.dart'; + +class AddressBloc extends Bloc { + AddressBloc() : super(AddressInitial()) { + List addresses = []; + on((event, emit) { + emit(AddressLoadingState()); + try{ + addresses = event.addresses; + emit(AddressLoadedState(addresses: addresses)); + }catch(e){ + emit(AddressErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/primary_information/address/address_event.dart b/lib/bloc/profile/primary_information/address/address_event.dart new file mode 100644 index 0000000..1f4ba71 --- /dev/null +++ b/lib/bloc/profile/primary_information/address/address_event.dart @@ -0,0 +1,15 @@ +part of 'address_bloc.dart'; + +abstract class AddressEvent extends Equatable { + const AddressEvent(); + + @override + List get props => []; +} + +class GetAddress extends AddressEvent{ + final List addresses; + const GetAddress({required this.addresses}); + @override + List get props => [addresses]; +} diff --git a/lib/bloc/profile/primary_information/address/address_state.dart b/lib/bloc/profile/primary_information/address/address_state.dart new file mode 100644 index 0000000..fcdeea3 --- /dev/null +++ b/lib/bloc/profile/primary_information/address/address_state.dart @@ -0,0 +1,27 @@ +part of 'address_bloc.dart'; + +abstract class AddressState extends Equatable { + const AddressState(); + + @override + List get props => []; +} + +class AddressInitial extends AddressState {} + +class AddressLoadedState extends AddressState{ + final List addresses; + const AddressLoadedState({required this.addresses}); + @override + List get props => [addresses]; +} + +class AddressErrorState extends AddressState{ + final String message; + const AddressErrorState({required this.message}); + @override + List get props => [message]; +} +class AddressLoadingState extends AddressState{ + +} diff --git a/lib/bloc/profile/primary_information/contact/contact_bloc.dart b/lib/bloc/profile/primary_information/contact/contact_bloc.dart new file mode 100644 index 0000000..5753c70 --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_bloc.dart @@ -0,0 +1,143 @@ +import 'dart:math'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:unit2/sevices/profile/contact_services.dart'; +import 'package:unit2/utils/profile_utilities.dart'; + +import '../../../../model/profile/basic_information/contact_information.dart'; + +part 'contact_event.dart'; +part 'contact_state.dart'; + +class ContactBloc extends Bloc { + ContactBloc() : super(ContactInitial()) { + List contactInformations = []; + List serviceTypes = []; + //// get all contacts + on((event, emit) { + emit(ContactLoadingState()); + try { + contactInformations = event.contactInformations; + emit(ContactLoadedState(contactInformation: contactInformations)); + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + //// Load Contacts + on((event, emit) { + emit(ContactLoadedState(contactInformation: contactInformations)); + }); + //// show add form + on((event, emit) async { + try { + emit(ContactLoadingState()); + if (serviceTypes.isEmpty) { + serviceTypes = await ProfileUtilities.instance.getServiceType(); + } + emit(ContactAddingState(serviceTypes: serviceTypes)); + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + ///// Show edit form + on((event, emit) async { + ServiceType serviceType; + List commServiceProvivers; + CommService serviceProvider; + try{ + if (serviceTypes.isEmpty) { + serviceTypes = await ProfileUtilities.instance.getServiceType(); + } + serviceType = serviceTypes.firstWhere((ServiceType element) { + return element.id == event.contactInfo.commService!.serviceType!.id; + }); + commServiceProvivers = await ContactService.instance + .getServiceProvider(serviceTypeId: serviceType.id!); + serviceProvider = commServiceProvivers.firstWhere((CommService element) => + element.id == event.contactInfo.commService!.id); + emit(ContactEditingState( + serviceTypes: serviceTypes, + selectedServiceType: serviceType, + commServiceProviders: commServiceProvivers, + selectedProvider: serviceProvider, + contactInfo: event.contactInfo)); + }catch(e){ + emit(ContactErrorState(message: e.toString())); + } + }); + ////edit contact + on((event, emit) async { + try { + Map responseStatus = await ContactService.instance + .update( + profileId: event.profileId, + token: event.token, + contactInfo: event.contactInfo); + if (responseStatus['success']) { + ContactInfo contactInfo = + ContactInfo.fromJson(responseStatus['data']['contact_info']); + contactInformations.removeWhere( + (ContactInfo element) => element.id == event.contactInfo.id); + contactInformations.add(contactInfo); + emit(ContactEditedState( + + response: responseStatus)); + } else { + emit(ContactEditedState( + + response: responseStatus)); + } + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + + //// add contact + + on((event, emit) async { + try { + Map responseStatus = await ContactService.instance + .add( + profileId: event.profileId, + token: event.token, + contactInfo: event.contactInfo); + if (responseStatus['success']) { + ContactInfo contactInfo = + ContactInfo.fromJson(responseStatus['data']['contact_info']); + contactInformations.add(contactInfo); + emit(ContactEditedState( + + response: responseStatus)); + } else { + emit(ContactEditedState( + + response: responseStatus)); + } + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + //// delete contact + on((event, emit) async { + try { + final bool success = await ContactService.instance.deleteContact( + profileId: event.profileId, + token: event.token, + contactInfo: event.contactInfo); + if (success) { + contactInformations + .removeWhere((element) => element.id == event.contactInfo.id); + emit(ContactDeletedState( + succcess: success)); + } else { + emit(ContactDeletedState( + succcess: success)); + } + } catch (e) { + emit(ContactErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/primary_information/contact/contact_event.dart b/lib/bloc/profile/primary_information/contact/contact_event.dart new file mode 100644 index 0000000..5e7106f --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_event.dart @@ -0,0 +1,70 @@ +part of 'contact_bloc.dart'; + +abstract class ContactEvent extends Equatable { + const ContactEvent(); + + @override + List get props => []; +} + +////get contacts +class GetContacts extends ContactEvent{ + final List contactInformations; + const GetContacts({required this.contactInformations}); + @override + List get props => []; +} + +//// load contacts +class LoadContacts extends ContactEvent{ + + @override + List get props => []; +} + +//// show add form +class ShowAddForm extends ContactEvent{ + +} + +//// show edit form +class ShowEditForm extends ContactEvent{ + final ContactInfo contactInfo; + const ShowEditForm({required this.contactInfo}); + @override + List get props => [contactInfo]; + +} + +////add event +class AddContactInformation extends ContactEvent{ + final int profileId; + final String token; + final ContactInfo contactInfo; + const AddContactInformation({required this.contactInfo, required this.profileId, required this.token}); + @override + List get props => [profileId,token,contactInfo]; +} + +////edit event +class EditContactInformation extends ContactEvent{ + final int profileId; + final String token; + final ContactInfo contactInfo; + const EditContactInformation({required this.contactInfo, required this.profileId, required this.token}); + @override + List get props => [profileId,token,contactInfo]; +} + +//// delete event + +class DeleteContactInformation extends ContactEvent{ + final int profileId; + final String token; + final ContactInfo contactInfo; + const DeleteContactInformation({required this.contactInfo, required this.profileId, required this.token}); + @override + List get props => [profileId,token,contactInfo]; +} + + diff --git a/lib/bloc/profile/primary_information/contact/contact_state.dart b/lib/bloc/profile/primary_information/contact/contact_state.dart new file mode 100644 index 0000000..af38743 --- /dev/null +++ b/lib/bloc/profile/primary_information/contact/contact_state.dart @@ -0,0 +1,81 @@ +part of 'contact_bloc.dart'; + +abstract class ContactState extends Equatable { + const ContactState(); + + @override + List get props => []; +} + +class ContactInitial extends ContactState {} + +////loaded state +class ContactLoadedState extends ContactState{ + final List contactInformation; + const ContactLoadedState({required this.contactInformation}); + @override + List get props => []; +} +////loading state +class ContactLoadingState extends ContactState{ + +} +//// adding state +class ContactAddingState extends ContactState{ + final List serviceTypes; + const ContactAddingState({ required this.serviceTypes}); + @override + List get props => [serviceTypes]; +} +//// Editing state +class ContactEditingState extends ContactState{ + final List serviceTypes; + final List commServiceProviders; + final CommService selectedProvider; + final ServiceType selectedServiceType; + final ContactInfo contactInfo; + const ContactEditingState({ required this.serviceTypes, required this.selectedServiceType, required this.selectedProvider, required this.commServiceProviders, required this.contactInfo}); + @override + List get props => [serviceTypes]; +} + + +//// added state +class ContactAddedState extends ContactState{ + + final Map response; + const ContactAddedState({ required this.response}); + @override + List get props => [response]; +} + + + + +//// edited state +class ContactEditedState extends ContactState{ + + final Map response; + const ContactEditedState({ required this.response}); + @override + List get props => [response]; +} +////deleted state +class ContactDeletedState extends ContactState{ + + final bool succcess; + const ContactDeletedState({required this.succcess}); + @override + List get props => [succcess]; +} + +////error state +class ContactErrorState extends ContactState{ + final String message; + const ContactErrorState({required this.message}); + @override + List get props => [message]; +} + + + diff --git a/lib/bloc/profile/primary_information/identification/identification_bloc.dart b/lib/bloc/profile/primary_information/identification/identification_bloc.dart new file mode 100644 index 0000000..2ea178d --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_bloc.dart @@ -0,0 +1,21 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; + +import '../../../../model/profile/basic_information/identification_information.dart'; + +part 'identification_event.dart'; +part 'identification_state.dart'; + +class IdentificationBloc extends Bloc { + IdentificationBloc() : super(IdentificationInitial()) { + List identificationInformations = []; + on((event, emit) { + try{ + identificationInformations = event.identificationInformation; + emit(IdentificationLoadedState(identificationInformation: identificationInformations)); + }catch(e){ + emit(IdenficationErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/primary_information/identification/identification_event.dart b/lib/bloc/profile/primary_information/identification/identification_event.dart new file mode 100644 index 0000000..03bbc09 --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_event.dart @@ -0,0 +1,15 @@ +part of 'identification_bloc.dart'; + +abstract class IdentificationEvent extends Equatable { + const IdentificationEvent(); + + @override + List get props => []; +} + +class GetIdentifications extends IdentificationEvent{ + final List identificationInformation; + const GetIdentifications({required this.identificationInformation}); + @override + List get props => [identificationInformation]; +} diff --git a/lib/bloc/profile/primary_information/identification/identification_state.dart b/lib/bloc/profile/primary_information/identification/identification_state.dart new file mode 100644 index 0000000..0cae35d --- /dev/null +++ b/lib/bloc/profile/primary_information/identification/identification_state.dart @@ -0,0 +1,28 @@ +part of 'identification_bloc.dart'; + +abstract class IdentificationState extends Equatable { + const IdentificationState(); + + @override + List get props => []; +} + +class IdentificationInitial extends IdentificationState {} + +class IdentificationLoadedState extends IdentificationState{ + final List identificationInformation; + const IdentificationLoadedState({required this.identificationInformation}); + @override + List get props => [identificationInformation]; +} + +class IdenficationErrorState extends IdentificationState{ + final String message; + const IdenficationErrorState({required this.message}); + @override + List get props => [message]; +} + +class IdentificationLoadingState extends IdentificationState{ + +} diff --git a/lib/bloc/profile/profile_bloc.dart b/lib/bloc/profile/profile_bloc.dart new file mode 100644 index 0000000..162bb9e --- /dev/null +++ b/lib/bloc/profile/profile_bloc.dart @@ -0,0 +1,26 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/profile/profileInfomation.dart'; +import 'package:unit2/sevices/profile/profile_service.dart'; +part 'profile_event.dart'; +part 'profile_state.dart'; + +class ProfileBloc extends Bloc { + ProfileBloc() : super(ProfileInitial()) { + ProfileInformation? globalProfileInformation; + on((event, emit) async { + emit(ProfileLoading()); + try { + + ProfileInformation? profileInformation = + await ProfileService.instance.getProfile(event.token, event.userID); + globalProfileInformation = profileInformation; + emit(ProfileLoaded(profileInformation: globalProfileInformation!)); + } catch (e) { + emit(ProfileErrorState(mesage: e.toString())); + } + }); + + + } +} diff --git a/lib/bloc/profile/profile_event.dart b/lib/bloc/profile/profile_event.dart new file mode 100644 index 0000000..218cb3e --- /dev/null +++ b/lib/bloc/profile/profile_event.dart @@ -0,0 +1,24 @@ +part of 'profile_bloc.dart'; + +abstract class ProfileEvent extends Equatable { + const ProfileEvent(); + + @override + List get props => []; +} + +class LoadProfile extends ProfileEvent { + final String token; + final int userID; + const LoadProfile({required this.token, required this.userID}); + @override + List get props => [token, userID]; +} + +class LoadProfileInformation extends ProfileEvent { + @override + List get props => []; +} + + + diff --git a/lib/bloc/profile/profile_state.dart b/lib/bloc/profile/profile_state.dart new file mode 100644 index 0000000..7c2bddb --- /dev/null +++ b/lib/bloc/profile/profile_state.dart @@ -0,0 +1,29 @@ +part of 'profile_bloc.dart'; + +abstract class ProfileState extends Equatable { + const ProfileState(); + + @override + List get props => []; +} + +class ProfileInitial extends ProfileState {} + +class ProfileLoaded extends ProfileState { + final ProfileInformation profileInformation; + const ProfileLoaded({required this.profileInformation}); + @override + List get props => [profileInformation]; +} + +class ProfileErrorState extends ProfileState { + final String mesage; + const ProfileErrorState({required this.mesage}); + @override + List get props => [mesage]; +} + +class ProfileLoading extends ProfileState {} + + + diff --git a/lib/bloc/profile/references/references_bloc.dart b/lib/bloc/profile/references/references_bloc.dart new file mode 100644 index 0000000..ba27258 --- /dev/null +++ b/lib/bloc/profile/references/references_bloc.dart @@ -0,0 +1,210 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/location/address_category.dart'; +import 'package:unit2/model/location/barangay.dart'; +import 'package:unit2/model/location/city.dart'; +import 'package:unit2/model/location/country.dart'; +import 'package:unit2/model/location/region.dart'; +import 'package:unit2/sevices/profile/references_services.dart'; +import '../../../model/location/provinces.dart'; +import '../../../model/profile/references.dart'; +import '../../../utils/location_utilities.dart'; + +part 'references_event.dart'; +part 'references_state.dart'; + +class ReferencesBloc extends Bloc { + List references = []; + List globalCountries = []; + List globalRegions = []; + List globalCategories = []; + + ReferencesBloc() : super(ReferencesInitial()) { + on((event, emit) async { + emit(ReferencesLoadingState()); + try { + if(references.isEmpty){ + List refs = await ReferencesServices.instace + .getRefences(event.profileId, event.token); + references = refs; + emit(ReferencesLoadedState(references: references)); + }else{ + emit(ReferencesLoadedState(references: references)); + } + } catch (e) { + ReferencesErrorState(message: e.toString()); + } +////SHOW FORM FOR ADDING REFERENCES + }); + on((event, emit) async { + emit(ReferencesLoadingState()); + try { + if (globalRegions.isEmpty) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalCountries.isEmpty) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + if (globalCategories.isEmpty) { + List categories = + await LocationUtils.instance.getAddressCategory(); + globalCategories = categories; + } + emit(AddReferenceState( + countries: globalCountries, + regions: globalRegions, + categories: globalCategories)); + } catch (e) { + emit(ReferencesErrorState(message: e.toString())); + } + ////SHOW EDIT FORM + }); + on((event, emit) async { + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedCity; + AddressCategory? selectedCategory; + Country selectedCountry; + Barangay? selectedBarangay; + try { + if (globalRegions.isEmpty) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalCountries.isEmpty) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + if (globalCategories.isEmpty) { + List categories = + await LocationUtils.instance.getAddressCategory(); + globalCategories = categories; + } +//// checck if address is overseas + bool overseas = + event.personalReference.address!.country!.id! != 175 ? true : false; + selectedCategory = globalCategories.firstWhere((AddressCategory element) => event.personalReference.address!.addressCategory!.id == element.id); + ////if address is not overseas set initial values for address + if (!overseas) { + selectedRegion = globalRegions.firstWhere((Region element) => + event.personalReference.address!.cityMunicipality!.province! + .region!.code == + element.code); + List provinces = await LocationUtils.instance + .getProvinces(regionCode: selectedRegion.code.toString()); + selectedProvince = provinces.firstWhere((Province province) => + event.personalReference.address!.cityMunicipality!.province! + .code == + province.code); + List cities = await LocationUtils.instance + .getCities(code: selectedProvince.code!); + selectedCity = cities.firstWhere((CityMunicipality city) => + event.personalReference.address!.cityMunicipality!.code == + city.code); + List barangays = await LocationUtils.instance.getBarangay(code: selectedCity.code.toString()); + if(event.personalReference.address?.barangay!=null){ + selectedBarangay = barangays.firstWhere((Barangay barangay)=>event.personalReference.address?.barangay?.code == barangay.code); + }else{ + selectedBarangay = null; + } + emit(EditReferenceState( + selectedRegion: selectedRegion, + ref: event.personalReference, + countries: globalCountries, + regions: globalRegions, + barangays: barangays, + categories: globalCategories, + isOverseas: overseas, + provinces: provinces, + selectedProvince: selectedProvince, + cities: cities, + selectedCity: selectedCity, + selectedCategory: selectedCategory, + selectedBarangay: selectedBarangay + )); + } else { + //// if address is overseas set initial value for country + selectedCountry = globalCountries.firstWhere((Country element) => event.personalReference.address!.country!.id == element.id); + emit(EditReferenceState( + selectedCountry: selectedCountry, + selectedCategory: selectedCategory, + selectedRegion: null, + ref: event.personalReference, + countries: globalCountries, + regions: globalRegions, + categories: globalCategories, + isOverseas: overseas)); + } + } catch (e) { + emit(ReferencesErrorState(message: e.toString())); + } + }); + + //// CALL THE ERROR STATE EVEN T + on((event, emit) async { + emit(const ReferencesErrorState( + message: "Something went wrong. Please try again")); + //// EDIT REFERENCES EVENT + });on((event,emit)async{ + Map status =await ReferencesServices.instace.update(ref: event.reference, token: event.token, profileId: event.profileId); + if (status['success']) { + PersonalReference ref = PersonalReference.fromJson(status['data']); + references.removeWhere((PersonalReference element)=>element.id == event.reference.id); + references.add(ref); + emit( + ReferenceEditedState( response: status)); + } else { + emit( + ReferenceEditedState( response: status)); + } + + }); + +//// add reference event + on((event, emit) async { + try { + Map status = await ReferencesServices.instace + .addReference( + ref: event.reference, + token: event.token, + profileId: event.profileId); + if (status['success']) { + PersonalReference ref = PersonalReference.fromJson(status['data']); + references.add(ref); + emit( + ReferencesAddedState( response: status)); + } else { + emit( + ReferencesAddedState( response: status)); + } + } catch (e) { + emit(ReferencesErrorState(message: e.toString())); + } + }); + ////LOAD REFERENCE + on((event, emit) { + emit(ReferencesLoadingState()); + emit(ReferencesLoadedState(references: references)); + + }); + ////DELETE REFERENCE + on((event, emit) async { + try { + final bool success = await ReferencesServices.instace.delete( + profileId: event.profileId, token: event.token, id: event.refId); + if (success) { + event.references.removeWhere( + (PersonalReference element) => element.id == event.refId); + references = event.references; + emit(DeleteReferenceState( success: success)); + } else { + emit(DeleteReferenceState(success: success)); + } + } catch (e) { + emit(ReferencesErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/references/references_event.dart b/lib/bloc/profile/references/references_event.dart new file mode 100644 index 0000000..5eedf7d --- /dev/null +++ b/lib/bloc/profile/references/references_event.dart @@ -0,0 +1,66 @@ +part of 'references_bloc.dart'; + +abstract class ReferencesEvent extends Equatable { + const ReferencesEvent(); + + @override + List get props => []; +} + +class GetReferences extends ReferencesEvent { + final int profileId; + final String token; + const GetReferences({required this.profileId, required this.token}); + @override + List get props => [profileId, token]; +} + +class ShowAddReferenceForm extends ReferencesEvent {} + +class ShowEditReferenceForm extends ReferencesEvent { + final PersonalReference personalReference; + const ShowEditReferenceForm({required this.personalReference}); + @override + List get props => [personalReference]; +} + +class CallErrorState extends ReferencesEvent {} + +class AddReference extends ReferencesEvent { + final PersonalReference reference; + final String token; + final int profileId; + const AddReference( + {required this.profileId, required this.reference, required this.token}); + @override + List get props => [profileId, token, reference]; +} + +class EditReference extends ReferencesEvent { + final PersonalReference reference; + final String token; + final int profileId; + const EditReference( + {required this.profileId, required this.reference, required this.token}); + @override + List get props => [profileId, token, reference]; +} + +class DeleteReference extends ReferencesEvent { + final List references; + final int profileId; + final String token; + final int refId; + const DeleteReference( + {required this.profileId, + required this.refId, + required this.references, + required this.token}); + @override + List get props => [profileId, token, refId, references]; +} + +class LoadReferences extends ReferencesEvent { + @override + List get props => []; +} diff --git a/lib/bloc/profile/references/references_state.dart b/lib/bloc/profile/references/references_state.dart new file mode 100644 index 0000000..b3a07d3 --- /dev/null +++ b/lib/bloc/profile/references/references_state.dart @@ -0,0 +1,93 @@ +part of 'references_bloc.dart'; + +abstract class ReferencesState extends Equatable { + const ReferencesState(); + + @override + List get props => []; +} + +class ReferencesInitial extends ReferencesState {} + +class ReferencesLoadedState extends ReferencesState { + final List references; + const ReferencesLoadedState({required this.references}); + + @override + List get props => [references]; +} + +class ReferencesErrorState extends ReferencesState { + final String message; + const ReferencesErrorState({required this.message}); + + @override + List get props => [message]; +} + +class ReferencesLoadingState extends ReferencesState {} + +class ReferencesAddedState extends ReferencesState { + final Map response; + const ReferencesAddedState( + { required this.response}); + @override + List get props => [ response]; +} +class ReferenceEditedState extends ReferencesState { + + final Map response; + const ReferenceEditedState( + { required this.response}); + @override + List get props => [ response]; +} + +class EditReferenceState extends ReferencesState { + final List regions; + final List countries; + final List categories; + final List? provinces; + final List? cities; + final List? barangays; + final PersonalReference ref; + final bool isOverseas; + final Region? selectedRegion; + final Province? selectedProvince; + final CityMunicipality? selectedCity; + final AddressCategory selectedCategory; + final Barangay? selectedBarangay; + final Country? selectedCountry; + const EditReferenceState( + { this.barangays, + this.selectedBarangay, + required this.selectedCategory, + this.cities, + this.selectedCity, + this.provinces, + this.selectedProvince, + this.selectedRegion, + this.selectedCountry, + required this.isOverseas, + required this.ref, + required this.categories, + required this.countries, + required this.regions}); + @override + List get props => [regions, countries, categories, isOverseas]; +} + +class AddReferenceState extends ReferencesState { + final List regions; + final List countries; + final List categories; + const AddReferenceState( + {required this.categories, + required this.countries, + required this.regions}); +} + +class DeleteReferenceState extends ReferencesState { + final bool success; + const DeleteReferenceState({ required this.success}); +} diff --git a/lib/bloc/profile/voluntary_works/voluntary_work_bloc.dart b/lib/bloc/profile/voluntary_works/voluntary_work_bloc.dart new file mode 100644 index 0000000..d2bbd22 --- /dev/null +++ b/lib/bloc/profile/voluntary_works/voluntary_work_bloc.dart @@ -0,0 +1,24 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/profile/volunatary_services.dart'; + +import '../../../model/profile/voluntary_works.dart'; + +part 'voluntary_work_event.dart'; +part 'voluntary_work_state.dart'; + +class VoluntaryWorkBloc extends Bloc { + VoluntaryWorkBloc() : super(VoluntaryWorkInitial()) { + List voluntaryWorks = []; + on((event, emit) async{ + emit(VoluntaryWorkLoadingState()); + try{ + List works = await VoluntaryService.instance.getVoluntaryWorks(event.profileId, event.token); + voluntaryWorks = works; + emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks)); + }catch(e){ + emit(VoluntaryWorkErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/voluntary_works/voluntary_work_event.dart b/lib/bloc/profile/voluntary_works/voluntary_work_event.dart new file mode 100644 index 0000000..0e62010 --- /dev/null +++ b/lib/bloc/profile/voluntary_works/voluntary_work_event.dart @@ -0,0 +1,16 @@ +part of 'voluntary_work_bloc.dart'; + +abstract class VoluntaryWorkEvent extends Equatable { + const VoluntaryWorkEvent(); + + @override + List get props => []; +} + +class GetVoluntarWorks extends VoluntaryWorkEvent{ + final int profileId; + final String token; + const GetVoluntarWorks({required this.profileId, required this.token}); + @override + List get props => [profileId,token]; +} diff --git a/lib/bloc/profile/voluntary_works/voluntary_work_state.dart b/lib/bloc/profile/voluntary_works/voluntary_work_state.dart new file mode 100644 index 0000000..8c2c912 --- /dev/null +++ b/lib/bloc/profile/voluntary_works/voluntary_work_state.dart @@ -0,0 +1,27 @@ +part of 'voluntary_work_bloc.dart'; + +abstract class VoluntaryWorkState extends Equatable { + const VoluntaryWorkState(); + + @override + List get props => []; +} + +class VoluntaryWorkInitial extends VoluntaryWorkState {} +class VoluntaryWorkLoadedState extends VoluntaryWorkState{ + final List voluntaryWorks; + const VoluntaryWorkLoadedState({required this.voluntaryWorks}); + @override + List get props => [voluntaryWorks]; +} + +class VoluntaryWorkErrorState extends VoluntaryWorkState{ + final String message; + const VoluntaryWorkErrorState({required this.message}); + @override + List get props => [message]; +} + +class VoluntaryWorkLoadingState extends VoluntaryWorkState{ + +} diff --git a/lib/bloc/profile/workHistory/workHistory_bloc.dart b/lib/bloc/profile/workHistory/workHistory_bloc.dart new file mode 100644 index 0000000..d19eca5 --- /dev/null +++ b/lib/bloc/profile/workHistory/workHistory_bloc.dart @@ -0,0 +1,187 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart'; +import 'package:unit2/model/profile/work_history.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.dart'; +import 'package:unit2/model/utils/position.dart'; +import 'package:unit2/sevices/profile/work_history_services.dart'; +import 'package:unit2/utils/profile_utilities.dart'; + +import '../../../model/utils/category.dart'; + +part 'workHistory_event.dart'; +part 'workHistory_state.dart'; + +class WorkHistoryBloc extends Bloc { + List workExperiences = []; + List agencyPositions = []; + List agencies = []; + List appointmentStatus = []; + List agencyCategory = []; + WorkHistoryBloc() : super(EducationInitial()) { + ////GET WORK HISTORIES + on((event, emit) async { + emit(WorkHistoryLoadingState()); + try { + if (workExperiences.isEmpty) { + List works = await WorkHistoryService.instance + .getWorkExperiences(event.profileId!, event.token!); + workExperiences = works; + } + + emit(WorkHistoryLoaded(workExperiences: workExperiences)); + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); +///// LOAD WORK HISTORIES + on((event, emit) { + emit(WorkHistoryLoadingState()); + emit(WorkHistoryLoaded(workExperiences: workExperiences)); + }); + ////DELETE + on((event, emit) async { + try { + final bool success = await WorkHistoryService.instance.delete( + profileId: event.profileId, + token: event.token, + work: event.workHistory); + if (success) { + workExperiences.removeWhere( + (WorkHistory element) => element.id == event.workHistory.id); + emit(DeletedState(success: success)); + } else { + emit(DeletedState(success: success)); + } + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + //// ADD WORK HISTORIES + on((event, emit) async { + try { + Map status = await WorkHistoryService.instance.add( + isPrivate: event.isPrivate, + workHistory: event.workHistory, + token: event.token, + profileId: event.profileId); + if (status['success']) { + WorkHistory workHistory = WorkHistory.fromJson(status['data']); + workExperiences.add(workHistory); + emit(WorkHistoryAddedState(response: status)); + } else { + emit(WorkHistoryAddedState(response: status)); + } + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + +////UPDATE WORK HISTORY + on((event, emit) async { + try { + Map status = await WorkHistoryService.instance.update( + oldWorkHistory: event.oldWorkHistory, + newWorkHistory: event.workHistory, + token: event.token, + profileId: event.profileId); + if (status['success']) { + WorkHistory workHistory = WorkHistory.fromJson(status['data']); + workExperiences.removeWhere((WorkHistory work) { + return work.id == event.oldWorkHistory.id; + }); + workExperiences.add(workHistory); + emit(WorkHistoryEditedState(response: status)); + } else { + emit(WorkHistoryEditedState( + response: status, + )); + } + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + +////SHOW EDIT WORK HISTORIES + on((event, emit) async { + try { + /////POSITIONS------------------------------------------ + if (agencyPositions.isEmpty) { + List positions = + await WorkHistoryService.instance.getAgencyPosition(); + agencyPositions = positions; + } + + /////AGENCIES------------------------------------------ + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + + /////Category Agency------------------------------------------ + if (agencyCategory.isEmpty) { + List categoryAgencies = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = categoryAgencies; + } + /////////------------------------------------- + if (appointmentStatus.isEmpty) { + List status = + WorkHistoryService.instance.getAppointmentStatusList(); + appointmentStatus = status; + } + + emit(EditWorkHistoryState( + workHistory: event.workHistory, + agencyPositions: agencyPositions, + appointmentStatus: appointmentStatus, + agencyCategory: agencyCategory, + agencies: agencies)); + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + ////SHOW ADD FORM WORK HISTORIES + on((event, emit) async { + emit(WorkHistoryLoadingState()); + try { + /////POSITIONS------------------------------------------ + if (agencyPositions.isEmpty) { + List positions = + await WorkHistoryService.instance.getAgencyPosition(); + agencyPositions = positions; + } + + /////AGENCIES------------------------------------------ + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + + /////Category Agency------------------------------------------ + if (agencyCategory.isEmpty) { + List categoryAgencies = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = categoryAgencies; + } + /////////------------------------------------- + if (appointmentStatus.isEmpty) { + List status = + WorkHistoryService.instance.getAppointmentStatusList(); + appointmentStatus = status; + } + + emit(AddWorkHistoryState( + agencyPositions: agencyPositions, + appointmentStatus: appointmentStatus, + agencyCategory: agencyCategory, + agencies: agencies)); + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/profile/workHistory/workHistory_event.dart b/lib/bloc/profile/workHistory/workHistory_event.dart new file mode 100644 index 0000000..0f394b7 --- /dev/null +++ b/lib/bloc/profile/workHistory/workHistory_event.dart @@ -0,0 +1,64 @@ +part of 'workHistory_bloc.dart'; + +abstract class WorkHistorytEvent extends Equatable { + const WorkHistorytEvent(); + + @override + List get props => []; +} + +class GetWorkHistories extends WorkHistorytEvent{ + final int profileId; + final String token; + const GetWorkHistories({required this.profileId, required this.token}); + + + @override + List get props => [profileId, token]; +} + +class LoadWorkHistories extends WorkHistorytEvent{ + @override + List get props => []; +} + +class ShowAddWorkHistoryForm extends WorkHistorytEvent{ + +} +class ShowEditWorkHistoryForm extends WorkHistorytEvent{ + final WorkHistory workHistory; + const ShowEditWorkHistoryForm({required this.workHistory}); + @override + List get props => [workHistory]; + +} +class DeleteWorkHistory extends WorkHistorytEvent{ + final String token; + final int profileId; + final WorkHistory workHistory; + const DeleteWorkHistory({required this.profileId, required this.token, required this.workHistory}); + @override + List get props => [token, profileId,workHistory]; +} + +class UpdateWorkHistory extends WorkHistorytEvent{ + final WorkHistory workHistory; + final WorkHistory oldWorkHistory; + final String profileId; + final String token; + const UpdateWorkHistory({required this.oldWorkHistory, required this.profileId, required this.token, required this.workHistory}); + @override + List get props => [profileId,token,workHistory,oldWorkHistory]; +} + +class AddWorkHostory extends WorkHistorytEvent{ + final WorkHistory workHistory; + final bool isPrivate; + final int profileId; + final String token; + const AddWorkHostory({required this.workHistory, required this.isPrivate, required this.profileId, required this.token}); + @override + List get props => [workHistory,profileId,token,isPrivate]; +} + + diff --git a/lib/bloc/profile/workHistory/workHistory_state.dart b/lib/bloc/profile/workHistory/workHistory_state.dart new file mode 100644 index 0000000..2008857 --- /dev/null +++ b/lib/bloc/profile/workHistory/workHistory_state.dart @@ -0,0 +1,74 @@ +part of 'workHistory_bloc.dart'; + +abstract class WorkHistoryState extends Equatable { + const WorkHistoryState(); + + @override + List get props => []; +} + +class EducationInitial extends WorkHistoryState {} + +class WorkHistoryLoaded extends WorkHistoryState{ + final List workExperiences; + const WorkHistoryLoaded({required this.workExperiences}); + @override + List get props => [workExperiences]; +} + +class WorkHistoryLoadingState extends WorkHistoryState{ + +} +class WorkHistoryErrorState extends WorkHistoryState{ + final String message; + const WorkHistoryErrorState({required this.message}); + + @override + List get props => [message]; +} + + + +class AddWorkHistoryState extends WorkHistoryState{ + final List agencyPositions; + final List agencies; + final List agencyCategory; + final List appointmentStatus; + + const AddWorkHistoryState({required this.agencyPositions, required this.appointmentStatus,required this.agencies,required this.agencyCategory}); + @override + List get props => [agencyPositions,appointmentStatus,agencies,agencyCategory]; + +} + +class EditWorkHistoryState extends WorkHistoryState{ + final WorkHistory workHistory; + final List agencyPositions; + final List agencies; + final List agencyCategory; + final List appointmentStatus; + const EditWorkHistoryState({required this.workHistory, required this.agencies,required this.agencyCategory, required this.agencyPositions, required this.appointmentStatus}); + @override + List get props => [workHistory, agencyPositions,appointmentStatus,agencies,agencyCategory]; +} + +class DeletedState extends WorkHistoryState{ + final bool success; + const DeletedState({required this.success}); + @override + List get props => [success]; +} + +class WorkHistoryEditedState extends WorkHistoryState{ + final Map response; + const WorkHistoryEditedState({required this.response}); + @override + List get props => [response]; +} + +class WorkHistoryAddedState extends WorkHistoryState{ + final Map response; + const WorkHistoryAddedState({required this.response}); + @override + List get props => [response]; +} diff --git a/lib/bloc/user/user_bloc.dart b/lib/bloc/user/user_bloc.dart new file mode 100644 index 0000000..5c9c705 --- /dev/null +++ b/lib/bloc/user/user_bloc.dart @@ -0,0 +1,99 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:unit2/model/login_data/user_info/user_data.dart'; +import 'package:unit2/model/login_data/version_info.dart'; +import 'package:unit2/screens/unit2/login/functions/get_app_version.dart'; +import 'package:unit2/sevices/login_service/auth_service.dart'; +import 'package:unit2/utils/global.dart'; + +import '../../utils/scanner.dart'; +import '../../utils/text_container.dart'; + +part 'user_event.dart'; +part 'user_state.dart'; + +class UserBloc extends Bloc { + UserData? _userData; + VersionInfo? _versionInfo; + String? _apkVersion; + bool save = false; + UserBloc() : super(UserInitial()) { + // this event is called when opening the app to check if + // there is new app version + on((event, emit) async { + try { + emit(SplashScreen()); + VersionInfo versionInfo = await AuthService.instance.getVersionInfo(); + _versionInfo = versionInfo; + String apkVersion = await getAppVersion(); + _apkVersion = apkVersion; + final String? saved = CREDENTIALS?.get('saved'); + final String? username = CREDENTIALS?.get('username'); + final String? password = CREDENTIALS?.get('password'); + debugPrint(username); + debugPrint(password); + if (saved != null) { + save = true; + add(UserLogin(username: username, password: password)); + } else { + emit(VersionLoaded( + versionInfo: _versionInfo, apkVersion: _apkVersion)); + } + } catch (e) { + emit(UserError( + message: e.toString(), + )); + } + }); +//Loading the current version of the app + on((event, emit) { + emit(VersionLoaded(versionInfo: _versionInfo, apkVersion: _apkVersion)); + }); + + on((event, emit) async { + try { + Map response = await AuthService.instance + .webLogin(username: event.username, password: event.password); + if (response['status'] == true) { + UserData userData = UserData.fromJson(response['data']); + emit(UserLoggedIn( + userData: userData, success: true, message: response['message'],savedCredentials: save)); + } else { + emit(UserLoggedIn( + userData: null, success: false, message: response['message'],savedCredentials: save)); + } + } on TimeoutException catch (_) { + emit(InternetTimeout(message: timeoutError)); + } on SocketException catch (_) { + emit(InternetTimeout(message: timeoutError)); + } + }); + on((event, emit) async { + try { + UserData? userData = await AuthService.instance + .qrLogin(uuid: event.uuid, password: event.password); + _userData = userData; + emit(UserLoggedIn(userData: _userData,savedCredentials: save)); + } on TimeoutException catch (_) { + emit(InternetTimeout(message: timeoutError)); + } on SocketException catch (_) { + emit(InternetTimeout(message: timeoutError)); + } on Error catch (_) { + emit(InvalidCredentials(message: "Invalid username or password")); + } + }); + on((event, emit) { + emit(UserLoggedIn(userData: _userData,savedCredentials: save)); + }); + on((event, emit) async { + ScanResult result = await QRCodeBarCodeScanner.instance.scanner(); + if (result.rawContent.toString().isNotEmpty) { + emit(UuidLoaded(uuid: result.rawContent.toString())); + } + }); + } +} diff --git a/lib/bloc/bloc/user_event.dart b/lib/bloc/user/user_event.dart similarity index 100% rename from lib/bloc/bloc/user_event.dart rename to lib/bloc/user/user_event.dart diff --git a/lib/bloc/bloc/user_state.dart b/lib/bloc/user/user_state.dart similarity index 69% rename from lib/bloc/bloc/user_state.dart rename to lib/bloc/user/user_state.dart index 551c9e2..de6688f 100644 --- a/lib/bloc/bloc/user_state.dart +++ b/lib/bloc/user/user_state.dart @@ -20,6 +20,7 @@ class UserLoading extends UserState { } class SplashScreen extends UserState { + @override List get props => []; } @@ -32,7 +33,10 @@ class UserError extends UserState { } class UserLoggedIn extends UserState{ final UserData? userData; - UserLoggedIn({this.userData}); + final String? message; + final bool? success; + final bool? savedCredentials; + UserLoggedIn({this.userData,this.message,this.success,this.savedCredentials}); } class VersionLoaded extends UserState { @@ -48,3 +52,15 @@ class UuidLoaded extends UserState{ @override List get props => [uuid]; } + +class InternetTimeout extends UserState{ + final String message; + InternetTimeout({required this.message}); + @override + List get props => [message]; +} + +class InvalidCredentials extends UserState{ + final String message ; + InvalidCredentials ({required this.message}); +} diff --git a/lib/main.dart b/lib/main.dart index be88b93..da7df5a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,15 +3,28 @@ import 'package:flutter/material.dart'; import 'package:device_preview/device_preview.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; +import 'package:hive/hive.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/app_router.dart'; import 'package:unit2/utils/global_context.dart'; import 'package:unit2/utils/global_context.dart'; +import 'package:path_provider/path_provider.dart' as path_provider; import './utils/router.dart'; import './utils/global.dart'; -void main() { - runApp(MyApp()); +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + var appDirectory = await path_provider.getApplicationDocumentsDirectory(); + await Hive.initFlutter(appDirectory.path); + CREDENTIALS = await Hive.openBox('credentials'); + SOSCONTACTS = await Hive.openBox('soscontacts'); + SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) + .then((_) { + runApp(MyApp()); + }); } // void main() => runApp( @@ -46,6 +59,9 @@ class MyApp extends StatelessWidget { BlocProvider( create: (_) => UserBloc(), ), + BlocProvider( + create: (_) => ProfileBloc(), + ), ], child: MaterialApp( navigatorKey: NavigationService.navigatorKey, @@ -55,8 +71,10 @@ class MyApp extends StatelessWidget { // routeInformationParser: goRouter.routeInformationParser, // routerDelegate: goRouter.routerDelegate, // routeInformationProvider: goRouter.routeInformationProvider, + title: 'uniT2 - Universal Tracker and Tracer', theme: ThemeData( + primarySwatch: Colors.red, appBarTheme: const AppBarTheme( systemOverlayStyle: SystemUiOverlayStyle( statusBarBrightness: Brightness.dark, diff --git a/lib/model/location/address_category.dart b/lib/model/location/address_category.dart new file mode 100644 index 0000000..0916912 --- /dev/null +++ b/lib/model/location/address_category.dart @@ -0,0 +1,23 @@ +class AddressCategory { + AddressCategory({ + required this.id, + required this.name, + required this.type, + }); + + final int? id; + final String? name; + final String? type; + + factory AddressCategory.fromJson(Map json) => AddressCategory( + id: json["id"], + name: json["name"], + type: json["type"], + ); + + Map toJson() => { + "id": id, + "name": name, + "type": type, + }; +} \ No newline at end of file diff --git a/lib/model/location/barangay.dart b/lib/model/location/barangay.dart new file mode 100644 index 0000000..f36032c --- /dev/null +++ b/lib/model/location/barangay.dart @@ -0,0 +1,41 @@ +// To parse this JSON data, do +// +// final barangay = barangayFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'city.dart'; +import 'provinces.dart'; + +Barangay barangayFromJson(String str) => Barangay.fromJson(json.decode(str)); + +String barangayToJson(Barangay data) => json.encode(data.toJson()); + +class Barangay { + Barangay({ + required this.code, + required this.description, + required this.cityMunicipality, + }); + + final String? code; + final String? description; + final CityMunicipality? cityMunicipality; + + factory Barangay.fromJson(Map json) => Barangay( + code: json["code"], + description: json["description"], + cityMunicipality: json['city_municipality'] == null? null: CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "code": code, + "description": description, + "city_municipality": cityMunicipality!.toJson(), + }; +} + + + + diff --git a/lib/model/location/city.dart b/lib/model/location/city.dart new file mode 100644 index 0000000..1fc77cd --- /dev/null +++ b/lib/model/location/city.dart @@ -0,0 +1,51 @@ +// To parse this JSON data, do +// +// final city = cityFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'provinces.dart'; +import 'region.dart'; + +CityMunicipality cityFromJson(String str) => CityMunicipality.fromJson(json.decode(str)); + +String cityToJson(CityMunicipality data) => json.encode(data.toJson()); + +class CityMunicipality { + CityMunicipality({ + required this.code, + required this.description, + required this.province, + required this.psgcCode, + required this.zipcode, + }); + + final String? code; + final String? description; + final Province? province; + final String? psgcCode; + final String? zipcode; + + factory CityMunicipality.fromJson(Map json) => CityMunicipality( + code: json["code"], + description: json["description"], + province: json['province'] == null? null : Province.fromJson(json["province"]), + psgcCode: json["psgc_code"], + zipcode: json["zipcode"], + ); + + Map toJson() => { + "code": code, + "description": description, + "province": province?.toJson(), + "psgc_code": psgcCode, + "zipcode": zipcode, + }; + @override + String toString(){ + return 'CityMunicipality{code:$code, description:$description, provice:${province.toString()} }'; + } +} + + diff --git a/lib/model/location/country.dart b/lib/model/location/country.dart new file mode 100644 index 0000000..fe54ce8 --- /dev/null +++ b/lib/model/location/country.dart @@ -0,0 +1,40 @@ +// To parse this JSON data, do +// +// final country = countryFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +Country countryFromJson(String str) => Country.fromJson(json.decode(str)); + +String countryToJson(Country data) => json.encode(data.toJson()); + +class Country { + Country({ + required this.id, + required this.name, + required this.code, + }); + + final int? id; + final String? name; + final String? code; + + factory Country.fromJson(Map json) => Country( + id: json["id"], + name: json["name"], + code: json["code"].toString(), + ); + + Map toJson() => { + "id": id, + "name": name, + "code": code, + }; + + @override + String toString() { + return '$id $name $code '; + + } +} diff --git a/lib/model/location/provinces.dart b/lib/model/location/provinces.dart new file mode 100644 index 0000000..597587d --- /dev/null +++ b/lib/model/location/provinces.dart @@ -0,0 +1,49 @@ +// To parse this JSON data, do +// +// final province = provinceFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'region.dart'; + +Province provinceFromJson(String str) => Province.fromJson(json.decode(str)); + +String provinceToJson(Province data) => json.encode(data.toJson()); + +class Province { + Province({ + required this.code, + required this.description, + required this.region, + required this.psgcCode, + required this.shortname, + }); + + final String? code; + final String? description; + final Region? region; + final String? psgcCode; + final String? shortname; + + factory Province.fromJson(Map json) => Province( + code: json["code"], + description: json["description"], + region: json['region'] == null? null: Region.fromJson(json["region"]), + psgcCode: json["psgc_code"], + shortname: json["shortname"], + ); + + Map toJson() => { + "code": code, + "description": description, + "region": region!.toJson(), + "psgc_code": psgcCode, + "shortname": shortname, + }; + + @override + String toString(){ + return 'Province(name:$description ${region.toString()})'; + } +} diff --git a/lib/model/location/purok.dart b/lib/model/location/purok.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/model/location/region.dart b/lib/model/location/region.dart new file mode 100644 index 0000000..17bd41d --- /dev/null +++ b/lib/model/location/region.dart @@ -0,0 +1,39 @@ +// To parse this JSON data, do +// +// final region = regionFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +Region regionFromJson(String str) => Region.fromJson(json.decode(str)); + +String regionToJson(Region data) => json.encode(data.toJson()); + +class Region { + Region({ + required this.code, + required this.description, + required this.psgcCode, + }); + + final int? code; + final String? description; + final String? psgcCode; + + factory Region.fromJson(Map json) => Region( + code: json["code"], + description: json["description"], + psgcCode: json["psgc_code"], + ); + + Map toJson() => { + "code": code, + "description": description, + "psgc_code": psgcCode, + }; + + @override + String toString(){ + return 'Region(name:$description)'; + } +} diff --git a/lib/model/location/subdivision.dart b/lib/model/location/subdivision.dart new file mode 100644 index 0000000..950d80e --- /dev/null +++ b/lib/model/location/subdivision.dart @@ -0,0 +1,23 @@ +class Subdivision { + Subdivision({ + this.id, + this.lotNo, + this.blockNo, + }); + + final int? id; + final int? lotNo; + final int? blockNo; + + factory Subdivision.fromJson(Map json) => Subdivision( + id: json["id"], + lotNo: json["lot_no"], + blockNo: json["block_no"], + ); + + Map toJson() => { + "id": id, + "lot_no": lotNo, + "block_no": blockNo, + }; +} \ No newline at end of file diff --git a/lib/model/profile/basic_info.dart b/lib/model/profile/basic_info.dart new file mode 100644 index 0000000..243070e --- /dev/null +++ b/lib/model/profile/basic_info.dart @@ -0,0 +1,15 @@ +import 'package:unit2/model/profile/basic_information/adress.dart'; +import 'package:unit2/model/profile/basic_information/citizenship.dart'; +import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:unit2/model/profile/basic_information/identification_information.dart'; +import 'package:unit2/model/profile/basic_information/primary-information.dart'; + +class BasicInfo{ + PrimaryInformation? primaryInformation; + List contactInformation; + List identifications; + List citizenships; + List addresses; + BasicInfo({required this.addresses, required this.contactInformation, required this.primaryInformation,required this.identifications,required this.citizenships}); + +} \ No newline at end of file diff --git a/lib/model/profile/basic_information/adress.dart b/lib/model/profile/basic_information/adress.dart new file mode 100644 index 0000000..4e941ec --- /dev/null +++ b/lib/model/profile/basic_information/adress.dart @@ -0,0 +1,76 @@ + + +import '../../location/barangay.dart'; +import '../../location/city.dart'; +import '../../location/country.dart'; +import '../../location/subdivision.dart'; +import '../../utils/category.dart'; + +class MainAdress { + MainAdress({ + this.id, + this.address, + this.details, + this.subdivision, + }); + + final int? id; + final AddressClass? address; + final String? details; + final Subdivision? subdivision; + + factory MainAdress.fromJson(Map json) => MainAdress( + id: json["id"], + address: json["address"] == null ? null : AddressClass.fromJson(json["address"]), + details: json["details"], + subdivision: json["subdivision"] == null ? null : Subdivision.fromJson(json["subdivision"]), + ); + + Map toJson() => { + "id": id, + "address": address?.toJson(), + "details": details, + "subdivision": subdivision?.toJson(), + }; +} + +class AddressClass { + AddressClass({ + this.id, + this.country, + this.barangay, + this.category, + this.areaClass, + this.cityMunicipality, + }); + + final int? id; + final Country? country; + final Barangay? barangay; + final Category? category; + final String? areaClass; + final CityMunicipality? cityMunicipality; + + factory AddressClass.fromJson(Map json) => AddressClass( + id: json["id"], + country: json["country"] == null ? null : Country.fromJson(json["country"]), + barangay: json["barangay"] == null ? null : Barangay.fromJson(json["barangay"]), + category: json["category"] == null ? null : Category.fromJson(json["category"]), + areaClass: json["area_class"], + cityMunicipality: json["city_municipality"] == null ? null : CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "country": country?.toJson(), + "barangay": barangay?.toJson(), + "category": category?.toJson(), + "area_class": areaClass, + "city_municipality": cityMunicipality?.toJson(), + }; +} + + + + + diff --git a/lib/model/profile/basic_information/citizenship.dart b/lib/model/profile/basic_information/citizenship.dart new file mode 100644 index 0000000..1c694ed --- /dev/null +++ b/lib/model/profile/basic_information/citizenship.dart @@ -0,0 +1,22 @@ + +import '../../location/country.dart'; + +class Citizenship { + Citizenship({ + required this.country, + required this.naturalBorn, + }); + + final Country? country; + final bool? naturalBorn; + + factory Citizenship.fromJson(Map json) => Citizenship( + country: Country.fromJson(json["country"]), + naturalBorn: json["natural_born"], + ); + + Map toJson() => { + "country": country!.toJson(), + "natural_born": naturalBorn, + }; +} diff --git a/lib/model/profile/basic_information/contact_information.dart b/lib/model/profile/basic_information/contact_information.dart new file mode 100644 index 0000000..3c182e9 --- /dev/null +++ b/lib/model/profile/basic_information/contact_information.dart @@ -0,0 +1,107 @@ +// To parse this JSON data, do +// +// final contactInformation = contactInformationFromJson(jsonString); + + +import '../../utils/agency.dart'; + +class ContactInfo { + ContactInfo({ + required this.id, + required this.active, + required this.primary, + required this.numbermail, + required this.commService, + }); + + int? id; + bool? active; + bool? primary; + String? numbermail; + CommService? commService; + + factory ContactInfo.fromJson(Map json) => ContactInfo( + id: json["id"], + active: json["active"], + primary: json["primary"], + numbermail: json["numbermail"], + commService: json["comm_service"]==null?null: CommService.fromJson(json["comm_service"]), + ); + + Map toJson() => { + "id": id, + "active": active, + "primary": primary, + "numbermail": numbermail, + "comm_service": commService!.toJson(), + }; +} + +class CommService { + CommService({ + required this.id, + required this.serviceType, + required this.serviceProvider, + }); + + int? id; + ServiceType? serviceType; + ServiceProvider? serviceProvider; + + factory CommService.fromJson(Map json) => CommService( + id: json["id"], + serviceType: json["service_type"]==null?null: ServiceType.fromJson(json["service_type"]), + serviceProvider: json["service_provider"] == null?null: ServiceProvider.fromJson(json["service_provider"]), + ); + + Map toJson() => { + "id": id, + "service_type": serviceType!.toJson(), + "service_provider": serviceProvider!.toJson(), + }; +} + +class ServiceProvider { + ServiceProvider({ + required this.id, + required this.alias, + required this.agency, + }); + + int? id; + String? alias; + Agency? agency; + + factory ServiceProvider.fromJson(Map json) => ServiceProvider( + id: json["id"], + alias: json["alias"], + agency: json["agency"] == null? null: Agency.fromJson(json["agency"]), + ); + + Map toJson() => { + "id": id, + "alias": alias, + "agency": agency!.toJson(), + }; +} + + +class ServiceType { + ServiceType({ + required this.id, + required this.name, + }); + + int? id; + String? name; + + factory ServiceType.fromJson(Map json) => ServiceType( + id: json["id"], + name: json["name"], + ); + + Map toJson() => { + "id": id, + "name": name, + }; +} diff --git a/lib/model/profile/basic_information/identification_information.dart b/lib/model/profile/basic_information/identification_information.dart new file mode 100644 index 0000000..61411c1 --- /dev/null +++ b/lib/model/profile/basic_information/identification_information.dart @@ -0,0 +1,110 @@ +import 'dart:convert'; + +import '../../location/city.dart'; +import '../../location/country.dart'; +import '../../utils/agency.dart'; + +Identification identificationFromJson(String str) => Identification.fromJson(json.decode(str)); + +String identificationToJson(Identification data) => json.encode(data.toJson()); + +class Identification { + Identification({ + required this.id, + required this.agency, + required this.issuedAt, + this.dateIssued, + this.expirationDate, + required this.asPdfReference, + required this.identificationNumber, + }); + + int? id; + Agency? agency; + IssuedAt? issuedAt; + DateTime? dateIssued; + DateTime? expirationDate; + bool? asPdfReference; + String? identificationNumber; + + factory Identification.fromJson(Map json) => Identification( + id: json["id"], + agency:json["agency"] == null? null: Agency.fromJson(json["agency"]), + issuedAt: json["issued_at"] == null? null:IssuedAt.fromJson(json["issued_at"]), + dateIssued:json["date_issued"]==null?null:DateTime.parse(json["date_issued"]), + expirationDate:json["expiration_date"]==null?null:DateTime.parse(json["expiration_date"]), + asPdfReference: json["as_pdf_reference"], + identificationNumber: json["identification_number"], + ); + + Map toJson() => { + "id": id, + "agency": agency!.toJson(), + "issued_at": issuedAt!.toJson(), + "date_issued": dateIssued, + "expiration_date": expirationDate, + "as_pdf_reference": asPdfReference, + "identification_number": identificationNumber, + }; +} + + +class IssuedAt { + IssuedAt({ + required this.id, + this.issuedAtClass, + required this.country, + this.barangay, + required this.addressCategory, + required this.cityMunicipality, + }); + + int? id; + dynamic issuedAtClass; + Country? country; + dynamic barangay; + AddressCategory? addressCategory; + CityMunicipality? cityMunicipality; + + factory IssuedAt.fromJson(Map json) => IssuedAt( + id: json["id"], + issuedAtClass: json["class"], + country: json['country'] == null? null: Country.fromJson(json["country"]), + barangay: json["barangay"], + addressCategory: json["address_category"] == null? null: AddressCategory.fromJson(json["address_category"]), + cityMunicipality:json["city_municipality"] == null? null: CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "class": issuedAtClass, + "country": country!.toJson(), + "barangay": barangay, + "address_category": addressCategory!.toJson(), + "city_municipality": cityMunicipality!.toJson(), + }; +} + +class AddressCategory { + AddressCategory({ + required this.id, + required this.name, + required this.type, + }); + + int? id; + String? name; + String? type; + + factory AddressCategory.fromJson(Map json) => AddressCategory( + id: json["id"], + name: json["name"], + type: json["type"], + ); + + Map toJson() => { + "id": id, + "name": name, + "type": type, + }; +} diff --git a/lib/model/profile/basic_information/primary-information.dart b/lib/model/profile/basic_information/primary-information.dart new file mode 100644 index 0000000..adb26f8 --- /dev/null +++ b/lib/model/profile/basic_information/primary-information.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +class PrimaryInformation { + PrimaryInformation({ + required this.id, + required this.lastName, + required this.firstName, + required this.middleName, + required this.nameExtension, + required this.sex, + required this.birthdate, + required this.civilStatus, + required this.bloodType, + required this.heightM, + required this.weightKg, + required this.photoPath, + required this.esigPath, + required this.maidenName, + required this.deceased, + required this.gender, + required this.uuidQrcode, + required this.titlePrefix, + required this.titleSuffix, + required this.showTitleId, + }); + + int? id; + String? lastName; + String? firstName; + String? middleName; + String? nameExtension; + String? sex; + DateTime? birthdate; + String? civilStatus; + String? bloodType; + double? heightM; + double? weightKg; + String? photoPath; + String? esigPath; + String? maidenName; + bool? deceased; + String? gender; + String? uuidQrcode; + String? titlePrefix; + String? titleSuffix; + bool? showTitleId; + + factory PrimaryInformation.fromJson(Map json) => + PrimaryInformation( + id: json["id"], + lastName: json["last_name"], + firstName: json["first_name"], + middleName: json["middle_name"], + nameExtension: json["name_extension"], + sex: json["sex"], + birthdate: json['birthdate']==null?null:DateTime.parse(json["birthdate"]), + civilStatus: json["civil_status"], + bloodType: json["blood_type"], + heightM: json["height_m"]?.toDouble(), + weightKg: json["weight_kg"], + photoPath: json["photo_path"], + esigPath: json["esig_path"], + maidenName: json["maiden_name"], + deceased: json["deceased"], + gender: json["gender"], + uuidQrcode: json["uuid_qrcode"], + titlePrefix: json["title_prefix"], + titleSuffix: json["title_suffix"], + showTitleId: json["show_title_id"], + ); + + Map toJson() => { + "id": id, + "last_name": lastName, + "first_name": firstName, + "middle_name": middleName, + "name_extension": nameExtension, + "sex": sex, + "birthdate": + "${birthdate!.year.toString().padLeft(4, '0')}-${birthdate!.month.toString().padLeft(2, '0')}-${birthdate!.day.toString().padLeft(2, '0')}", + "civil_status": civilStatus, + "blood_type": bloodType, + "height_m": heightM, + "weight_kg": weightKg, + "photo_path": photoPath, + "esig_path": esigPath, + "maiden_name": maidenName, + "deceased": deceased, + "gender": gender, + "uuid_qrcode": uuidQrcode, + "title_prefix": titlePrefix, + "title_suffix": titleSuffix, + "show_title_id": showTitleId, + }; +} diff --git a/lib/model/profile/educational_background.dart b/lib/model/profile/educational_background.dart new file mode 100644 index 0000000..83c2086 --- /dev/null +++ b/lib/model/profile/educational_background.dart @@ -0,0 +1,145 @@ +// To parse this JSON data, do +// +// final educationalBackground = educationalBackgroundFromJson(jsonString); + +import 'dart:convert'; + +EducationalBackground educationalBackgroundFromJson(String str) => EducationalBackground.fromJson(json.decode(str)); + +String educationalBackgroundToJson(EducationalBackground data) => json.encode(data.toJson()); + +class EducationalBackground { + EducationalBackground({ + this.id, + this.honors, + this.education, + this.periodTo, + this.attachments, + this.periodFrom, + this.unitsEarned, + this.yearGraduated, + }); + + final int? id; + final List? honors; + final Education? education; + final String? periodTo; + final dynamic attachments; + final String? periodFrom; + final dynamic unitsEarned; + final String? yearGraduated; + + factory EducationalBackground.fromJson(Map json) => EducationalBackground( + id: json["id"], + honors: json["honors"] == null ? [] : List.from(json["honors"]!.map((x) => Honor.fromJson(x))), + education: json["education"] == null ? null : Education.fromJson(json["education"]), + periodTo: json["period_to"], + attachments: json["attachments"], + periodFrom: json["period_from"], + unitsEarned: json["units_earned"], + yearGraduated: json["year_graduated"], + ); + + Map toJson() => { + "id": id, + "honors": honors == null ? [] : List.from(honors!.map((x) => x.toJson())), + "education": education?.toJson(), + "period_to": periodTo, + "attachments": attachments, + "period_from": periodFrom, + "units_earned": unitsEarned, + "year_graduated": yearGraduated, + }; +} + +class Education { + Education({ + this.id, + this.level, + this.course, + this.school, + }); + + final int? id; + final String? level; + final Course? course; + final School? school; + + factory Education.fromJson(Map json) => Education( + id: json["id"], + level: json["level"], + course: json["course"] == null ? null : Course.fromJson(json["course"]), + school: json["school"] == null ? null : School.fromJson(json["school"]), + ); + + Map toJson() => { + "id": id, + "level": level, + "course": course?.toJson(), + "school": school?.toJson(), + }; +} + +class Course { + Course({ + this.id, + this.program, + }); + + final int? id; + final String? program; + + factory Course.fromJson(Map json) => Course( + id: json["id"], + program: json["program"], + ); + + Map toJson() => { + "id": id, + "program": program, + }; +} + +class School { + School({ + this.id, + this.name, + }); + + final int? id; + final String? name; + + factory School.fromJson(Map json) => School( + id: json["id"], + name: json["name"], + ); + + Map toJson() => { + "id": id, + "name": name, + }; +} + +class Honor { + Honor({ + this.id, + this.name, + this.academ, + }); + + final int? id; + final String? name; + final bool? academ; + + factory Honor.fromJson(Map json) => Honor( + id: json["id"], + name: json["name"], + academ: json["academ"], + ); + + Map toJson() => { + "id": id, + "name": name, + "academ": academ, + }; +} diff --git a/lib/model/profile/eligibility.dart b/lib/model/profile/eligibility.dart new file mode 100644 index 0000000..f57007d --- /dev/null +++ b/lib/model/profile/eligibility.dart @@ -0,0 +1,123 @@ +// To parse this JSON data, do +// +// final eligibity = eligibityFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'package:unit2/model/location/region.dart'; + +import '../location/address_category.dart'; +import '../location/city.dart'; +import '../location/country.dart'; +import '../utils/eligibility.dart'; + +EligibityCert eligibityFromJson(String str) => + EligibityCert.fromJson(json.decode(str)); + +String eligibityToJson(EligibityCert data) => json.encode(data.toJson()); + +class EligibityCert { + EligibityCert({ + required this.id, + required this.rating, + required this.examDate, + required this.attachments, + required this.eligibility, + required this.examAddress, + required this.validityDate, + required this.licenseNumber, + required this.overseas, + }); + bool? overseas; + final int? id; + final double? rating; + final DateTime? examDate; + final dynamic attachments; + final Eligibility? eligibility; + final ExamAddress? examAddress; + final DateTime? validityDate; + final String? licenseNumber; + + factory EligibityCert.fromJson(Map json) => EligibityCert( + id: json["id"], + rating: json["rating"]?.toDouble(), + examDate: json['exam_date'] == null + ? null + : DateTime.parse(json["exam_date"]), + attachments: null, + eligibility: json['eligibility'] == null + ? null + : Eligibility.fromJson(json["eligibility"]), + examAddress: json['exam_address'] == null + ? null + : ExamAddress.fromJson(json["exam_address"]), + validityDate: json['validity_date'] == null + ? null + : DateTime.parse(json["validity_date"]), + licenseNumber: json["license_number"], + overseas: null, + ); + + Map toJson() => { + "id": id, + "rating": rating, + "exam_date": + "${examDate!.year.toString().padLeft(4, '0')}-${examDate!.month.toString().padLeft(2, '0')}-${examDate!.day.toString().padLeft(2, '0')}", + "attachments": attachments, + "eligibility": eligibility!.toJson(), + "exam_address": examAddress!.toJson(), + "validity_date": "${validityDate!.year.toString().padLeft(4, '0')}-${validityDate!.month.toString().padLeft(2, '0')}-${validityDate!.day.toString().padLeft(2, '0')}", + "license_number": licenseNumber, + }; + @override + String toString() { + return 'eligibility:${eligibility.toString()}, rating:$rating, examDate:${examDate.toString()},validydate:${validityDate.toString()}, lisence:$licenseNumber, examAddress:${examAddress.toString()}'; + } +} + +class ExamAddress { + ExamAddress({ + required this.id, + required this.examAddressClass, + required this.country, + required this.barangay, + required this.addressCategory, + required this.cityMunicipality, + }); + + final int? id; + final dynamic examAddressClass; + final Country? country; + final dynamic barangay; + final AddressCategory? addressCategory; + final CityMunicipality? cityMunicipality; + + factory ExamAddress.fromJson(Map json) => ExamAddress( + id: json["id"], + examAddressClass: json["class"], + country: + json["country"] == null ? null : Country.fromJson(json["country"]), + barangay: json["barangay"], + addressCategory: json["address_category"] == null + ? null + : AddressCategory.fromJson(json["address_category"]), + cityMunicipality: json["city_municipality"] == null + ? null + : CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "class": examAddressClass, + "country": country!.toJson(), + "barangay": barangay, + "address_category": addressCategory!.toJson(), + "city_municipality": cityMunicipality!.toJson(), + }; + + @override + String toString() { + return 'country:${country.toString()} , address:${cityMunicipality.toString()}'; + } +} diff --git a/lib/model/profile/family_backround.dart b/lib/model/profile/family_backround.dart new file mode 100644 index 0000000..68275a1 --- /dev/null +++ b/lib/model/profile/family_backround.dart @@ -0,0 +1,247 @@ +// To parse this JSON data, do +// +// final familyBackground = familyBackgroundFromJson(jsonString); + +import 'dart:convert'; +import 'dart:ffi'; + +import '../utils/category.dart'; +import '../utils/position.dart'; + +FamilyBackground familyBackgroundFromJson(String str) => FamilyBackground.fromJson(json.decode(str)); + +String familyBackgroundToJson(FamilyBackground data) => json.encode(data.toJson()); + +class FamilyBackground { + FamilyBackground({ + this.company, + this.position, + this.relationship, + this.relatedPerson, + this.companyAddress, + this.emergencyContact, + this.incaseOfEmergency, + this.companyContactNumber, + }); + + final Company? company; + final Position? position; + final Relationship? relationship; + final RelatedPerson? relatedPerson; + final String? companyAddress; + final List? emergencyContact; + final bool? incaseOfEmergency; + final String? companyContactNumber; + + factory FamilyBackground.fromJson(Map json) => FamilyBackground( + company: json["company"] == null ? null : Company.fromJson(json["company"]), + position: json["position"] == null ? null : Position.fromJson(json["position"]), + relationship: json["relationship"] == null ? null : Relationship.fromJson(json["relationship"]), + relatedPerson: json["related_person"] == null ? null : RelatedPerson.fromJson(json["related_person"]), + companyAddress: json["company_address"], + emergencyContact: json["emergency_contact"] == null ? [] : List.from(json["emergency_contact"]!.map((x) => EmergencyContact.fromJson(x))), + incaseOfEmergency: json["incase_of_emergency"], + companyContactNumber: json["company_contact_number"], + ); + + Map toJson() => { + "company": company?.toJson(), + "position": position?.toJson(), + "relationship": relationship?.toJson(), + "related_person": relatedPerson?.toJson(), + "company_address": companyAddress, + "emergency_contact": emergencyContact == null ? [] : List.from(emergencyContact!.map((x) => x.toJson())), + "incase_of_emergency": incaseOfEmergency, + "company_contact_number": companyContactNumber, + }; +} + +class Company { + Company({ + this.id, + this.name, + this.category, + this.privateEntity, + }); + + final int? id; + final String? name; + final Category? category; + final bool? privateEntity; + + factory Company.fromJson(Map json) => Company( + id: json["id"], + name: json["name"], + category: json["category"] == null ? null : Category.fromJson(json["category"]), + privateEntity: json["private_entity"], + ); + + Map toJson() => { + "id": id, + "name": name, + "category": category?.toJson(), + "private_entity": privateEntity, + }; +} + + +class EmergencyContact { + EmergencyContact({ + this.telco, + this.isactive, + this.provider, + this.isprimary, + this.numbermail, + this.serviceType, + this.contactinfoid, + this.commServiceId, + }); + + final String? telco; + final bool? isactive; + final int? provider; + final bool? isprimary; + final String? numbermail; + final int? serviceType; + final int? contactinfoid; + final int? commServiceId; + + factory EmergencyContact.fromJson(Map json) => EmergencyContact( + telco: json["telco"], + isactive: json["isactive"], + provider: json["provider"], + isprimary: json["isprimary"], + numbermail: json["numbermail"], + serviceType: json["service_type"], + contactinfoid: json["contactinfoid"], + commServiceId: json["comm_service_id"], + ); + + Map toJson() => { + "telco": telco, + "isactive": isactive, + "provider": provider, + "isprimary": isprimary, + "numbermail": numbermail, + "service_type": serviceType, + "contactinfoid": contactinfoid, + "comm_service_id": commServiceId, + }; +} + + +class RelatedPerson { + RelatedPerson({ + this.id, + this.sex, + this.gender, + this.deceased, + this.heightM, + this.birthdate, + this.esigPath, + this.lastName, + this.weightKg, + this.bloodType, + this.firstName, + this.photoPath, + this.maidenName, + this.middleName, + this.uuidQrcode, + this.civilStatus, + this.titlePrefix, + this.titleSuffix, + this.showTitleId, + this.nameExtension, + }); + + final int? id; + final String? sex; + final String? gender; + final bool? deceased; + final double? heightM; + final DateTime? birthdate; + final String? esigPath; + final String? lastName; + final double? weightKg; + final String? bloodType; + final String? firstName; + final String? photoPath; + final dynamic maidenName; + final String? middleName; + final String? uuidQrcode; + final String? civilStatus; + final String? titlePrefix; + final String? titleSuffix; + final bool? showTitleId; + final String? nameExtension; + + factory RelatedPerson.fromJson(Map json) => RelatedPerson( + id: json["id"], + sex: json["sex"], + gender: json["gender"], + deceased: json["deceased"], + heightM: json["height_m"] == null?null:double.parse(json["height_m"].toString()), + birthdate: json["birthdate"] == null ? null : DateTime.parse(json["birthdate"]), + esigPath: json["esig_path"], + lastName: json["last_name"], + weightKg: json["weight_kg"] == null? null:double.parse(json["weight_kg"].toString()) , + bloodType: json["blood_type"], + firstName: json["first_name"], + photoPath: json["photo_path"], + maidenName: json["maiden_name"], + middleName: json["middle_name"], + uuidQrcode: json["uuid_qrcode"], + civilStatus: json["civil_status"], + titlePrefix: json["title_prefix"], + titleSuffix: json["title_suffix"], + showTitleId: json["show_title_id"], + nameExtension: json["name_extension"], + ); + + Map toJson() => { + "id": id, + "sex": sex, + "gender": gender, + "deceased": deceased, + "height_m": heightM, + "birthdate": "${birthdate!.year.toString().padLeft(4, '0')}-${birthdate!.month.toString().padLeft(2, '0')}-${birthdate!.day.toString().padLeft(2, '0')}", + "esig_path": esigPath, + "last_name": lastName, + "weight_kg": weightKg, + "blood_type": bloodType, + "first_name": firstName, + "photo_path": photoPath, + "maiden_name": maidenName, + "middle_name": middleName, + "uuid_qrcode": uuidQrcode, + "civil_status": civilStatus, + "title_prefix": titlePrefix, + "title_suffix": titleSuffix, + "show_title_id": showTitleId, + "name_extension": nameExtension, + }; +} + +class Relationship { + Relationship({ + this.id, + this.type, + this.category, + }); + + final int? id; + final String? type; + final String? category; + + factory Relationship.fromJson(Map json) => Relationship( + id: json["id"], + type: json["type"], + category: json["category"], + ); + + Map toJson() => { + "id": id, + "type": type, + "category": category, + }; +} diff --git a/lib/model/profile/learning_development.dart b/lib/model/profile/learning_development.dart new file mode 100644 index 0000000..ce7a045 --- /dev/null +++ b/lib/model/profile/learning_development.dart @@ -0,0 +1,231 @@ +// To parse this JSON data, do +// +// final learningDevelopement = learningDevelopementFromJson(jsonString); + +import 'dart:convert'; + +import '../location/city.dart'; +import '../location/country.dart'; +import '../utils/industry_class.dart'; + +LearningDevelopement learningDevelopementFromJson(String str) => LearningDevelopement.fromJson(json.decode(str)); + +String learningDevelopementToJson(LearningDevelopement data) => json.encode(data.toJson()); + +class LearningDevelopement { + LearningDevelopement({ + this.attachments, + this.sponsoredBy, + this.conductedTraining, + this.totalHoursAttended, + }); + + final dynamic attachments; + final EdBy? sponsoredBy; + final ConductedTraining? conductedTraining; + final double? totalHoursAttended; + + factory LearningDevelopement.fromJson(Map json) => LearningDevelopement( + attachments: json["attachments"], + sponsoredBy: json["sponsored_by"] == null ? null : EdBy.fromJson(json["sponsored_by"]), + conductedTraining: json["conducted_training"] == null ? null : ConductedTraining.fromJson(json["conducted_training"]), + totalHoursAttended: json["total_hours_attended"], + ); + + Map toJson() => { + "attachments": attachments, + "sponsored_by": sponsoredBy?.toJson(), + "conducted_training": conductedTraining?.toJson(), + "total_hours_attended": totalHoursAttended, + }; +} + +class ConductedTraining { + ConductedTraining({ + this.id, + this.title, + this.topic, + this.venue, + this.locked, + this.toDate, + this.fromDate, + this.totalHours, + this.conductedBy, + this.sessionsAttended, + this.learningDevelopmentType, + }); + + final int? id; + final LearningDevelopmentType? title; + final LearningDevelopmentType? topic; + final Venue? venue; + final bool? locked; + final DateTime? toDate; + final DateTime? fromDate; + final int? totalHours; + final EdBy? conductedBy; + final List? sessionsAttended; + final LearningDevelopmentType? learningDevelopmentType; + + factory ConductedTraining.fromJson(Map json) => ConductedTraining( + id: json["id"], + title: json["title"] == null ? null : LearningDevelopmentType.fromJson(json["title"]), + topic: json["topic"] == null ? null : LearningDevelopmentType.fromJson(json["topic"]), + venue: json["venue"] == null ? null : Venue.fromJson(json["venue"]), + locked: json["locked"], + toDate: json["to_date"] == null ? null : DateTime.parse(json["to_date"]), + fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]), + totalHours: json["total_hours"], + conductedBy: json["conducted_by"] == null ? null : EdBy.fromJson(json["conducted_by"]), + sessionsAttended: json["sessions_attended"] == null ? [] : List.from(json["sessions_attended"]!.map((x) => x)), + learningDevelopmentType: json["learning_development_type"] == null ? null : LearningDevelopmentType.fromJson(json["learning_development_type"]), + ); + + Map toJson() => { + "id": id, + "title": title?.toJson(), + "topic": topic?.toJson(), + "venue": venue?.toJson(), + "locked": locked, + "to_date": "${toDate!.year.toString().padLeft(4, '0')}-${toDate!.month.toString().padLeft(2, '0')}-${toDate!.day.toString().padLeft(2, '0')}", + "from_date": "${fromDate!.year.toString().padLeft(4, '0')}-${fromDate!.month.toString().padLeft(2, '0')}-${fromDate!.day.toString().padLeft(2, '0')}", + "total_hours": totalHours, + "conducted_by": conductedBy?.toJson(), + "sessions_attended": sessionsAttended == null ? [] : List.from(sessionsAttended!.map((x) => x)), + "learning_development_type": learningDevelopmentType?.toJson(), + }; +} + +class EdBy { + EdBy({ + this.id, + this.name, + this.category, + this.privateEntity, + }); + + final int? id; + final String? name; + final SponsoredByCategory? category; + final bool? privateEntity; + + factory EdBy.fromJson(Map json) => EdBy( + id: json["id"], + name: json["name"], + category: json["category"] == null ? null : SponsoredByCategory.fromJson(json["category"]), + privateEntity: json["private_entity"], + ); + + Map toJson() => { + "id": id, + "name": name, + "category": category?.toJson(), + "private_entity": privateEntity, + }; +} + +class SponsoredByCategory { + SponsoredByCategory({ + this.id, + this.name, + this.industryClass, + }); + + final int? id; + final String? name; + final IndustryClass? industryClass; + + factory SponsoredByCategory.fromJson(Map json) => SponsoredByCategory( + id: json["id"], + name: json["name"], + industryClass: json["industry_class"] == null ? null : IndustryClass.fromJson(json["industry_class"]), + ); + + Map toJson() => { + "id": id, + "name": name, + "industry_class": industryClass?.toJson(), + }; +} + + +class LearningDevelopmentType { + LearningDevelopmentType({ + this.id, + this.title, + }); + + final int? id; + final String? title; + + factory LearningDevelopmentType.fromJson(Map json) => LearningDevelopmentType( + id: json["id"], + title: json["title"], + ); + + Map toJson() => { + "id": id, + "title": title, + }; +} + +class Venue { + Venue({ + this.id, + this.country, + this.barangay, + this.category, + this.areaClass, + this.cityMunicipality, + }); + + final int? id; + final Country? country; + final dynamic barangay; + final VenueCategory? category; + final dynamic areaClass; + final CityMunicipality? cityMunicipality; + + factory Venue.fromJson(Map json) => Venue( + id: json["id"], + country: json["country"] == null ? null : Country.fromJson(json["country"]), + barangay: json["barangay"], + category: json["category"] == null ? null : VenueCategory.fromJson(json["category"]), + areaClass: json["area_class"], + cityMunicipality: json["city_municipality"] == null ? null : CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "country": country?.toJson(), + "barangay": barangay, + "category": category?.toJson(), + "area_class": areaClass, + "city_municipality": cityMunicipality?.toJson(), + }; +} + +class VenueCategory { + VenueCategory({ + this.id, + this.name, + this.type, + }); + + final int? id; + final String? name; + final String? type; + + factory VenueCategory.fromJson(Map json) => VenueCategory( + id: json["id"], + name: json["name"], + type: json["type"], + ); + + Map toJson() => { + "id": id, + "name": name, + "type": type, + }; +} + diff --git a/lib/model/profile/other_information/non_acedimic_recognition.dart b/lib/model/profile/other_information/non_acedimic_recognition.dart new file mode 100644 index 0000000..7d277e0 --- /dev/null +++ b/lib/model/profile/other_information/non_acedimic_recognition.dart @@ -0,0 +1,37 @@ +// To parse this JSON data, do +// +// final nonAcademicRecognition = nonAcademicRecognitionFromJson(jsonString); + +import 'dart:convert'; + +import 'package:unit2/model/utils/agency.dart'; + +NonAcademicRecognition nonAcademicRecognitionFromJson(String str) => NonAcademicRecognition.fromJson(json.decode(str)); + +String nonAcademicRecognitionToJson(NonAcademicRecognition data) => json.encode(data.toJson()); + +class NonAcademicRecognition { + NonAcademicRecognition({ + this.id, + this.title, + this.presenter, + }); + + final int? id; + final String? title; + final Agency? presenter; + + factory NonAcademicRecognition.fromJson(Map json) => NonAcademicRecognition( + id: json["id"], + title: json["title"], + presenter: json["presenter"] == null ? null : Agency.fromJson(json["presenter"]), + ); + + Map toJson() => { + "id": id, + "title": title, + "presenter": presenter?.toJson(), + }; +} + + diff --git a/lib/model/profile/other_information/organization_memberships.dart b/lib/model/profile/other_information/organization_memberships.dart new file mode 100644 index 0000000..9d690a4 --- /dev/null +++ b/lib/model/profile/other_information/organization_memberships.dart @@ -0,0 +1,29 @@ +// To parse this JSON data, do +// +// final organizationMembership = organizationMembershipFromJson(jsonString); + +import 'dart:convert'; + +import '../../utils/agency.dart'; + +OrganizationMembership organizationMembershipFromJson(String str) => OrganizationMembership.fromJson(json.decode(str)); + +String organizationMembershipToJson(OrganizationMembership data) => json.encode(data.toJson()); + +class OrganizationMembership { + OrganizationMembership({ + this.agency, + }); + + final Agency? agency; + + factory OrganizationMembership.fromJson(Map json) => OrganizationMembership( + agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]), + ); + + Map toJson() => { + "agency": agency?.toJson(), + }; +} + + diff --git a/lib/model/profile/other_information/skills_and_hobbies.dart b/lib/model/profile/other_information/skills_and_hobbies.dart new file mode 100644 index 0000000..4d7cff3 --- /dev/null +++ b/lib/model/profile/other_information/skills_and_hobbies.dart @@ -0,0 +1,29 @@ +// To parse this JSON data, do +// +// final skillsHobbies = skillsHobbiesFromJson(jsonString); + +import 'dart:convert'; + +SkillsHobbies skillsHobbiesFromJson(String str) => SkillsHobbies.fromJson(json.decode(str)); + +String skillsHobbiesToJson(SkillsHobbies data) => json.encode(data.toJson()); + +class SkillsHobbies { + SkillsHobbies({ + this.id, + this.name, + }); + + final int? id; + final String? name; + + factory SkillsHobbies.fromJson(Map json) => SkillsHobbies( + id: json["id"], + name: json["name"], + ); + + Map toJson() => { + "id": id, + "name": name, + }; +} diff --git a/lib/model/profile/profileInfomation.dart b/lib/model/profile/profileInfomation.dart new file mode 100644 index 0000000..53fc065 --- /dev/null +++ b/lib/model/profile/profileInfomation.dart @@ -0,0 +1,22 @@ +import 'package:unit2/model/profile/basic_info.dart'; +import 'package:unit2/model/profile/basic_information/primary-information.dart'; +import 'package:unit2/model/profile/educational_background.dart'; +import 'package:unit2/model/profile/eligibility.dart'; +import 'package:unit2/model/profile/family_backround.dart'; +import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/model/profile/references.dart'; +import 'package:unit2/model/profile/voluntary_works.dart'; +import 'package:unit2/model/profile/work_history.dart'; + +class ProfileInformation{ + final BasicInfo basicInfo; + // OtherInformation otherInformation; + // List eligibilities; + // List references; + // List learningsAndDevelopment; + // List educationalBackgrounds; + // List families; + // ListworkExperiences; + // List voluntaryWorks; + ProfileInformation({required this.basicInfo}); +} \ No newline at end of file diff --git a/lib/model/profile/references.dart b/lib/model/profile/references.dart new file mode 100644 index 0000000..d7e1e05 --- /dev/null +++ b/lib/model/profile/references.dart @@ -0,0 +1,84 @@ +// To parse this JSON data, do +// +// final references = referencesFromJson(jsonString); +import '../location/address_category.dart'; +import '../location/barangay.dart'; +import '../location/city.dart'; +import '../location/country.dart'; +import '../location/provinces.dart'; + +class PersonalReference { + PersonalReference({ + required this.id, + required this.address, + required this.lastName, + required this.contactNo, + required this.firstName, + required this.middleName, + }); + + final int? id; + final Address? address; + final String? lastName; + final String? contactNo; + final String? firstName; + final String? middleName; + + factory PersonalReference.fromJson(Map json) => PersonalReference( + id: json["id"], + address: json['address'] == null?null: Address.fromJson(json["address"]), + lastName: json["last_name"], + contactNo: json["contact_no"], + firstName: json["first_name"], + middleName: json["middle_name"], + ); + + Map toJson() => { + "id": id, + "address": address!.toJson(), + "last_name": lastName, + "contact_no": contactNo, + "first_name": firstName, + "middle_name": middleName, + }; +} + +class Address { + Address({ + required this.id, + required this.addressClass, + required this.country, + required this.barangay, + required this.addressCategory, + required this.cityMunicipality, + }); + + final int? id; + final String? addressClass; + final Country? country; + final Barangay? barangay; + final AddressCategory? addressCategory; + final CityMunicipality? cityMunicipality; + + factory Address.fromJson(Map json) => Address( + id: json["id"], + addressClass: json["class"], + country: json['country']== null?null: Country.fromJson(json["country"]), + barangay:json["barangay"]== null?null: Barangay.fromJson(json["barangay"]), + addressCategory: json["address_category"]== null? null: AddressCategory.fromJson(json["address_category"]), + cityMunicipality: json["city_municipality"]==null?null: CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "class": addressClass, + "country": country!.toJson(), + "barangay": barangay!.toJson(), + "address_category": addressCategory!.toJson(), + "city_municipality": cityMunicipality!.toJson(), + }; +} + + + + diff --git a/lib/model/profile/voluntary_works.dart b/lib/model/profile/voluntary_works.dart new file mode 100644 index 0000000..8f5cdae --- /dev/null +++ b/lib/model/profile/voluntary_works.dart @@ -0,0 +1,95 @@ +// To parse this JSON data, do +// +// final voluntaryWork = voluntaryWorkFromJson(jsonString); + +import 'dart:convert'; + +import '../location/address_category.dart'; +import '../location/city.dart'; +import '../location/country.dart'; +import '../utils/agency.dart'; +import '../utils/position.dart'; + +VoluntaryWork voluntaryWorkFromJson(String str) => VoluntaryWork.fromJson(json.decode(str)); + +String voluntaryWorkToJson(VoluntaryWork data) => json.encode(data.toJson()); + +class VoluntaryWork { + VoluntaryWork({ + this.agency, + this.address, + this.toDate, + this.position, + this.fromDate, + this.totalHours, + }); + + final Agency? agency; + final Address? address; + final DateTime? toDate; + final Position? position; + final DateTime? fromDate; + final int? totalHours; + + factory VoluntaryWork.fromJson(Map json) => VoluntaryWork( + agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]), + address: json["address"] == null ? null : Address.fromJson(json["address"]), + toDate: json["to_date"] == null? null : DateTime.parse(json['to_data']), + position: json["position"] == null ? null : Position.fromJson(json["position"]), + fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]), + totalHours: json["total_hours"], + ); + + Map toJson() => { + "agency": agency?.toJson(), + "address": address?.toJson(), + "to_date": toDate, + "position": position?.toJson(), + "from_date": "${fromDate!.year.toString().padLeft(4, '0')}-${fromDate!.month.toString().padLeft(2, '0')}-${fromDate!.day.toString().padLeft(2, '0')}", + "total_hours": totalHours, + }; +} + +class Address { + Address({ + this.id, + this.addressClass, + this.country, + this.barangay, + this.addressCategory, + this.cityMunicipality, + }); + + final int? id; + final dynamic addressClass; + final Country? country; + final dynamic barangay; + final AddressCategory? addressCategory; + final CityMunicipality? cityMunicipality; + + factory Address.fromJson(Map json) => Address( + id: json["id"], + addressClass: json["class"], + country: json["country"] == null ? null : Country.fromJson(json["country"]), + barangay: json["barangay"], + addressCategory: json["address_category"] == null ? null : AddressCategory.fromJson(json["address_category"]), + cityMunicipality: json["city_municipality"] == null ? null : CityMunicipality.fromJson(json["city_municipality"]), + ); + + Map toJson() => { + "id": id, + "class": addressClass, + "country": country?.toJson(), + "barangay": barangay, + "address_category": addressCategory?.toJson(), + "city_municipality": cityMunicipality?.toJson(), + }; +} + + + + + + + + diff --git a/lib/model/profile/work_history.dart b/lib/model/profile/work_history.dart new file mode 100644 index 0000000..821e603 --- /dev/null +++ b/lib/model/profile/work_history.dart @@ -0,0 +1,74 @@ +// To parse this JSON data, do +// +// final workHistory = workHistoryFromJson(jsonString); + +import 'dart:convert'; + +import '../utils/agency.dart'; +import '../utils/category.dart'; +import '../utils/industry_class.dart'; +import '../utils/position.dart'; + +WorkHistory workHistoryFromJson(String str) => WorkHistory.fromJson(json.decode(str)); + +String workHistoryToJson(WorkHistory data) => json.encode(data.toJson()); + +class WorkHistory { + WorkHistory({ + this.id, + this.agency, + this.sgStep, + this.toDate, + this.position, + this.fromDate, + // this.attachments, + this.salaryGrade, + this.monthlySalary, + this.appointmentStatus, + }); + + final int? id; + final Agency? agency; + final int? sgStep; + final DateTime? toDate; + final Position? position; + final DateTime? fromDate; + // final dynamic attachments; + final int? salaryGrade; + final double? monthlySalary; + final String? appointmentStatus; + + factory WorkHistory.fromJson(Map json) => WorkHistory( + id: json["id"], + agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]), + sgStep: json["sg_step"], + toDate: json["to_date"] == null ? null : DateTime.parse(json["to_date"]), + position: json["position"] == null ? null : Position.fromJson(json["position"]), + fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]), + // attachments: json["attachments"], + salaryGrade: json["salary_grade"], + monthlySalary: json["monthly_salary"], + appointmentStatus: json["appointment_status"], + ); + + Map toJson() => { + "id": id, + "agency": agency?.toJson(), + "sg_step": sgStep, + "to_date": "${toDate!.year.toString().padLeft(4, '0')}-${toDate!.month.toString().padLeft(2, '0')}-${toDate!.day.toString().padLeft(2, '0')}", + "position": position?.toJson(), + "from_date": "${fromDate!.year.toString().padLeft(4, '0')}-${fromDate!.month.toString().padLeft(2, '0')}-${fromDate!.day.toString().padLeft(2, '0')}", + // "attachments": attachments, + "salary_grade": salaryGrade, + "monthly_salary": monthlySalary, + "appointment_status": appointmentStatus, + }; +} + + + + + + + + diff --git a/lib/model/utils/agency.dart b/lib/model/utils/agency.dart new file mode 100644 index 0000000..68056fb --- /dev/null +++ b/lib/model/utils/agency.dart @@ -0,0 +1,29 @@ +import 'package:unit2/model/utils/category.dart'; + +class Agency { + Agency({ + this.id, + this.name, + this.category, + this.privateEntity, + }); + + final int? id; + final String? name; + final Category? category; + final bool? privateEntity; + + factory Agency.fromJson(Map json) => Agency( + id: json["id"], + name: json["name"], + category: json["category"] == null ? null : Category.fromJson(json["category"]), + privateEntity: json["private_entity"], + ); + + Map toJson() => { + "id": id, + "name": name, + "category": category?.toJson(), + "private_entity": privateEntity, + }; +} \ No newline at end of file diff --git a/lib/model/utils/agency_position.dart b/lib/model/utils/agency_position.dart new file mode 100644 index 0000000..f2d4f01 --- /dev/null +++ b/lib/model/utils/agency_position.dart @@ -0,0 +1,31 @@ + +import 'dart:convert'; + + +// To parse this JSON data, do +// +// final appoinemtStatus = appoinemtStatusFromJson(jsonString); +AppoinemtStatus appoinemtStatusFromJson(String str) => AppoinemtStatus.fromJson(json.decode(str)); + +String appoinemtStatusToJson(AppoinemtStatus data) => json.encode(data.toJson()); + +class AppoinemtStatus { + AppoinemtStatus({ + required this.value, + required this.label, + }); + + final String value; + final String label; + + factory AppoinemtStatus.fromJson(Map json) => AppoinemtStatus( + value: json["value"], + label: json["label"], + ); + + Map toJson() => { + "value": value, + "label": label, + }; +} + diff --git a/lib/model/utils/category.dart b/lib/model/utils/category.dart new file mode 100644 index 0000000..8319067 --- /dev/null +++ b/lib/model/utils/category.dart @@ -0,0 +1,25 @@ +import 'package:unit2/model/utils/industry_class.dart'; + +class Category { + Category({ + this.id, + this.name, + this.industryClass, + }); + + final int? id; + final String? name; + final IndustryClass? industryClass; + + factory Category.fromJson(Map json) => Category( + id: json["id"], + name: json["name"], + industryClass: json["industry_class"] == null ? null : IndustryClass.fromJson(json["industry_class"]), + ); + + Map toJson() => { + "id": id, + "name": name, + "industry_class": industryClass?.toJson(), + }; +} \ No newline at end of file diff --git a/lib/model/utils/eligibility.dart b/lib/model/utils/eligibility.dart new file mode 100644 index 0000000..b2ec606 --- /dev/null +++ b/lib/model/utils/eligibility.dart @@ -0,0 +1,39 @@ +// To parse this JSON data, do +// +// final eligibilities = eligibilitiesFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +Eligibility eligibilitiesFromJson(String str) => Eligibility.fromJson(json.decode(str)); + +String eligibilitiesToJson(Eligibility data) => json.encode(data.toJson()); + +class Eligibility { + Eligibility({ + required this.id, + required this.title, + required this.type, + }); + + final int id; + final String title; + final String type; + + factory Eligibility.fromJson(Map json) => Eligibility( + id: json["id"], + title: json["title"], + type: json["type"], + ); + + Map toJson() => { + "id": id, + "title": title, + "type": type, + }; + @override + String toString() { +return title; + + } +} diff --git a/lib/model/utils/industry_class.dart b/lib/model/utils/industry_class.dart new file mode 100644 index 0000000..c6bb4bf --- /dev/null +++ b/lib/model/utils/industry_class.dart @@ -0,0 +1,23 @@ +class IndustryClass { + IndustryClass({ + this.id, + this.name, + this.description, + }); + + final int? id; + final String? name; + final String? description; + + factory IndustryClass.fromJson(Map json) => IndustryClass( + id: json["id"], + name: json["name"], + description: json["description"], + ); + + Map toJson() => { + "id": id, + "name": name, + "description": description, + }; +} \ No newline at end of file diff --git a/lib/model/utils/position.dart b/lib/model/utils/position.dart new file mode 100644 index 0000000..ff7ba26 --- /dev/null +++ b/lib/model/utils/position.dart @@ -0,0 +1,19 @@ +class Position { + Position({ + this.id, + this.title, + }); + + final int? id; + final String? title; + + factory Position.fromJson(Map json) => Position( + id: json["id"], + title: json["title"], + ); + + Map toJson() => { + "id": id, + "title": title, + }; +} \ No newline at end of file diff --git a/lib/screens/profile/components/basic_information/address_screen.dart b/lib/screens/profile/components/basic_information/address_screen.dart new file mode 100644 index 0000000..b394883 --- /dev/null +++ b/lib/screens/profile/components/basic_information/address_screen.dart @@ -0,0 +1,166 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/basic_information/adress.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; + +class AddressScreen extends StatelessWidget { + + const AddressScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text(adressScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: ProgressHUD( + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is AddressLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is AddressLoadedState || + state is AddressErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is AddressLoadedState) { + if (state.addresses.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.addresses.length, + itemBuilder: + (BuildContext context, int index) { + String? subdivision = + state.addresses[index].details ?? ''; + String category = state.addresses[index] + .address! + .category! + .name!; + String? barangay = state.addresses[index] + .address! + .barangay != + null + ? '${state.addresses[index].address!.barangay!.description!.toUpperCase()},' + : ''; + String cityMunicipality = state.addresses[index] + .address! + .cityMunicipality! + .description!; + String province = state.addresses[index] + .address! + .cityMunicipality! + .province! + .description!; + String region = state.addresses[index] + .address! + .cityMunicipality! + .province! + .region! + .description!; + return Column( + children: [ + Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: + const EdgeInsets.fromLTRB( + 8, 16, 0, 16), + child: Row(children: [ + Expanded( + child: Column( + children: [ + Row( + children: [ + Text( + subdivision, + style: + Theme.of(context) + .textTheme + .titleMedium, + ), + const SizedBox( + width: 5, + ), + Text( + category, + style: + Theme.of(context) + .textTheme + .bodySmall, + ) + ], + ), + const Divider(), + const SizedBox( + height: 5, + ), + Text( + "$barangay $cityMunicipality, $province, $region", + style: Theme.of(context) + .textTheme + .labelLarge, + ), + ], + )), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ]), + ), + ], + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have address added. Please click + to add."); + } + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} diff --git a/lib/screens/profile/components/basic_information/citizenship_screen.dart b/lib/screens/profile/components/basic_information/citizenship_screen.dart new file mode 100644 index 0000000..f826806 --- /dev/null +++ b/lib/screens/profile/components/basic_information/citizenship_screen.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:unit2/model/profile/basic_information/citizenship.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; + +class CitizenShipScreen extends StatefulWidget { + final List citizenships; + const CitizenShipScreen({super.key, required this.citizenships}); + + @override + State createState() => _CitizenShipScreenState(); +} + +class _CitizenShipScreenState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text(citizenshipScreenTitle),centerTitle: true, + backgroundColor: primary, + ), + body: widget.citizenships.isEmpty? + Container( + width: screenWidth, + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: const BorderRadius.all(Radius.circular(12))), + + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("Philippines",style: Theme.of(context).textTheme.titleLarge,), + Text("Filipino",style: Theme.of(context).textTheme.titleSmall,) + ], + + + ), + ):Container() + , + ); + } +} \ No newline at end of file diff --git a/lib/screens/profile/components/basic_information/contact_information/add_modal.dart b/lib/screens/profile/components/basic_information/contact_information/add_modal.dart new file mode 100644 index 0000000..40c2494 --- /dev/null +++ b/lib/screens/profile/components/basic_information/contact_information/add_modal.dart @@ -0,0 +1,243 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:fluttericon/entypo_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart'; +import 'package:unit2/sevices/profile/contact_services.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/text_container.dart'; + +import '../../../../../theme-data.dart/colors.dart'; + +class AddContactInformationScreen extends StatefulWidget { + final int profileId; + final String token; + const AddContactInformationScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => + _AddContactInformationScreenState(); +} + +class _AddContactInformationScreenState + extends State { + final formKey = GlobalKey(); + ServiceType? selectedServiceType; + CommService? selectedCommServiceProvider; + List commServiceProviders = []; + bool callServiceType = false; + bool primaryaContact = false; + bool active = false; + String? numberMail; + var mobileFormatter = MaskTextInputFormatter( + mask: "+63 (###) ###-####", + filter: {"#": RegExp(r"^[1-9][0-9]*$")}, + type: MaskAutoCompletionType.lazy, + initialText: "0"); + + var landLineFormatter = MaskTextInputFormatter( + mask: "(###) ###-###", + filter: {"#": RegExp(r"^[0-9]")}, + type: MaskAutoCompletionType.lazy, + initialText: "0"); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is ContactAddingState) { + return FormBuilder( + key: formKey, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 24, horizontal: 12), + child: Column( + children: [ + const SizedBox( + height: 24, + ), + ////Service Type + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "service_type", + items: state.serviceTypes + .map>( + (ServiceType e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + decoration: normalTextFieldStyle("Service Type*", ""), + onChanged: (var service) async { + if (selectedServiceType != service) { + selectedServiceType = service; + setState(() { + callServiceType = true; + }); + commServiceProviders = await ContactService.instance + .getServiceProvider( + serviceTypeId: selectedServiceType!.id!); + setState(() { + setState(() { + callServiceType = false; + }); + }); + } + }), + const SizedBox( + height: 12, + ), + ////Service Provider + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.transparent, + inAsyncCall: callServiceType, + child: FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "Service Provider", + items: commServiceProviders.isEmpty + ? [] + : commServiceProviders + .map>( + (CommService e) { + return DropdownMenuItem( + value: e, child: Text(e.serviceProvider!.agency!.name!)); + }).toList(), + decoration: normalTextFieldStyle( + "Communication Service *", ""), + onChanged: (var serviceProvider) { + selectedCommServiceProvider = serviceProvider; + }), + ), + ), + selectedServiceType != null + ? selectedServiceType?.id == 2 + //// Landline + ? FormBuilderTextField( + inputFormatters: [landLineFormatter], + name: 'number-mail', + validator: FormBuilderValidators.required( + errorText: "This field is required"), + decoration: normalTextFieldStyle( + "Landline number *", + "(area code) xxx - xxxx"), + ) + : selectedServiceType!.id == 1 || + selectedServiceType!.id == 19 + //// Mobile number + ? FormBuilderTextField( + name: 'number-mail', + inputFormatters: [mobileFormatter], + validator: FormBuilderValidators.required( + errorText: "This field is required"), + decoration: normalTextFieldStyle( + "Mobile number *", + "+63 (9xx) xxx - xxxx"), + ) + : selectedServiceType!.id == 4 + ////Social Media + ? FormBuilderTextField( + name: 'number-mail', + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + decoration: normalTextFieldStyle( + "Account ID / Username *", ""), + ) + : selectedServiceType!.id == 3 + ////Email Address + ? FormBuilderTextField( + name: 'number-mail', + validator: + FormBuilderValidators.compose([ + FormBuilderValidators.email( + errorText: + "Input vaild email"), + FormBuilderValidators.required( + errorText: + "This field is required") + ]), + decoration: normalTextFieldStyle( + "Email Address*", ""), + ) + : Container() + : const SizedBox(), + SizedBox( + height: selectedServiceType != null ? 12 : 0, + ), + //// Primary + FormBuilderSwitch( + initialValue: primaryaContact, + activeColor: second, + onChanged: (value) { + setState(() { + primaryaContact = value!; + }); + }, + decoration: normalTextFieldStyle("Primary?", 'Primary?'), + name: 'overseas', + title: Text(primaryaContact ? "YES" : "NO"), + ), + //// Active + const SizedBox( + height: 12, + ), + FormBuilderSwitch( + initialValue: primaryaContact, + activeColor: second, + onChanged: (value) { + setState(() { + active = value!; + }); + }, + decoration: normalTextFieldStyle("Active?", ''), + name: 'overseas', + title: Text(active ? "YES" : "NO"), + ), + const Expanded(child: SizedBox()), + SizedBox( + height: 60, + width: double.infinity, + child: ElevatedButton( + onPressed: () { + if (formKey.currentState!.saveAndValidate()) { + + numberMail = + formKey.currentState!.value['number-mail']; + CommService commService = selectedCommServiceProvider!; + ContactInfo contactInfo = ContactInfo( + id: null, + active: active, + primary: primaryaContact, + numbermail: numberMail, + commService: commService); + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add(AddContactInformation(contactInfo: contactInfo, profileId: widget.profileId, token: widget.token)); + } + }, + style: + mainBtnStyle(primary, Colors.transparent, second), + child: const Text(submit), + ), + ) + ], + ), + )); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/basic_information/contact_information/edit_modal.dart b/lib/screens/profile/components/basic_information/contact_information/edit_modal.dart new file mode 100644 index 0000000..e2c10a0 --- /dev/null +++ b/lib/screens/profile/components/basic_information/contact_information/edit_modal.dart @@ -0,0 +1,275 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:fluttericon/entypo_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart'; +import 'package:unit2/sevices/profile/contact_services.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/text_container.dart'; + +import '../../../../../theme-data.dart/colors.dart'; + +class EditContactInformationScreen extends StatefulWidget { + final int profileId; + final String token; + const EditContactInformationScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => + _EditContactInformationScreenState(); +} + +class _EditContactInformationScreenState + extends State { + final formKey = GlobalKey(); + ServiceType? selectedServiceType; + CommService? selectedCommProvider; + List commServiceProviders = []; + String? numberMail; + bool callServiceType = false; + bool? primaryaContact; + bool? active; + + var mobileFormatter = MaskTextInputFormatter( + mask: "+63 (###) ###-####", + filter: {"#": RegExp(r"^[1-9][0-9]*$")}, + type: MaskAutoCompletionType.lazy, + initialText: "0"); + + var landLineFormatter = MaskTextInputFormatter( + mask: "(###) ###-###", + filter: {"#": RegExp(r"^[0-9]")}, + type: MaskAutoCompletionType.lazy, + initialText: "0"); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is ContactEditingState) { + selectedServiceType = state.selectedServiceType; + selectedCommProvider = state.selectedProvider; + commServiceProviders = state.commServiceProviders; + primaryaContact = state.contactInfo.primary!; + active = state.contactInfo.active!; + return FormBuilder( + key: formKey, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 24, horizontal: 12), + child: Column( + children: [ + const SizedBox( + height: 24, + ), + StatefulBuilder(builder: (context, setState) { + return Column(children: [ + ////Service Type + DropdownButtonFormField( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + value: selectedServiceType, + items: state.serviceTypes + .map>( + (ServiceType e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + decoration: + normalTextFieldStyle("Service Type*", ""), + onChanged: (var service) async { + if (selectedServiceType!.id != service!.id) { + selectedServiceType = service; + setState(() { + callServiceType = true; + }); + commServiceProviders = await ContactService.instance + .getServiceProvider( + serviceTypeId: + selectedServiceType!.id!); + selectedCommProvider = null; + setState(() { + setState(() { + callServiceType = false; + }); + }); + } + }), + const SizedBox( + height: 12, + ), + ////Service Provider + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.transparent, + inAsyncCall: callServiceType, + child: DropdownButtonFormField( + value: selectedCommProvider, + validator: FormBuilderValidators.required( + errorText: "This field is required"), + items: commServiceProviders.isEmpty + ? [] + : commServiceProviders + .map>( + (CommService e) { + return DropdownMenuItem< + CommService>( + value: e, + child: Text(e.serviceProvider!.agency!.name!)); + }).toList(), + decoration: normalTextFieldStyle( + "Communication Service *", ""), + onChanged: (var commServiceProvider) { + selectedCommProvider = commServiceProvider; + }), + ), + ), + selectedServiceType != null + ? selectedServiceType?.id == 2 + //// Landline + ? FormBuilderTextField( + name: 'number-mail', + initialValue: state.contactInfo.numbermail, + inputFormatters: [landLineFormatter], + validator: FormBuilderValidators.required( + errorText: "This field is required"), + decoration: normalTextFieldStyle( + "Landline number *", + "(area code) xxx - xxxx"), + ) + : selectedServiceType!.id == 1 || + selectedServiceType!.id == 19 + //// Mobile number + ? FormBuilderTextField( + name: 'number-mail', + inputFormatters: [mobileFormatter], + initialValue: + state.contactInfo.numbermail, + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + decoration: normalTextFieldStyle( + "Mobile number *", + "+63 (9xx) xxx - xxxx"), + ) + : selectedServiceType!.id == 4 + ////Social Media + ? FormBuilderTextField( + name: 'number-mail', + initialValue: + state.contactInfo.numbermail, + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + decoration: normalTextFieldStyle( + "Account ID / Username *", ""), + ) + : selectedServiceType!.id == 3 + ////Email Address + ? FormBuilderTextField( + name: 'number-mail', + initialValue: state + .contactInfo.numbermail, + validator: FormBuilderValidators + .compose([ + FormBuilderValidators.email( + errorText: + "Input vaild email"), + FormBuilderValidators.required( + errorText: + "This field is required") + ]), + decoration: + normalTextFieldStyle( + "Email Address*", ""), + ) + : Container() + : const SizedBox(), + ]); + }), + SizedBox( + height: selectedServiceType != null ? 12 : 0, + ), + //// Primary + StatefulBuilder(builder: (context, setState) { + return FormBuilderSwitch( + initialValue: primaryaContact, + activeColor: second, + onChanged: (value) { + setState(() { + primaryaContact = value; + }); + }, + decoration: normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Primary ?"), + ); + }), + //// Active + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return FormBuilderSwitch( + initialValue: active, + activeColor: second, + onChanged: (value) { + setState(() { + active = value; + }); + }, + decoration: normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Active ?"), + ); + }), + const Expanded(child: SizedBox()), + SizedBox( + height: 60, + width: double.infinity, + child: ElevatedButton( + onPressed: () { + if (formKey.currentState!.saveAndValidate()) { + numberMail = + formKey.currentState!.value['number-mail']; + CommService commService = selectedCommProvider!; + ContactInfo contactInfo = ContactInfo( + id: state.contactInfo.id, + active: active, + primary: primaryaContact, + numbermail: numberMail, + commService: commService); + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add( + EditContactInformation( + contactInfo: contactInfo, + profileId: widget.profileId, + token: widget.token)); + } + }, + style: + mainBtnStyle(primary, Colors.transparent, second), + child: const Text(submit), + ), + ) + ], + ), + )); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/basic_information/contact_information_screen.dart b/lib/screens/profile/components/basic_information/contact_information_screen.dart new file mode 100644 index 0000000..b572c86 --- /dev/null +++ b/lib/screens/profile/components/basic_information/contact_information_screen.dart @@ -0,0 +1,369 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/screens/profile/components/basic_information/contact_information/add_modal.dart'; +import 'package:unit2/screens/profile/components/basic_information/contact_information/edit_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/alerts.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/Leadings/close_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; + +class ContactInformationScreen extends StatelessWidget { + const ContactInformationScreen({ + super.key, + }); + + @override + Widget build(BuildContext context) { + int profileId; + String token; + return SafeArea( + child: Scaffold( + appBar: AppBar( + title: const Text(contactScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: context.watch().state is ContactLoadedState? [ + AddLeading(onPressed: () { + context.read().add(ShowAddForm()); + }) + ]:( context.watch().state is ContactAddingState || context.watch().state is ContactEditingState)?[ + CloseLeading(onPressed: (){ + context.read().add(LoadContacts()); + }) + ]:[] + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token!; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is ContactLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ContactLoadedState || + state is ContactErrorState || + state is ContactAddingState || + state is ContactEditingState || + state is ContactDeletedState || + state is ContactAddedState || + state is ContactEditedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////ADDED CONTACT STATE + if (state is ContactAddedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } + } + + ////EDIT CONTACT STATE + if (state is ContactEditedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } + } + + ////DELETED STATE + if (state is ContactDeletedState) { + if (state.succcess) { + successAlert(context, "Deletion Successfull", + "Contact Info has been deleted successfully", + () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting Contact Info", () { + Navigator.of(context).pop(); + context.read().add(LoadContacts( + )); + }); + } + } + }, + builder: (context, state) { + if (state is ContactLoadedState) { + if (state.contactInformation.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.contactInformation.length, + itemBuilder: + (BuildContext context, int index) { + String numberMail = state + .contactInformation[index] + .numbermail!; + String commService = state + .contactInformation[index] + .commService! + .serviceProvider! + .alias!; + return Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.fromLTRB(12, 12, 0, 12), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Row( + children: [ + Expanded( + child: Text( + numberMail, + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500)), + ), + state.contactInformation[index] + .active == + true + ? const Badge( + backgroundColor: + Colors + .green, + label: Text( + "Active", + ), + ) + : const SizedBox(), + const SizedBox( + width: 5), + state.contactInformation[index] + .primary == + true + ? const Badge( + backgroundColor: + Colors + .blue, + label: Text( + "Primary"), + ) + : const SizedBox() + ], + ), + const Divider(), + const SizedBox( + height: 5, + ), + Row( + children: [ + Flexible( + flex: 2, + child: Text( + commService + .toString().toUpperCase(), + style: Theme.of( + context) + .textTheme + .titleSmall, + ), + ), + const SizedBox( + + child: Text(" - "), + ), + Flexible( + flex: 1, + child: Text(state + .contactInformation[ + index] + .commService! + .serviceProvider! + .agency! + .name + .toString()), + ), + ], + ), + ]), + ), + AppPopupMenu( + offset: + const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + ////delete contact-= = = = = = = = =>> + if (value == 2) { + final progress = + ProgressHUD.of( + context); + progress!.showWithText( + "Loading..."); + confirmAlert( + context, + () => context + .read< + ContactBloc>() + .add(DeleteContactInformation( + contactInfo: + state.contactInformation[ + index], + profileId: + profileId, + token: + token)), + "Delete?", + "Are you sure you want to delete this contact info?"); + } + if (value == 1) { + ////edit contact-= = = = = = = = =>> + context + .read() + .add(ShowEditForm( + contactInfo: state + .contactInformation[ + index])); + final progress = + ProgressHUD.of( + context); + progress!.showWithText( + "Loading..."); + } + }, + menuItems: [ + popMenuItem( + text: "Edit", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Delete", + value: 2, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have contact information added. Please click + to add"); + } + } + if (state is ContactAddingState) { + return AddContactInformationScreen( + profileId: profileId, + token: token, + ); + } + if (state is ContactEditingState) { + return EditContactInformationScreen( + profileId: profileId, token: token); + } + if (state is ContactErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () { + context.read().add(LoadContacts()); + }); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )), + ); + } + + PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); + } +} diff --git a/lib/screens/profile/components/basic_information/identification_information_screen.dart b/lib/screens/profile/components/basic_information/identification_information_screen.dart new file mode 100644 index 0000000..2d59569 --- /dev/null +++ b/lib/screens/profile/components/basic_information/identification_information_screen.dart @@ -0,0 +1,149 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/identification/identification_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/model/profile/basic_information/identification_information.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; + +import '../../../../bloc/user/user_bloc.dart'; + +class IdentificationsScreen extends StatelessWidget { + const IdentificationsScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text(identificationScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + if (state is IdentificationLoadedState) { + if (state.identificationInformation.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.identificationInformation.length, + itemBuilder: (BuildContext context, int index) { + String agency = + state.identificationInformation[index].agency!.name!; + String idNumber = + state.identificationInformation[index].identificationNumber!; + bool government = + state.identificationInformation[index].agency!.privateEntity!; + String issuedAt = + "${state.identificationInformation[index].issuedAt!.cityMunicipality!.description!} ${state.identificationInformation[index].issuedAt!.cityMunicipality!.province!.description}"; + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text(agency, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w400)), + const Divider(), + const SizedBox( + height: 5, + ), + Row(children: [ + Expanded( + child: Text( + "$idNumberText : $idNumber", + style: + Theme.of(context) + .textTheme + .titleSmall, + ), + ), + Badge( + backgroundColor: + success2, + label: Text( + government == true + ? privateText + .toUpperCase() + : governmentText + .toUpperCase(), + style: Theme.of( + context) + .textTheme + .bodySmall! + .copyWith( + color: Colors + .white), + )) + ]), + const SizedBox( + height: 5, + ), + Text(issuedAt), + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have identifications added. Please click + to add."); + } + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + )); + } +} diff --git a/lib/screens/profile/components/basic_information/primary_information_screen.dart b/lib/screens/profile/components/basic_information/primary_information_screen.dart new file mode 100644 index 0000000..3dddc42 --- /dev/null +++ b/lib/screens/profile/components/basic_information/primary_information_screen.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:intl/intl.dart'; +import 'package:unit2/model/profile/basic_information/primary-information.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; + +class PrimaryInfo extends StatefulWidget { + final PrimaryInformation primaryInformation; + const PrimaryInfo({super.key, required this.primaryInformation}); + + @override + State createState() => _PrimaryInfoState(); +} + +class _PrimaryInfoState extends State { + @override + Widget build(BuildContext context) { + final _formKey = GlobalKey(); + bool enabled = false; + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + return Scaffold( + appBar: AppBar( + title: const Text(primaryInformationScreenTitle), + centerTitle: true, + backgroundColor: primary, + ), + body: Container( + padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 24), + child: FormBuilder( + child: Column( + children: [ + FormBuilderTextField( + enabled: enabled, + name: lastname, + initialValue: widget.primaryInformation.lastName!, + decoration: normalTextFieldStyle("Last name", ""), + + ), + const SizedBox(height: 15,), + FormBuilderTextField( + enabled: enabled, + name: firstname, + initialValue: widget.primaryInformation.firstName!, + decoration: normalTextFieldStyle("First name", ""), + ), + const SizedBox(height: 15,), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 2, + child: FormBuilderTextField( + enabled: enabled, + name: middlename, + initialValue: widget.primaryInformation.middleName!, + decoration: normalTextFieldStyle("Middle name", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: extensionName, + initialValue: widget.primaryInformation.nameExtension??='N/A', + decoration: normalTextFieldStyle("Name extension", ""), + ),) + ]), + + ), + const SizedBox(height: 15,), + SizedBox(width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: extensionName, + initialValue: dteFormat2.format(widget.primaryInformation.birthdate!), + decoration: normalTextFieldStyle("Birth date", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: sex, + initialValue: widget.primaryInformation.sex!, + decoration: normalTextFieldStyle("Sex", ""), + ),) + ]),), + const SizedBox(height: 15,), + SizedBox(width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: bloodType, + initialValue:widget.primaryInformation.bloodType!, + decoration: normalTextFieldStyle("Blood type", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: civilStatus, + initialValue: widget.primaryInformation.civilStatus!, + decoration: normalTextFieldStyle("Civil Status", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: gender, + initialValue:widget.primaryInformation.gender??="N/A", + decoration: normalTextFieldStyle("Gender", ""), + ),), + ]),), + + const SizedBox(height: 15,), + SizedBox(width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: height, + initialValue:widget.primaryInformation.heightM!.toString(), + decoration: normalTextFieldStyle("Height", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: width, + initialValue: widget.primaryInformation.weightKg!.toString(), + decoration: normalTextFieldStyle("Weight", ""), + ),), + const SizedBox(width: 10,), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: prefixSuffix, + initialValue:"${widget.primaryInformation.titlePrefix??="NA"} | ${widget.primaryInformation.titleSuffix??="N/A"}", + decoration: normalTextFieldStyle("Title Prefix and Suffix", ""), + ),), + ]),), + ], + )), + )); + } +} diff --git a/lib/screens/profile/components/education_screen.dart b/lib/screens/profile/components/education_screen.dart new file mode 100644 index 0000000..4771db8 --- /dev/null +++ b/lib/screens/profile/components/education_screen.dart @@ -0,0 +1,222 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; + +import 'package:unit2/model/profile/educational_background.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; + +import '../../../bloc/profile/education/education_bloc.dart'; + +class EducationScreen extends StatelessWidget { + const EducationScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text(educationScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + //userbloc + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + //profilebloc + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + //education bloc + return BlocConsumer( + listener: (context, state) { + if (state is EducationalBackgroundLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is EducationalBackgroundLoadedState || + state is EducationalBackgroundErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is EducationalBackgroundLoadedState) { + if (state.educationalBackground.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.educationalBackground.length, + itemBuilder: + (BuildContext context, int index) { + String level = state + .educationalBackground[index] + .education! + .level!; + String periodFrom = state + .educationalBackground[index] + .periodFrom!; + String periodTo = state + .educationalBackground[index].periodTo!; + String? program = state + .educationalBackground[index] + .education! + .course == + null + ? null + : state.educationalBackground[index] + .education!.course!.program!; + List? honors = state + .educationalBackground[index].honors! + .toList(); + String school = state + .educationalBackground[index] + .education! + .school! + .name!; + return Column( + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Row( + children: [ + Expanded( + child: Text( + level, + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500), + )), + Text( + "$periodFrom - ", + style: Theme.of( + context) + .textTheme + .bodyMedium, + ), + ], + ), + const SizedBox( + height: 5, + ), + Text( + school, + style: Theme.of(context) + .textTheme + .titleSmall, + ), + Container( + padding: + const EdgeInsets + .only(top: 8), + child: honors + .isNotEmpty + ? Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + const Text( + " : ", + style: TextStyle( + fontWeight: + FontWeight.w600), + ), + Column( + children: honors + .map((Honor honor) => + Text(" - ${honor.name!}")) + .toList(), + ), + ], + ) + : const SizedBox()), + program == null + ? const SizedBox() + : Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + const SizedBox( + height: 5, + ), + Text(program), + ], + ), + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have any Educational Background added. Please click + to add."); + } + } + if (state is EducationalBackgroundErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} diff --git a/lib/screens/profile/components/eligibility/add_modal.dart b/lib/screens/profile/components/eligibility/add_modal.dart new file mode 100644 index 0000000..07068e9 --- /dev/null +++ b/lib/screens/profile/components/eligibility/add_modal.dart @@ -0,0 +1,485 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:intl/intl.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/eligibility.dart'; + +import '../../../../bloc/profile/eligibility/eligibility_bloc.dart'; +import '../../../../model/location/city.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../model/location/region.dart'; +import '../../../../model/utils/eligibility.dart'; +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; +import '../../../../utils/location_utilities.dart'; +import '../../../../utils/text_container.dart'; + +class AddEligibilityScreen extends StatefulWidget { + const AddEligibilityScreen( + {super.key, required this.profileId, required this.token}); + final int profileId; + final String token; + + @override + State createState() => _AddEligibilityScreenState(); +} + +class _AddEligibilityScreenState extends State { + final formKey = GlobalKey(); + bool? overseas = false; + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + Country? selectedCountry; + Eligibility? selectedEligibility; + List? provinces; + List? citymuns; + bool provinceCall = false; + bool cityCall = false; + final examDateController = TextEditingController(); + final validityDateController = TextEditingController(); + String? token; + String? profileId; + String? rating; + String? license; + @override + Widget build(BuildContext context) { + return BlocBuilder( + buildWhen: (previous, current) { + return false; + }, + builder: (context, state) { + ////ADD ELIGIBILITY STATE + if (state is AddEligibilityState) { + return SingleChildScrollView( + child: SizedBox( + height: screenHeight * .95, + child: ProgressHUD( + child: Center( + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 25, horizontal: 18), + child: FormBuilder( + key: formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ////ELIGIBILITIES DROPDOWN + FormBuilderDropdown( + onChanged: (Eligibility? eligibility) { + selectedEligibility = eligibility; + }, + autovalidateMode: + AutovalidateMode.onUserInteraction, + validator: (value) => + value == null ? 'required' : null, + items: state.eligibilities + .map>( + (Eligibility eligibility) { + return DropdownMenuItem( + value: eligibility, + child: Text(eligibility.title)); + }).toList(), + name: "eligibility", + decoration: normalTextFieldStyle( + "Eligibility", "Eligibility")), + const SizedBox( + height: 8, + ), + + SizedBox( + width: screenWidth, + child: Row( + children: [ + ////LICENSE NUMBER + Flexible( + flex: 1, + child: FormBuilderTextField( + onChanged: (value) { + license = value; + }, + name: 'license_number', + decoration: normalTextFieldStyle( + "license number", "license number"), + ), + ), + const SizedBox( + width: 8, + ), + ////RATING + Flexible( + flex: 1, + child: FormBuilderTextField( + keyboardType: + const TextInputType.numberWithOptions(), + onChanged: (value) { + rating = value; + }, + name: 'rating', + decoration: normalTextFieldStyle( + 'rating %', 'rating'), + ), + ), + ], + ), + ), + const SizedBox( + height: 8, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + ////EXAM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + use24HourFormat: false, + icon: const Icon(Icons.date_range), + controller: examDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: + normalTextFieldStyle("Exam date", "") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 8, + ), + ////VALIDITY DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + controller: validityDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "Validity date", "Validity date") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + ), + ), + ], + ), + ), + const SizedBox( + height: 8, + ), + Text( + "Placement of Examination/Conferment", + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith(fontSize: blockSizeVertical * 2), + ), + const SizedBox( + height: 8, + ), + ////OVERSEAS ADDRESS SWITCH + Column( + children: [ + FormBuilderSwitch( + validator: FormBuilderValidators.required( + errorText: 'This field is required'), + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value; + }); + }, + decoration: normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Overseas Address?"), + ), + const SizedBox( + height: 8, + ), + ////COUNTRY DROPDOWN + SizedBox( + child: overseas == true + ? FormBuilderDropdown( + initialValue: null, + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + items: state.countries + .map>( + (Country country) { + return DropdownMenuItem( + value: country, + child: FittedBox( + child: Text(country.name!))); + }).toList(), + name: 'country', + decoration: normalTextFieldStyle( + "Country*", "Country"), + onChanged: (Country? value) { + selectedCountry = value; + }, + ) + : Column( + children: [ + ////REGION DROPDOWN + FormBuilderDropdown( + autovalidateMode: AutovalidateMode + .onUserInteraction, + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + //// region onchange + onChanged: (Region? region) async { + + if(selectedRegion != region){ + setState(() { + provinceCall = true; + }); + selectedRegion = region; + getProvinces(); + } + }, + initialValue: selectedRegion, + decoration: normalTextFieldStyle( + "Region*", "Region"), + name: 'region', + items: state.regions + .map>( + (Region region) { + return DropdownMenuItem( + value: region, + child: Text( + region.description!)); + }).toList(), + ), + const SizedBox( + height: 8, + ), + ////PROVINCE DROPDOWN + SizedBox( + height: 70, + child: ModalProgressHUD( + color: Colors.transparent, + inAsyncCall: provinceCall, + child: DropdownButtonFormField< + Province?>( + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + value: selectedProvince, + onChanged: + (Province? province) { + + if(selectedProvince != province){ + setState(() { + cityCall = true; + }); + selectedProvince = province; + getCities(); + } + }, + items: provinces == null + ? [] + : provinces!.map< + DropdownMenuItem< + Province>>( + (Province province) { + return DropdownMenuItem( + value: province, + child: FittedBox( + child: Text(province + .description!), + )); + }).toList(), + decoration: + normalTextFieldStyle( + "Province*", + "Province")), + ), + ), + + //// CityMunicipalities dropdown + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: cityCall, + child: DropdownButtonFormField< + CityMunicipality>( + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + onChanged: + (CityMunicipality? city) { + selectedMunicipality = city; + }, + decoration: + normalTextFieldStyle( + "Municipality*", + "Municipality"), + value: selectedMunicipality, + items: citymuns == null + ? [] + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality c) { + return DropdownMenuItem( + value: c, + child: Text(c + .description!)); + }).toList(), + ), + ), + ), + + ], + )), + ], + ), + + const Expanded( + child: SizedBox(), + ), + + SizedBox( + width: screenWidth, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + //rating + double? rate = rating == null + ? null + : double.parse(rating!); + //lisence + String? licenseNumber = license; + CityMunicipality? cityMunicipality = + selectedMunicipality; + DateTime? examDate = examDateController + .text.isEmpty + ? null + : DateTime.parse(examDateController.text); + DateTime? validityDate = + validityDateController.text.isEmpty + ? null + : DateTime.parse( + validityDateController.text); + + ExamAddress examAddress = ExamAddress( + barangay: null, + id: null, + addressCategory: null, + examAddressClass: null, + country: selectedCountry ?? + Country( + id: 175, + name: 'Philippines', + code: 'PH'), + cityMunicipality: cityMunicipality); + EligibityCert eligibityCert = EligibityCert( + id: null, + rating: rate, + examDate: examDate, + attachments: null, + eligibility: selectedEligibility, + examAddress: examAddress, + validityDate: validityDate, + licenseNumber: licenseNumber, + overseas: overseas); + if (formKey.currentState!.saveAndValidate()) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add( + AddEligibility( + eligibityCert: eligibityCert, + profileId: + widget.profileId.toString(), + token: widget.token)); + } + // context.read().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token)) + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ]), + ), + ), + ), + ), + ), + ); + } + + return Container(); + }, + ); + } + + Future getProvinces() async { + try { + List newProvinces = await LocationUtils.instance + .getProvinces(regionCode: selectedRegion!.code.toString()); + setState(() { + provinces = newProvinces; + selectedProvince = provinces![0]; + provinceCall = false; + cityCall = true; + getCities(); + }); + } catch (e) { + context.read().add(CallErrorState()); + } + } + + Future getCities() async { + try { + List newCities = await LocationUtils.instance + .getCities(code: selectedProvince!.code.toString()); + citymuns = newCities; + setState(() { + selectedMunicipality = newCities[0]; + cityCall = false; + }); + } catch (e) { + context.read().add(CallErrorState()); + } + } +} diff --git a/lib/screens/profile/components/eligibility/edit_modal.dart b/lib/screens/profile/components/eligibility/edit_modal.dart new file mode 100644 index 0000000..b2ffb29 --- /dev/null +++ b/lib/screens/profile/components/eligibility/edit_modal.dart @@ -0,0 +1,542 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:intl/intl.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:unit2/model/location/city.dart'; +import 'package:unit2/model/profile/eligibility.dart'; +import 'package:unit2/model/utils/eligibility.dart'; +import 'package:unit2/utils/location_utilities.dart'; +import '../../../../bloc/profile/eligibility/eligibility_bloc.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/region.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; +import '../../../../utils/text_container.dart'; + +class EditEligibilityScreen extends StatefulWidget { + final EligibityCert eligibityCert; + final int profileId; + final String token; + const EditEligibilityScreen({super.key, required this.eligibityCert, required this.profileId, required this.token}); + + @override + State createState() => _EditEligibilityScreenState(); +} + +class _EditEligibilityScreenState extends State { + final formKey = GlobalKey(); + final provinceKey = GlobalKey(); + bool? overseas; + List? provinces; + List? citymuns; + List? regions; + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + Country? selectedCountry; + Eligibility? selectedEligibility; + bool provinceCall = false; + bool cityCall = false; + String? token; + String? profileId; + String? rating; + String? license; + final examDateController = TextEditingController(); + final validityDateController = TextEditingController(); + @override + Widget build(BuildContext context) { + + return BlocBuilder( + buildWhen: (previous, current) { + + return false; + }, + builder: (context, state) { + //EDIT ELIGIBILITY STATE + if (state is EditEligibilityState) { + examDateController.text = + state.eligibityCert.examDate == null + ? '' + : state.eligibityCert.examDate.toString(); + validityDateController.text = + state.eligibityCert.validityDate == null + ? '' + : state.eligibityCert.validityDate.toString(); + + provinces = state.provinces; + citymuns = state.cities; + regions = state.regions; + overseas = state.isOverseas; + selectedRegion = state.currentRegion; + selectedProvince = state.currentProvince; + selectedMunicipality = state.currentCity; + selectedEligibility = state.currentEligibility; + rating = state.eligibityCert.rating?.toString(); + license = state.eligibityCert.licenseNumber; + return Center( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: FormBuilder( + key: formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ////ELIGIBILITIES DROPDOWN + DropdownButtonFormField( + validator: (value) => + value == null ? 'required' : null, + isExpanded: true, + onChanged: (Eligibility? eligibility) { + selectedEligibility = eligibility; + }, + value: selectedEligibility, + items: state.eligibilities + .map>( + (Eligibility eligibility) { + return DropdownMenuItem( + value: eligibility, + child: Text(eligibility.title)); + }).toList(), + decoration: normalTextFieldStyle( + "Eligibility", "")), + const SizedBox( + height: 20, + ), + + SizedBox( + width: screenWidth, + child: Row( + children: [ + ////LICENSE NUMBER + Flexible( + flex: 1, + child: FormBuilderTextField( + onChanged: (value) { + license = value; + }, + name: 'license_number', + initialValue: license, + decoration: normalTextFieldStyle( + "license number", + "license number"), + ), + ), + const SizedBox( + width: 12, + ), + // //RATING + Flexible( + flex: 1, + child: FormBuilderTextField( + keyboardType: const TextInputType + .numberWithOptions(), + onChanged: (value) { + rating = value; + }, + name: 'rating', + initialValue: rating == null + ? 'N/A' + : rating.toString(), + decoration: normalTextFieldStyle( + 'rating', 'rating'), + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + // //EXAM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators.required(errorText: "This field is required"), + use24HourFormat: false, + controller: examDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "Exam date", "") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + )), + const SizedBox( + width: 12, + ), + ////VALIDITY DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators.required(errorText: "This field is required"), + + use24HourFormat: false, + controller: validityDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "validity date", "") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + Text( + "Placement of Examination/Confinement", + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontSize: blockSizeVertical * 2), + ), + const SizedBox( + height: 12, + ), + //OVERSEAS ADDRESS SWITCH + StatefulBuilder( + builder: (context, StateSetter setState) { + return Column( + children: [ + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value; + }); + }, + decoration: + normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Overseas Address?"), + ), + const SizedBox( + height: 20, + ), + //COUNTRY DROPDOWN + SizedBox( + child: overseas == true + ? FormBuilderDropdown( + validator: (value) => + value == null + ? 'required' + : null, + initialValue: + state.selectedCountry, + items: state.countries.map< + DropdownMenuItem< + Country>>( + (Country country) { + return DropdownMenuItem< + Country>( + value: country, + child: FittedBox( + child: Text(country + .name!))); + }).toList(), + name: 'country', + decoration: + normalTextFieldStyle( + "Country*", + "Country"), + onChanged: (Country? value) { + selectedCountry = value; + }, + ) + : Column( + children: [ + //REGION DROPDOWN + DropdownButtonFormField< + Region?>( + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + onChanged: (Region? + region) async { + setState(() { + provinceCall = true; + }); + selectedRegion = region; + provinces = await LocationUtils + .instance + .getProvinces( + regionCode: + selectedRegion! + .code + .toString()); + selectedProvince = + provinces![0]; + setState(() { + provinceCall = false; + cityCall = true; + }); + citymuns = await LocationUtils + .instance + .getCities( + code: + selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = false; + }); + }, + value: selectedRegion, + decoration: + normalTextFieldStyle( + "Region*", + "Region"), + items: regions == null + ? [] + : regions!.map< + DropdownMenuItem< + Region>>((Region + region) { + return DropdownMenuItem< + Region>( + value: region, + child: Text(region + .description!)); + }).toList(), + ), + const SizedBox( + height: 20, + ), + ////PROVINCE DROPDOWN + SizedBox( + height: 70, + child: ModalProgressHUD( + color: + Colors.transparent, + inAsyncCall: + provinceCall, + child: DropdownButtonFormField< + Province?>( + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + value: + selectedProvince, + onChanged: (Province? + province) async { + setState(() { + cityCall = true; + }); + selectedProvince = + province; + citymuns = await LocationUtils + .instance + .getCities( + code: selectedProvince! + .code + .toString()); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = + false; + }); + }, + items: provinces == + null + ? [] + : provinces!.map< + DropdownMenuItem< + Province>>((Province + province) { + return DropdownMenuItem( + value: + province, + child: + FittedBox( + child: + Text(province.description!), + )); + }).toList(), + decoration: + normalTextFieldStyle( + "Province*", + "Province")), + ), + ), + + //// City municipality + SizedBox( + height: 70, + child: ModalProgressHUD( + color: + Colors.transparent, + inAsyncCall: cityCall, + child: + DropdownButtonFormField< + CityMunicipality>( + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + onChanged: + (CityMunicipality? + city) { + selectedMunicipality = + city; + }, + decoration: + normalTextFieldStyle( + "Municipality*", + "Municipality"), + value: + selectedMunicipality, + items: citymuns == + null + ? [] + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality + c) { + return DropdownMenuItem( + value: c, + child: Text( + c.description!)); + }).toList(), + ), + ), + ), + const SizedBox( + height: 20, + ), + ], + )), + ], + ); + }), + + const Expanded( + child: SizedBox(), + ), + + SizedBox( + width: screenWidth, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + ////rating + double? rate = rating == null + ? null + : double.parse(rating!); + ////license + String? newLicense = license; + ////city municipality + CityMunicipality? cityMunicipality = + selectedMunicipality; + ////exam date + DateTime? examDate = + examDateController.text.isEmpty + ? null + : DateTime.parse( + examDateController.text); + // // validity date + DateTime? validityDate = + validityDateController.text.isEmpty + ? null + : DateTime.parse( + validityDateController + .text); + //// exam address + ExamAddress examAddress = ExamAddress( + barangay: state.eligibityCert + .examAddress?.barangay, + id: state + .eligibityCert.examAddress?.id, + addressCategory: state.eligibityCert + .examAddress?.addressCategory, + examAddressClass: state + .eligibityCert + .examAddress + ?.examAddressClass, + country: selectedCountry ??= + Country( + id: 175, + name: 'Philippines', + code: 'PH'), + cityMunicipality: cityMunicipality); + EligibityCert eligibityCert = + EligibityCert( + id: state.eligibityCert.id, + rating: rate, + examDate: examDate, + attachments: null, + eligibility: + selectedEligibility, + examAddress: examAddress, + validityDate: validityDate, + licenseNumber: newLicense, + overseas: overseas); + if (formKey.currentState! + .saveAndValidate()) { + final progress = + ProgressHUD.of( + context); + progress!.showWithText( + "Loading..."); + context.read().add( + UpdateEligibility( + eligibityCert: eligibityCert, + oldEligibility: state + .eligibityCert + .eligibility! + .id, + profileId:widget.profileId.toString(), + token: widget.token)); + } + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ]), + ), + ), + ); + + + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/eligibility_screen.dart b/lib/screens/profile/components/eligibility_screen.dart new file mode 100644 index 0000000..34c1af2 --- /dev/null +++ b/lib/screens/profile/components/eligibility_screen.dart @@ -0,0 +1,375 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/eligibility.dart'; +import 'package:unit2/screens/profile/components/eligibility/add_modal.dart'; +import 'package:unit2/screens/profile/components/eligibility/edit_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/Leadings/close_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../bloc/profile/eligibility/eligibility_bloc.dart'; +import '../../../utils/alerts.dart'; + +class EligibiltyScreen extends StatelessWidget { + const EligibiltyScreen({super.key}); + + @override + Widget build(BuildContext context) { + String? token; + int? profileId; + + return WillPopScope( + onWillPop: () async { + return true; + }, + child: Scaffold( + resizeToAvoidBottomInset: true, + appBar: AppBar( + title: context.watch().state is AddEligibilityState + ? const Text("Add Eligiblity") + : context.watch().state is EditEligibilityState + ? const Text("Edit Eligibilty") + : const Text(elibilityScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: (context.watch().state is EligibilityLoaded) + + ? [ + AddLeading(onPressed: () { + context + .read() + .add(ShowAddEligibilityForm()); + }) + ] + :(context.watch().state is AddEligibilityState || context.watch().state is EditEligibilityState)? [ + CloseLeading(onPressed: () { + context.read().add(const LoadEligibility()); + }) + ]:[], + ), + body: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = + state.userData!.user!.login!.user!.profileId; + return BlocBuilder( + builder: (context, state) { + if(state is ProfileLoaded){ + return ProgressHUD( + padding: const EdgeInsets.all(24), + indicatorWidget: const SpinKitFadingCircle( + color: Colors.white, + ), + backgroundColor: Colors.black87, + child: BlocConsumer( + listener: (context, state) { + if (state is EligibilityLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is EligibilityLoaded || + state is AddEligibilityState || + state is EditEligibilityState || + state is DeletedState || + state is EligibilityAddedState || + state is EligibilityEditedState || + state is EligibilityErrorState + ) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////DELETED STATE + if (state is DeletedState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Eligibility has been deleted successfully", + () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting eligibility", () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } + } + ////ADDED STATE + if (state is EligibilityAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } + } + ////UPDATED STATE + if (state is EligibilityEditedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add(const LoadEligibility( + )); + }); + } + } + }, + builder: (context, state) { + return BlocBuilder( + builder: (context, state) { + if (state is EligibilityLoaded) { + + if (state.eligibilities.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.eligibilities.length, + itemBuilder: + (BuildContext context, int index) { + String title = state + .eligibilities[index] + .eligibility! + .title; + return Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + width: screenWidth, + padding: + const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8), + decoration: box1(), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + title, + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500), + ), + const Divider(), + const SizedBox( + height: 5, + ), + Text( + "$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}", + style: Theme.of( + context) + .textTheme + .titleSmall), + const SizedBox( + height: 3, + ), + Text( + "Rating : ${state.eligibilities[index].rating ?? 'N/A'}.", + style: Theme.of( + context) + .textTheme + .titleSmall) + ]), + ), + AppPopupMenu( + 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 = + overseas; + + context + .read() + .add(ShowEditEligibilityForm( + eligibityCert: + eligibityCert)); + } + }, + menuItems: [ + popMenuItem( + text: "Edit", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Delete", + value: 2, + icon: Icons.delete), + popMenuItem( + text: "Attachment", + value: 3, + icon: FontAwesome + .attach) + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: + "You don't have any eligibilities added. Please click + to add"); + } + } + if (state is EditEligibilityState) { + return EditEligibilityScreen( + profileId: profileId!, + token: token!, + eligibityCert: state.eligibityCert); + } + if (state is AddEligibilityState) { + return AddEligibilityScreen(token: token!,profileId: profileId!,); + } + if (state is EligibilityErrorState) { + return SomethingWentWrong(message: state.message, onpressed: (){ + context.read().add(LoadEligibility(token: token,profileId: profileId)); + }); + } + return Container( + color: Colors.grey.shade200, + ); + }, + ); + }, + ), + ); + + } + return Container(); + } + ); + } + return Container(); + }, + )), + ); + } + + PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); + } +} diff --git a/lib/screens/profile/components/family_background_screen.dart b/lib/screens/profile/components/family_background_screen.dart new file mode 100644 index 0000000..f179041 --- /dev/null +++ b/lib/screens/profile/components/family_background_screen.dart @@ -0,0 +1,430 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/family_backround.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; + +import '../../../bloc/profile/family/family_bloc.dart'; + +class FamilyBackgroundScreen extends StatefulWidget { + const FamilyBackgroundScreen({ + super.key, + }); + + @override + State createState() => _FamilyBackgroundScreenState(); +} + +class _FamilyBackgroundScreenState extends State { + FamilyBackground? father; + FamilyBackground? mother; + FamilyBackground? spouse; + List children = []; + List otherRelated = []; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text(familyBackgroundScreenTitle), + centerTitle: true, + backgroundColor: primary, + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is FamilyLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is FamilyLoaded || state is FamilyErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is FamilyLoaded) { + father = state.families.firstWhere( + (element) => element.relationship!.id == 1); + mother = state.families.firstWhere( + (element) => element.relationship!.id == 2); + spouse = state.families.firstWhere( + (element) => element.relationship!.id == 3); + + // get all children + var childs = state.families + .where((element) => element.relationship!.id == 4); + if (childs.isNotEmpty) { + for (var element in childs) { + children.add(element); + } + } + + //get all related persons + var relateds = state.families + .where((element) => element.relationship!.id! > 4); + if (relateds.isNotEmpty) { + for (var element in relateds) { + otherRelated.add(element); + } + } + return ListView(children: [ + //Father---------------------------------------------- + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const Text(fatherText), + const SizedBox( + height: 5, + ), + Text( + " ${father!.relatedPerson!.firstName} ${father!.relatedPerson!.middleName} ${father!.relatedPerson!.lastName} ${father!.relatedPerson!.nameExtension ?? ''},", + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500), + ), + Text( + " ", + style: Theme.of(context) + .textTheme + .bodySmall, + ), + Row( + children: [ + Checkbox( + value: false, + onChanged: (value) { + setState(() { + value = !value!; + }); + }), + const Text(incaseOfEmergency) + ], + ) + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + + //Mother----------------------------------------------------- + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const Text(motherText), + const SizedBox( + height: 5, + ), + Text( + " ${mother!.relatedPerson!.firstName} ${mother!.relatedPerson!.middleName} ${mother!.relatedPerson!.lastName} ${mother!.relatedPerson!.nameExtension ?? ''}", + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500), + ), + Text(" ", + style: Theme.of(context) + .textTheme + .bodySmall), + Row( + children: [ + Checkbox( + value: false, + onChanged: (value) {}), + const Text(incaseOfEmergency) + ], + ) + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ), + const SizedBox( + height: 5, + ), + //Spouse --------------------------------------------------------- + spouse != null + ? Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const Text(spouseText), + const SizedBox( + height: 5, + ), + Text( + " ${spouse!.relatedPerson!.firstName} ${spouse!.relatedPerson!.middleName} ${spouse!.relatedPerson!.lastName} ${spouse!.relatedPerson!.nameExtension ?? ''}", + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500)), + Text(" ", + style: Theme.of(context) + .textTheme + .bodySmall), + Row( + children: [ + Checkbox( + value: false, + onChanged: (value) {}), + const Text(incaseOfEmergency) + ], + ) + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ) + : const SizedBox(), + const SizedBox( + height: 5, + ), + + // Childrens ---------------------------------- + children.isNotEmpty + ? Container( + decoration: box1(), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: children.map((child) { + int index = children.indexOf(child); + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + index == 0 + ? const Text(childrenText) + : const SizedBox(), + const SizedBox( + height: 5, + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + " ${child.relatedPerson!.firstName} ${child.relatedPerson!.middleName} ${child.relatedPerson!.lastName} ${child.relatedPerson!.nameExtension ?? ''}", + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500)), + Text(" ", + style: Theme.of( + context) + .textTheme + .bodySmall), + Row( + children: [ + Checkbox( + value: false, + onChanged: + (value) {}), + const Text( + incaseOfEmergency) + ], + ) + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ], + ), + ); + }).toList()), + ) + : const SizedBox(), + const SizedBox( + height: 5, + ), + //Other related person + otherRelated.isNotEmpty + ? Container( + decoration: box1(), + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: otherRelated.map((relative) { + int index2 = + otherRelated.indexOf(relative); + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + index2 == 0 + ? const Text(otherRelatedText) + : const SizedBox(), + const SizedBox( + height: 5, + ), + Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + " ${relative.relatedPerson!.firstName} ${relative.relatedPerson!.middleName} ${relative.relatedPerson!.lastName} ${relative.relatedPerson!.nameExtension ?? ''}", + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500)), + Text(" ", + style: Theme.of( + context) + .textTheme + .bodySmall!), + Row( + children: [ + Checkbox( + value: false, + onChanged: + (value) {}), + const Text( + incaseOfEmergency) + ], + ) + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + )) + ], + ), + ], + ), + ); + }).toList()), + ) + : const SizedBox(), + ]); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + }, + ), + ), + ); + } +} diff --git a/lib/screens/profile/components/learning_and_development_screen.dart b/lib/screens/profile/components/learning_and_development_screen.dart new file mode 100644 index 0000000..f2e8aa1 --- /dev/null +++ b/lib/screens/profile/components/learning_and_development_screen.dart @@ -0,0 +1,183 @@ +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_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:intl/intl.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; + +import '../../../bloc/profile/learningDevelopment/learning_development_bloc.dart'; + +class LearningAndDevelopmentScreen extends StatelessWidget { + + const LearningAndDevelopmentScreen( + {super.key,}); + + @override + Widget build(BuildContext context) { + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + return Scaffold( + appBar: AppBar( + title: const Text(learningAndDevelopmentScreenTitle), + centerTitle: true, + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + indicatorWidget: const SpinKitFadingCircle( + color: Colors.white, + ), + backgroundColor: Colors.black87, + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is LearningDevelopmentLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is LearningDevelopmentLoadedState || + state is LeaningDevelopmentErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + // TODO: implement listener + }, + builder: (context, state) { + if (state is LearningDevelopmentLoadedState) { + if (state.learningsAndDevelopment.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: + state.learningsAndDevelopment.length, + itemBuilder: + (BuildContext context, int index) { + String training = state + .learningsAndDevelopment[index] + .conductedTraining! + .title! + .title!; + String provider = state + .learningsAndDevelopment[index] + .conductedTraining! + .conductedBy! + .name!; + String start = dteFormat2.format(state + .learningsAndDevelopment[index] + .conductedTraining! + .fromDate!); + String end = dteFormat2.format(state + .learningsAndDevelopment[index] + .conductedTraining! + .toDate!); + String type = state + .learningsAndDevelopment[index] + .conductedTraining! + .learningDevelopmentType! + .title!; + return Column( + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + width: screenWidth, + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + training, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500), + ), + const Divider(), + const SizedBox( + height: 5, + ), + Text( + provider, + style: Theme.of(context) + .textTheme + .titleSmall, + ), + const SizedBox( + height: 5, + ), + Text( + "$duration: $start to $end", + style: Theme.of(context) + .textTheme + .labelMedium, + ), + const SizedBox( + height: 5, + ), + + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert)), + ], + ), + ), + const SizedBox( + height: 8, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have any Learning and Development added. Please click + to add."); + } + } + if (state is LeaningDevelopmentErrorState) { + return (SomethingWentWrong( + message: state.message, onpressed: () {})); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} diff --git a/lib/screens/profile/components/loading_screen.dart b/lib/screens/profile/components/loading_screen.dart new file mode 100644 index 0000000..0d469b9 --- /dev/null +++ b/lib/screens/profile/components/loading_screen.dart @@ -0,0 +1,159 @@ +import 'package:expandable_group/expandable_group_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttericon/brandico_icons.dart'; +import 'package:fluttericon/elusive_icons.dart'; +import 'package:fluttericon/entypo_icons.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:fluttericon/modern_pictograms_icons.dart'; +import 'package:unit2/screens/profile/components/main_menu.dart'; +import 'package:unit2/screens/profile/components/submenu.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import '../../../theme-data.dart/colors.dart'; + +class LoadingScreen extends StatelessWidget { + const LoadingScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + + Container( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: ListView( + children: [ + const Text( + "View and Update your Profile Information", + textAlign: TextAlign.center, + ), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Elusive.address_book, + color: primary, + ), + title: Text( + "Basic Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(Icons.person, "Primary", () {}), + subMenu(Icons.home, "Home Addresses", () {}), + subMenu(Icons.contact_mail, "Identifications", () {}), + subMenu(Icons.contact_phone, "Contact Info", () {}), + subMenu(Icons.flag, "Citizenships", () {}), + ]), + const Divider(), + MainMenu( + icon: Elusive.group, + title: "Family", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.graduation_cap, + title: "Education", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Icons.stars, + title: "Eligibility", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.shopping_bag, + title: "Work History", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.walking, + title: "Voluntary Work & Civic Services", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Elusive.lightbulb, + title: "Learning & Development", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Brandico.codepen, + title: "Personal References", + onTap: () {}, + ), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Icons.info, + color: primary, + ), + title: Text( + "Other Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(Icons.fitness_center, "Skills & Hobbies", () {}), + subMenu(FontAwesome5.certificate, + "Organization Memberships", () {}), + subMenu( + Entypo.doc_text, "Non-Academic Recognitions", () {}), + ]), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + FontAwesome5.laptop_house, + color: primary, + ), + title: Text( + "Assets", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(ModernPictograms.home, "Real Property Tax", () {}), + ]), + ], + ), + ), + Container( + width: screenWidth, + height: screenHeight, + color: Colors.white70, + ), + Center( + child: Container( + height: 80, + width: 80, + decoration:const BoxDecoration( + color: Colors.black87, + borderRadius: BorderRadius.all(Radius.circular(8)) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const[ + SpinKitFadingCircle( + size: 42, + color: Colors.white), + + ], + ), + ), + ), + ], + ); + } +} diff --git a/lib/screens/profile/components/main_menu.dart b/lib/screens/profile/components/main_menu.dart index d315a7d..cdc5c26 100644 --- a/lib/screens/profile/components/main_menu.dart +++ b/lib/screens/profile/components/main_menu.dart @@ -4,9 +4,11 @@ import 'package:unit2/theme-data.dart/colors.dart'; class MainMenu extends StatelessWidget { final IconData icon; final String title; + final Function() onTap; const MainMenu({ required this.icon, required this.title, + required this.onTap, Key? key, }) : super(key: key); @@ -19,9 +21,10 @@ class MainMenu extends StatelessWidget { ), title: Text( title, - style: TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle(fontWeight: FontWeight.bold), ), trailing: const Icon(Icons.keyboard_arrow_right), + onTap: onTap, ); } } diff --git a/lib/screens/profile/components/other_information/non_academic/add_modal.dart b/lib/screens/profile/components/other_information/non_academic/add_modal.dart new file mode 100644 index 0000000..08793bd --- /dev/null +++ b/lib/screens/profile/components/other_information/non_academic/add_modal.dart @@ -0,0 +1,378 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/other_information/non_acedimic_recognition.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global.dart'; + +import '../../../../../model/utils/agency.dart'; +import '../../../../../model/utils/category.dart'; +import '../../../../../theme-data.dart/box_shadow.dart'; +import '../../../../../theme-data.dart/btn-style.dart'; +import '../../../../../theme-data.dart/colors.dart'; +import '../../../../../utils/text_container.dart'; + +class AddNonAcademicRecognitionScreen extends StatefulWidget { + const AddNonAcademicRecognitionScreen({super.key}); + + @override + State createState() => + _AddNonAcademicRecognitionScreenState(); +} + +class _AddNonAcademicRecognitionScreenState + extends State { + bool showAgencyCategory = false; + final agencyFocusNode = FocusNode(); + + final agencyCategoryFocusNode = FocusNode(); + final addAgencyController = TextEditingController(); + Agency? selectedAgency; + Category? selectedCategory; + Agency? newAgency; + bool showIsPrivateRadio = false; + bool? isPrivate = false; + NonAcademicRecognition? nonAcademicRecognition; + final _formKey = GlobalKey(); + int? profileId; + String? token; + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + + return BlocBuilder( + builder: (context, state) { + if (state is AddNonAcademeRecognitionState) { + return SizedBox( + height: blockSizeVertical * 90, + child: SingleChildScrollView( + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 25,horizontal: 18), + child: Column( + children: [ + FormBuilderTextField(name: 'title', + decoration: normalTextFieldStyle("Recognition / Award Title *", "Recognition / Award Title"), + validator: FormBuilderValidators.required(errorText: "this field is required"), + ), + const SizedBox(height: 12,), + StatefulBuilder( + builder: (context, setState) { + //// AGENCY SEARCHFIELD + return Column( + children: [ + SearchField( + itemHeight: 70, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name! + .toUpperCase(), + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency + .privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + focusNode: agencyFocusNode, + searchInputDecoration: + normalTextFieldStyle( + "Agency *", "") + .copyWith( + suffixIcon: + const Icon(Icons + .arrow_drop_down)), + ////agency suggestion tap + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + agencyFocusNode.unfocus(); + if (selectedAgency + ?.category == + null) { + showAgencyCategory = true; + showIsPrivateRadio = true; + } else { + showAgencyCategory = false; + showIsPrivateRadio = false; + } + }); + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment + .center, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + const SizedBox( + height: 20, + ), + const Text( + "No result found..."), + const SizedBox( + height: 10, + ), + TextButton( + //// Add agency onpressed + onPressed: () { + showDialog( + context: + context, + builder: + (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Agency?"), + content: + SizedBox( + height: + 130, + child: + Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle("", ""), + ), + const SizedBox( + height: + 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + //// onpressed + onPressed: () { + setState(() { + newAgency = Agency(id: null, name: addAgencyController.text.toUpperCase(), category: null, privateEntity: null); + state.agencies.insert(0, newAgency!); + addAgencyController.clear(); + Navigator.pop(context); + }); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: const Text( + "Add position")) + ]), + ), + ), + const SizedBox( + height: 8, + ), + SizedBox( + child: showAgencyCategory + ? SearchField( + focusNode: + agencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .agencyCategories + .map((Category + category) => + SearchFieldListItem( + category + .name!, + item: + category, + child: + ListTile( + title: Text( + category + .name!), + subtitle: Text(category + .industryClass! + .name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: Text( + "No result found ...")), + ), + ////agency controller suggestion tap + onSuggestionTap: + (agencyCategory) { + setState(() { + selectedCategory = + agencyCategory + .item; + + agencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", + "") + .copyWith( + suffixIcon: + const Icon( + Icons + .arrow_drop_down)), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: + InputDecoration( + border: + InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of( + context) + .textTheme + .headlineSmall! + .copyWith( + fontSize: + 24), + ), + const Icon(FontAwesome + .help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value + .toString() == + "YES") { + isPrivate = true; + } else { + isPrivate = false; + } + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: + lang)) + .toList( + growable: + false), + ) + : const SizedBox()), + ], + ); + }), + const SizedBox( + height: 24, + ), + SizedBox( + height: 60, + width: double.infinity, + child: ElevatedButton( + style: mainBtnStyle(primary, + Colors.transparent, second), + onPressed: () { + + if (_formKey.currentState! + .saveAndValidate()) { + String title = _formKey.currentState!.value['title']; + + if(selectedAgency?.privateEntity != null){ + newAgency = selectedAgency; + }else{ + newAgency = Agency( + id: selectedAgency?.id, + name: selectedAgency!.name, + category: + selectedCategory, + privateEntity: isPrivate); + } + nonAcademicRecognition = NonAcademicRecognition(id: null, title:title,presenter: newAgency ); + context.read().add(AddNonAcademeRecognition(nonAcademicRecognition: nonAcademicRecognition!, profileId: profileId!, token: token!)); + } + }, + child: const Text(submit)), + ) + ], + ), + )), + ) + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/other_information/non_academic/edit_modal.dart b/lib/screens/profile/components/other_information/non_academic/edit_modal.dart new file mode 100644 index 0000000..3d43d3c --- /dev/null +++ b/lib/screens/profile/components/other_information/non_academic/edit_modal.dart @@ -0,0 +1,410 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/other_information/non_acedimic_recognition.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global.dart'; + +import '../../../../../model/utils/agency.dart'; +import '../../../../../model/utils/category.dart'; +import '../../../../../theme-data.dart/box_shadow.dart'; +import '../../../../../theme-data.dart/btn-style.dart'; +import '../../../../../theme-data.dart/colors.dart'; +import '../../../../../utils/text_container.dart'; + +class EditNonAcademicRecognitionScreen extends StatefulWidget { + const EditNonAcademicRecognitionScreen({super.key}); + + @override + State createState() => + _EditNonAcademicRecognitionScreenState(); +} + +class _EditNonAcademicRecognitionScreenState + extends State { + bool showAgencyCategory = false; + final agencyFocusNode = FocusNode(); + + final agencyCategoryFocusNode = FocusNode(); + final addAgencyController = TextEditingController(); + Agency? selectedAgency; + Category? selectedCategory; + Agency? newAgency; + bool showIsPrivateRadio = false; + bool? isPrivate = false; + NonAcademicRecognition? nonAcademicRecognition; + final oldAgencyController = TextEditingController(); + final _formKey = GlobalKey(); + int? profileId; + String? token; + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocBuilder( + builder: (context, state) { + if (state is EditNonAcademeRecognitionState) { + oldAgencyController.text = + state.nonAcademicRecognition.presenter!.name!; + selectedAgency = state.nonAcademicRecognition.presenter; + selectedCategory = + state.nonAcademicRecognition.presenter!.category; + return SizedBox( + height: blockSizeVertical * 90, + child: SingleChildScrollView( + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: Column( + children: [ + FormBuilderTextField( + name: 'title', + initialValue: + state.nonAcademicRecognition.title, + decoration: normalTextFieldStyle( + "Recognition / Award Title *", + "Recognition / Award Title"), + validator: + FormBuilderValidators.required( + errorText: + "this field is required"), + ), + const SizedBox( + height: 12, + ), + StatefulBuilder( + builder: (context, setState) { + //// AGENCY SEARCHFIELD + return Column( + children: [ + SearchField( + controller: oldAgencyController, + itemHeight: 70, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name! + .toUpperCase(), + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency + .privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + focusNode: agencyFocusNode, + searchInputDecoration: + normalTextFieldStyle( + "Agency *", "") + .copyWith( + suffixIcon: + const Icon(Icons + .arrow_drop_down)), + ////agency suggestion tap + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + agencyFocusNode.unfocus(); + if (selectedAgency + ?.category == + null) { + showAgencyCategory = true; + showIsPrivateRadio = true; + } else { + showAgencyCategory = false; + showIsPrivateRadio = false; + } + }); + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment + .center, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + const SizedBox( + height: 20, + ), + const Text( + "No result found..."), + const SizedBox( + height: 10, + ), + TextButton( + //// Add agency onpressed + onPressed: () { + showDialog( + context: + context, + builder: + (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Agency?"), + content: + SizedBox( + height: + 130, + child: + Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle("", ""), + ), + const SizedBox( + height: + 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + //// onpressed + onPressed: () { + setState(() { + newAgency = Agency(id: null, name: addAgencyController.text.toUpperCase(), category: null, privateEntity: null); + state.agencies.insert(0, newAgency!); + addAgencyController.clear(); + Navigator.pop(context); + }); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: const Text( + "Add position")) + ]), + ), + ), + const SizedBox( + height: 8, + ), + SizedBox( + child: showAgencyCategory + ? SearchField( + focusNode: + agencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .agencyCategories + .map((Category + category) => + SearchFieldListItem( + category + .name!, + item: + category, + child: + ListTile( + title: Text( + category + .name!), + subtitle: Text(category + .industryClass! + .name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: Text( + "No result found ...")), + ), + ////agency controller suggestion tap + onSuggestionTap: + (agencyCategory) { + setState(() { + selectedCategory = + agencyCategory + .item; + + agencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", + "") + .copyWith( + suffixIcon: + const Icon( + Icons + .arrow_drop_down)), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: + InputDecoration( + border: + InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of( + context) + .textTheme + .headlineSmall! + .copyWith( + fontSize: + 24), + ), + const Icon(FontAwesome + .help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value + .toString() == + "YES") { + isPrivate = true; + } else { + isPrivate = false; + } + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: + lang)) + .toList( + growable: + false), + ) + : const SizedBox()), + ], + ); + }), + const SizedBox( + height: 24, + ), + SizedBox( + height: 60, + width: double.infinity, + child: ElevatedButton( + style: mainBtnStyle(primary, + Colors.transparent, second), + onPressed: () { + if (_formKey.currentState! + .saveAndValidate()) { + String title = _formKey + .currentState! + .value['title']; + + if (selectedAgency + ?.privateEntity != + null) { + newAgency = selectedAgency; + } else { + newAgency = Agency( + id: selectedAgency?.id, + name: + selectedAgency!.name, + category: + selectedCategory, + privateEntity: isPrivate); + } + nonAcademicRecognition = + NonAcademicRecognition( + id: state.nonAcademicRecognition.id, + title: title, + presenter: newAgency); + context + .read< + NonAcademicRecognitionBloc>() + .add(EditNonAcademeRecognition( + nonAcademicRecognition: + nonAcademicRecognition!, + profileId: profileId!, + token: token!)); + } + }, + child: const Text(submit)), + ) + ], + ), + )), + )); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/other_information/non_academic_recognition_screen.dart b/lib/screens/profile/components/other_information/non_academic_recognition_screen.dart new file mode 100644 index 0000000..56bac7f --- /dev/null +++ b/lib/screens/profile/components/other_information/non_academic_recognition_screen.dart @@ -0,0 +1,278 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/screens/profile/components/other_information/non_academic/add_modal.dart'; +import 'package:unit2/screens/profile/components/other_information/non_academic/edit_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; + +import '../../../../bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart'; +import '../../../../utils/alerts.dart'; + +class NonAcademicRecognitionScreen extends StatelessWidget { + const NonAcademicRecognitionScreen({ + super.key, + }); + + @override + Widget build(BuildContext context) { + int? profileId; + String? token; + return Scaffold( + appBar: AppBar( + title: const Text(nonAcademicRecTitle), + centerTitle: true, + backgroundColor: primary, + actions: [ + AddLeading(onPressed: () { + context + .read() + .add(ShowAddNonAcademeRecognitionForm()); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is NonAcademicRecognitionLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is NonAcademicRecognitionLoadedState || + state is NonAcademicRecognitionErrorState || + state is AddNonAcademeRecognitionState || state is EditNonAcademeRecognitionState || state is NonAcademeRecognitionEditedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////ADDED STATE + if (state is NonAcademeRecognitionAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(const GetNonAcademicRecognition()); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(const GetNonAcademicRecognition()); + }); + } + } + ////DELETED STATE + if (state is NonAcademeRecognitionDeletedState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Work has been deleted successfully", () { + Navigator.of(context).pop(); + context + .read() + .add(const GetNonAcademicRecognition()); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting Work History", () { + Navigator.of(context).pop(); + context + .read() + .add(const GetNonAcademicRecognition()); + }); + } + } + ////EDITED STATE + if (state is NonAcademeRecognitionEditedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add( LoadNonAcademeRecognition(nonAcademicRecognitions: state.nonAcademicRecognitions)); + }); + } else { + errorAlert(context, "Update Failed", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadNonAcademeRecognition(nonAcademicRecognitions: state.nonAcademicRecognitions)); + }); + } + } + }, + builder: (context, state) { + if (state is NonAcademicRecognitionLoadedState) { + if (state.nonAcademicRecognition.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: + state.nonAcademicRecognition.length, + itemBuilder: + (BuildContext context, int index) { + String award = state + .nonAcademicRecognition[index].title!; + String presenter = state + .nonAcademicRecognition[index] + .presenter! + .name!; + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + award, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500), + ), + const Divider(), + Text(presenter), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + + ////delete non academic recognition-= = = = = = = = =>> + if (value == 1) { + confirmAlert(context, () { + context + .read< + NonAcademicRecognitionBloc>() + .add(DeleteNonAcademeRecognition( + nonAcademicRecognition: + state + .nonAcademicRecognition[ + index], + profileId: + profileId!, + nonAcademicRecognitions: + state + .nonAcademicRecognition, + token: token!)); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 2) { + context + .read< + NonAcademicRecognitionBloc>() + .add(ShowEditNonAcademicRecognitionForm( + nonAcademicRecognition: + state.nonAcademicRecognition[ + index])); + } + }, + menuItems: [ + popMenuItem( + text: "Delete", + value: 1, + icon: Icons.delete), + popMenuItem( + text: "Edit", + value: 2, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + const EmptyData( + message: + "You don't have any Non Academic Recognition added. Please click + to add"); + } + } + if (state is AddNonAcademeRecognitionState) { + return const AddNonAcademicRecognitionScreen(); + }if(state is EditNonAcademeRecognitionState){ + return const EditNonAcademicRecognitionScreen(); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} + +PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); +} diff --git a/lib/screens/profile/components/other_information/org_membership/add_modal.dart b/lib/screens/profile/components/other_information/org_membership/add_modal.dart new file mode 100644 index 0000000..b2e60df --- /dev/null +++ b/lib/screens/profile/components/other_information/org_membership/add_modal.dart @@ -0,0 +1,324 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/other_information/org_membership/organization_membership_bloc.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/utils/text_container.dart'; +import '../../../../../model/utils/category.dart'; +import '../../../../../theme-data.dart/box_shadow.dart'; +import '../../../../../theme-data.dart/btn-style.dart'; +import '../../../../../theme-data.dart/colors.dart'; +import '../../../../../theme-data.dart/form-style.dart'; + +class AddOrgMemberShipScreen extends StatefulWidget { + final int profileId; + final String token; + const AddOrgMemberShipScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => _AddOrgMemberShipScreenState(); +} + +bool showAgencyCategory = false; +final agencyFocusNode = FocusNode(); + +final agencyCategoryFocusNode = FocusNode(); +final addAgencyController = TextEditingController(); +Agency? selectedAgency; +Category? selectedCategory; +Agency? newAgency; +bool showIsPrivateRadio = false; +bool? isPrivate = false; +final _formKey = GlobalKey(); +class _AddOrgMemberShipScreenState extends State { + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AddOrgMembershipState) { + return SingleChildScrollView( + child: FormBuilder( + key: _formKey, + child: Padding( + padding: + const EdgeInsets.symmetric(vertical: 25, horizontal: 18), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 100, + ), + StatefulBuilder(builder: (context, setState) { + //// AGENCY SEARCHFIELD + return Column( + children: [ + SearchField( + itemHeight: 70, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem(agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!.toUpperCase(), + overflow: TextOverflow.ellipsis, + ), + subtitle: Text( + agency.privateEntity == true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + focusNode: agencyFocusNode, + searchInputDecoration: normalTextFieldStyle( + "Agency *", "") + .copyWith( + suffixIcon: + const Icon(Icons.arrow_drop_down)), + ////agency suggestion tap + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + agencyFocusNode.unfocus(); + if (selectedAgency?.category == null) { + showAgencyCategory = true; + showIsPrivateRadio = true; + } else { + showAgencyCategory = false; + showIsPrivateRadio = false; + } + }); + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found..."), + const SizedBox( + height: 10, + ), + TextButton( + //// Add agency onpressed + onPressed: () { + showDialog( + context: context, + builder: + (BuildContext context) { + return AlertDialog( + title: const Text( + "Add Agency?"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle( + "", ""), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double + .infinity, + height: 50, + child: + ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + //// onpressed + onPressed: + () { + setState( + () { + newAgency = Agency( + id: null, + name: addAgencyController.text.toUpperCase(), + category: null, + privateEntity: null); + state.agencies.insert(0, + newAgency!); + addAgencyController.clear(); + Navigator.pop(context); + }); + }, + child: const Text( + "Add"))), + ], + ), + ), + ); + }); + }, + child: const Text("Add position")) + ]), + ), + ), + const SizedBox( + height: 8, + ), + SizedBox( + child: showAgencyCategory + ? SearchField( + focusNode: agencyCategoryFocusNode, + itemHeight: 70, + suggestions: state.agencyCategories + .map((Category category) => + SearchFieldListItem( + category.name!, + item: category, + child: ListTile( + title: + Text(category.name!), + subtitle: Text(category + .industryClass! + .name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: + Text("No result found ...")), + ), + ////agency controller suggestion tap + onSuggestionTap: (agencyCategory) { + setState(() { + selectedCategory = + agencyCategory.item; + + agencyCategoryFocusNode.unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: InputDecoration( + border: InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(fontSize: 24), + ), + const Icon( + FontAwesome.help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value.toString() == "YES") { + isPrivate = true; + } else { + isPrivate = false; + } + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: lang)) + .toList(growable: false), + ) + : const SizedBox()), + ], + ); + }), + ////SHOW CATEGORY AGENCY + + const SizedBox( + height: 24, + ), + SizedBox( + height: 60, + width: double.infinity, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (_formKey.currentState!.saveAndValidate()) { + if (selectedAgency?.privateEntity != null) { + newAgency = selectedAgency; + } else { + newAgency = Agency( + id: selectedAgency?.id, + name: selectedAgency!.name, + category: selectedCategory, + privateEntity: isPrivate); + } + + context + .read() + .add(AddOrgMembership( + agency: newAgency!, + profileId: widget.profileId, + token: widget.token)); + setState(() { + showAgencyCategory = false; + showIsPrivateRadio = false; + }); + } + }, + child: const Text(submit)), + ) + ]), + )), + ); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/other_information/org_membership_screen.dart b/lib/screens/profile/components/other_information/org_membership_screen.dart new file mode 100644 index 0000000..68cdc20 --- /dev/null +++ b/lib/screens/profile/components/other_information/org_membership_screen.dart @@ -0,0 +1,244 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/other_information/organization_memberships.dart'; +import 'package:unit2/screens/profile/components/other_information/org_membership/add_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/Leadings/close_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../../bloc/profile/other_information/org_membership/organization_membership_bloc.dart'; +import '../../../../utils/alerts.dart'; +import '../../../../utils/global.dart'; + +class OrgMembershipsScreen extends StatelessWidget { + const OrgMembershipsScreen({super.key}); + + @override + Widget build(BuildContext context) { + String? token; + int profileId; + return Scaffold( + appBar: AppBar( + title: const Text(orgMembershipTitle), + backgroundColor: primary, + centerTitle: true, + actions: context.watch().state is OrganizationMembershipLoaded?[ + AddLeading(onPressed: () { + context + .read() + .add(ShowAddOrgMembershipForm()); + }) + ]: context.watch().state is AddOrgMembershipState ?[CloseLeading(onPressed: (){ + context.read().add(const GetOrganizationMembership()); + })]:[] + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is OrgmembershipLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is OrganizationMembershipLoaded || + state is OrganizationMembershipErrorState || + state is AddOrgMembershipState || state is OrgMembershipDeletedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////ADDED STATE + if (state is OrgMembershipAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add( + LoadOrganizationMemberships( + )); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add( + LoadOrganizationMemberships( + )); + }); + } + } + ////DELETED STATE + if (state is OrgMembershipDeletedState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Work has been deleted successfully", () { + Navigator.of(context).pop(); + context.read().add( + LoadOrganizationMemberships( + )); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting Work History", () { + Navigator.of(context).pop(); + context.read().add( + LoadOrganizationMemberships( + )); + }); + } + } + + }, + builder: (context, state) { + if (state is OrganizationMembershipLoaded) { + return ListView.builder( + itemCount: state.orgMemberships.length, + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemBuilder: (BuildContext context, int index) { + String entity = state.orgMemberships[index] + .agency!.privateEntity == + false + ? governmentText.toUpperCase() + : privateText.toUpperCase(); + String agencyName = + state.orgMemberships[index].agency!.name!; + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row(children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + agencyName, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500), + ), + const Divider(), + Text( + entity, + style: Theme.of(context) + .textTheme + .labelLarge, + ), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + + ////delete orgmembership-= = = = = = = = =>> + if (value == 1) { + confirmAlert(context, () { + final progress = + ProgressHUD.of(context); + progress! + .showWithText("Loading..."); + context.read().add(DeleteOrgMemberShip(profileId: profileId, token: token!, org: state.orgMemberships[index])); + }, "Delete?", + "Confirm Delete?"); + } + + }, + menuItems: [ + + popMenuItem( + text: "Delete", + value: 1, + icon: Icons.delete), + + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ]), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } + if (state is AddOrgMembershipState) { + return AlertDialog( + content: AddOrgMemberShipScreen(profileId: profileId,token: token!,) + ); + }if(state is OrganizationMembershipErrorState){ + return SomethingWentWrong(message: state.message, onpressed: (){ + context.read().add(GetOrganizationMembership(token: token,profileId: profileId)); + }); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} +PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); +} + + +// const EmptyData(message: "You don't have any Organization Membership added. Please click + to add."), diff --git a/lib/screens/profile/components/other_information/skills_and_hobbies_screen.dart b/lib/screens/profile/components/other_information/skills_and_hobbies_screen.dart new file mode 100644 index 0000000..53a28a7 --- /dev/null +++ b/lib/screens/profile/components/other_information/skills_and_hobbies_screen.dart @@ -0,0 +1,360 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:simple_chips_input/simple_chips_input.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/other_information/skills_and_hobbies.dart'; +import 'package:unit2/screens/profile/components/other_information/skills_hobbies/add_modal.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; + +import '../../../../bloc/profile/other_information/hobbies/hoobies_bloc.dart'; +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../utils/alerts.dart'; + +class SkillHobbiesScreen extends StatefulWidget { + const SkillHobbiesScreen({super.key}); + + @override + State createState() => _SkillHobbiesScreenState(); +} + +class _SkillHobbiesScreenState extends State { + @override + Widget build(BuildContext context) { + String token; + int profileId; + final bloc = BlocProvider.of(context); + String output = ''; + String? deletedChip, deletedChipIndex; + final keySimpleChipsInput = GlobalKey(); + final FocusNode focusNode = FocusNode(); + return Scaffold( + appBar: AppBar( + title: const Text(skillAndHobbiesTitle), + backgroundColor: primary, + centerTitle: true, + actions: context.watch().state is AddHobbySkillState + ? [ + AddLeading(onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add Skills and Hobbies"), + content: SimpleChipsInput( + separatorCharacter: ",", + createCharacter: ",", + focusNode: focusNode, + validateInput: true, + autoFocus: true, + formKey: keySimpleChipsInput, + onSubmitted: (p0) { + setState(() { + output = p0; + }); + }, + onChipDeleted: (p0, p1) { + setState(() { + deletedChip = p0; + deletedChipIndex = p1.toString(); + }); + }, + onSaved: ((p0) { + setState(() { + output = p0; + }); + }), + chipTextStyle: const TextStyle( + color: Colors.white, + fontSize: 16, + ), + deleteIcon: const Icon( + Icons.delete, + size: 14.0, + color: second, + ), + widgetContainerDecoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.0), + border: Border.all(color: Colors.blue[100]!), + ), + chipContainerDecoration: BoxDecoration( + color: second, + borderRadius: BorderRadius.circular(50), + ), + placeChipsSectionAbove: false, + ), + actions: [ + ElevatedButton( + onPressed: () { + keySimpleChipsInput.currentState!.save(); + Navigator.of(context, rootNavigator: true).pop('dialog'); + bloc.add( + GetAddedHobbiesSkills( + addedHobbiesSkills: output)); + + }, + style: mainBtnStyle( + primary, Colors.transparent, second), + child: const Text(submit), + ) + ], + ); + }); + }) + ] + : [ + AddLeading(onPressed: () { + bloc.add(const ShowHobbySkillAddForm( + )); + + }) + ]), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + buildWhen: (previous, current) => false, + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token!; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is HobbiesLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is HobbiesLoadedState || + state is HobbiesErrorState || + state is AddHobbySkillState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////ADDED STATE + if (state is HobbiesAndSkillsAddedState) { + if (state.status['success']) { + successAlert(context, "Adding Successfull!", + state.status['message'], () { + Navigator.of(context).pop(); + context.read().add( + LoadHobbiesSkills( + skillsHobbies: + state.mySkillsAndHobbies)); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add( + LoadHobbiesSkills( + skillsHobbies: + state.mySkillsAndHobbies)); + }); + } + } + //// DELETED STATE + + if (state is HobbiesAndSkillsDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Skill/Hobby Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add( + LoadHobbiesSkills( + skillsHobbies: state.skillsHobbies)); + }); + } else { + errorAlert(context, "Deletion Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add( + LoadHobbiesSkills( + skillsHobbies: state.skillsHobbies)); + }); + } + } + }, + builder: (context, state) { + if (state is HobbiesLoadedState) { + + if (state.skillsAndHobbies.isNotEmpty) { + return Padding( + padding: const EdgeInsets.all(12), + child: Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.start, + clipBehavior: Clip.none, + verticalDirection: VerticalDirection.up, + crossAxisAlignment: + WrapCrossAlignment.start, + direction: Axis.horizontal, + children: state.skillsAndHobbies + .map((SkillsHobbies sh) { + return Wrap( + children: [ + Container( + padding: + const EdgeInsets.only(left: 6), + child: Wrap( + clipBehavior: Clip.antiAlias, + alignment: WrapAlignment.center, + crossAxisAlignment: + WrapCrossAlignment.center, + runAlignment: + WrapAlignment.center, + children: [ + Text( + sh.name!, + style: Theme.of(context) + .textTheme + .labelMedium, + ), + IconButton( + onPressed: () { + confirmAlert( + context, + () => context + .read< + HoobiesBloc>() + .add(DeleteSkillHobbies( + profileId: + profileId, + skillsHobbies: [ + sh + ], + token: + token)), + "Delete", + "Confirm Delete"); + }, + icon: const Icon( + Icons.delete, + size: 16, + color: second, + )) + ]), + ) + ], + ); + }).toList()), + ); + } else { + const EmptyData( + message: + "You don't have any Skills and Hobbies added. Please click + to add"); + } + } + if (state is AddHobbySkillState) { + return AddHobbiesAndSkillsScreen( + profileId: profileId, + token: token, + ); + } + // if (state is ShowAddModalState) { + // return AddModal(bloc: bloc); + // } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} + +// class AddModal extends StatefulWidget { +// final HoobiesBloc bloc; +// const AddModal({super.key, required this.bloc}); + +// @override +// State createState() => _AddModalState(); +// } + + + +// class _AddModalState extends State { +// @override +// Widget build(BuildContext context) { +// return BlocBuilder( +// builder: (context, state) { +// return AlertDialog( +// title: const Text("Add Skills and Hobbies"), +// content: SimpleChipsInput( +// separatorCharacter: ",", +// createCharacter: ",", +// focusNode: focusNode, +// validateInput: true, +// autoFocus: true, +// formKey: keySimpleChipsInput, +// onSubmitted: (p0) { +// setState(() { +// output = p0; +// }); +// }, +// onChipDeleted: (p0, p1) { +// setState(() { +// deletedChip = p0; +// deletedChipIndex = p1.toString(); +// }); +// }, +// onSaved: ((p0) { +// setState(() { +// output = p0; +// }); +// }), +// chipTextStyle: const TextStyle( +// color: Colors.white, +// fontSize: 16, +// ), +// deleteIcon: const Icon( +// Icons.delete, +// size: 14.0, +// color: second, +// ), +// widgetContainerDecoration: BoxDecoration( +// color: Colors.white, +// borderRadius: BorderRadius.circular(16.0), +// border: Border.all(color: Colors.blue[100]!), +// ), +// chipContainerDecoration: BoxDecoration( +// color: second, +// borderRadius: BorderRadius.circular(50), +// ), +// placeChipsSectionAbove: false, +// ), +// actions: [ +// ElevatedButton( +// onPressed: () { +// keySimpleChipsInput.currentState!.save(); +// context +// .read() +// .add(GetAddedHobbiesSkills(addedHobbiesSkills: output)); +// }, +// style: mainBtnStyle(primary, Colors.transparent, second), +// child: const Text(submit), +// ) +// ], +// ); +// }, +// ); +// } +// } diff --git a/lib/screens/profile/components/other_information/skills_hobbies/add_modal.dart b/lib/screens/profile/components/other_information/skills_hobbies/add_modal.dart new file mode 100644 index 0000000..8633278 --- /dev/null +++ b/lib/screens/profile/components/other_information/skills_hobbies/add_modal.dart @@ -0,0 +1,73 @@ +import 'dart:math'; + +import 'package:filter_list/filter_list.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:unit2/bloc/profile/other_information/hobbies/hoobies_bloc.dart'; +import 'package:unit2/model/profile/other_information/skills_and_hobbies.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; + +class AddHobbiesAndSkillsScreen extends StatefulWidget { +final int profileId; +final String token; + const AddHobbiesAndSkillsScreen({super.key,required this.profileId, required this.token}); + + @override + State createState() => + _AddHobbiesAndSkillsScreenState(); +} + +class _AddHobbiesAndSkillsScreenState extends State { + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if(state is AddHobbySkillState){ + final List selectedList= state.mySkillsAndHobbiesString.map((var element){ + return state.allSkillsAndHobbies.firstWhere((var data) => data.name == element ); + }).toList(); + return FilterListWidget( + themeData: FilterListThemeData(context,choiceChipTheme: const ChoiceChipThemeData(selectedBackgroundColor: primary)), + hideSelectedTextCount: true, + listData: state.allSkillsAndHobbies, + selectedListData: selectedList, + onApplyButtonClick: (list) { + // Navigator.pop(context, list); + context.read().add(AddHobbyAndSkills(profileId: widget.profileId, token: widget.token, skillsHobbies: list!)); + }, + choiceChipLabel: (item) { + + return item!.name; + }, + // choiceChipBuilder: (context, item, isSelected) { + // return Container( + // padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), + // margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10), + // decoration: BoxDecoration( + // border: Border.all( + // color: isSelected! ? Colors.blue[300]! : Colors.grey[300]!, + // )), + // child: Text(item.name), + // ); + // }, + validateSelectedItem: (list, val) { + /// identify if item is selected or not + return list!.contains(val); + }, + onItemSearch: (user, query) { + /// When search query change in search bar then this method will be called + /// + /// Check if items contains query + return user.name!.toLowerCase().contains(query.toLowerCase()); + }, + + ); + } + return Container(); + }, + ); + } +} diff --git a/lib/screens/profile/components/reference/add_modal.dart b/lib/screens/profile/components/reference/add_modal.dart new file mode 100644 index 0000000..6195f9c --- /dev/null +++ b/lib/screens/profile/components/reference/add_modal.dart @@ -0,0 +1,473 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:unit2/bloc/profile/references/references_bloc.dart'; +import 'package:unit2/model/location/address_category.dart'; +import 'package:unit2/model/location/barangay.dart'; +import 'package:unit2/model/profile/references.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global.dart'; +import '../../../../model/location/city.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../model/location/region.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../utils/location_utilities.dart'; +import '../../../../utils/text_container.dart'; + +class AddReferenceScreen extends StatefulWidget { + final int profileId; + final String token; + const AddReferenceScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => _AddReferenceScreenState(); +} + +class _AddReferenceScreenState extends State { + final formKey = GlobalKey(); + bool provinceCall = false; + bool cityCall = false; + bool barangayCall = false; + bool overseas = false; + List? provinces; + List? citymuns; + List? barangays; + List category = ['Permanent', "Residential", "Birthplace"]; + ////seletected + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + Barangay? selectedBarangay; + Country? selectedCountry; + AddressCategory? selectedCategory; + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AddReferenceState) { + return SingleChildScrollView( + child: SizedBox( + height: screenHeight * .95, + child: ProgressHUD( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 18), + child: FormBuilder( + key: formKey, + child: Column( + children: [ + const SizedBox(height: 25), + Row( + children: [ + ////LAST NAME + Flexible( + flex: 1, + child: FormBuilderTextField( + decoration: normalTextFieldStyle( + "Last name *", "Last name *"), + name: "lastname", + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + ), + const SizedBox( + width: 5, + ), + ////FIRST NAME + Flexible( + flex: 1, + child: FormBuilderTextField( + decoration: normalTextFieldStyle( + "First name *", "First name *"), + name: "firstname", + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + Row( + children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + decoration: normalTextFieldStyle( + "Middle name *", "Midlle name *"), + name: "middlename", + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + ), + const SizedBox( + width: 5, + ), + ////CATEGORY + Flexible( + flex: 1, + child: FormBuilderDropdown( + name: 'category', + validator: + FormBuilderValidators.required(errorText: ""), + decoration: + normalTextFieldStyle("Category", "Category"), + items: state.categories + .map>( + (AddressCategory cat) { + return DropdownMenuItem( + value: cat, + child: Text(cat.name!), + ); + }).toList(), + onChanged: (value) { + setState(() { + selectedCategory = value; + }); + }, + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + + ////OVERSEAS ADDRESS + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value!; + }); + }, + decoration: normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Overseas Address?"), + ), + SizedBox( + height: overseas == true ? 8 : 0, + ), + SizedBox( + child: overseas == false + ? Column( + children: [ + const SizedBox( + height: 12, + ), + ////REGION DROPDOWN + FormBuilderDropdown( + autovalidateMode: + AutovalidateMode.onUserInteraction, + validator: FormBuilderValidators.required( + errorText: "This field is required"), + onChanged: (Region? region) async { + if(selectedRegion != region){ + setState(() { + provinceCall = true; + }); + selectedRegion = region; + getProvinces(); + } + }, + initialValue: null, + decoration: normalTextFieldStyle( + "Region*", "Region"), + name: 'region', + items: state.regions + .map>( + (Region region) { + return DropdownMenuItem( + value: region, + child: Text(region.description!)); + }).toList(), + ), + const SizedBox( + height: 8, + ), + //// PROVINCE DROPDOWN + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.transparent, + inAsyncCall: provinceCall, + child: DropdownButtonFormField( + autovalidateMode: AutovalidateMode + .onUserInteraction, + validator: (value) => + value == null ? 'required' : null, + isExpanded: true, + value: selectedProvince, + onChanged: (Province? province) { + if(selectedProvince != province){ + setState(() { + cityCall = true; + }); + selectedProvince = province; + getCities(); + } + }, + items: provinces == null + ? [] + : provinces!.map< + DropdownMenuItem< + Province>>( + (Province province) { + return DropdownMenuItem( + value: province, + child: FittedBox( + child: Text(province + .description!), + )); + }).toList(), + decoration: normalTextFieldStyle( + "Province*", "Province")), + ), + ), + ////CITY MUNICIPALITY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: cityCall, + child: DropdownButtonFormField< + CityMunicipality>( + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + isExpanded: true, + onChanged: (CityMunicipality? city) { + if(selectedMunicipality != city){ + setState(() { + barangayCall = true; + }); + selectedMunicipality = city; + getBarangays(); + } + }, + decoration: normalTextFieldStyle( + "Municipality*", "Municipality"), + value: selectedMunicipality, + items: citymuns == null + ? [] + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality c) { + return DropdownMenuItem( + value: c, + child: + Text(c.description!)); + }).toList(), + ), + ), + ), + //// BARANGAY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: barangayCall, + child: DropdownButtonFormField( + + isExpanded: true, + onChanged: (Barangay? baragay) { + selectedBarangay = baragay; + }, + decoration: normalTextFieldStyle( + "Barangay*", "Barangay"), + value: selectedBarangay, + items: barangays == null + ? [] + : barangays!.map< + DropdownMenuItem>( + (Barangay barangay) { + return DropdownMenuItem( + value: barangay, + child: Text( + barangay.description!)); + }).toList(), + ), + ), + ), + ], + ) + //// COUNTRY DROPDOWN + : SizedBox( + height: 60, + child: FormBuilderDropdown( + initialValue: null, + validator: FormBuilderValidators.required( + errorText: "This field is required"), + items: state.countries + .map>( + (Country country) { + return DropdownMenuItem( + value: country, + child: FittedBox( + child: Text(country.name!))); + }).toList(), + name: 'country', + decoration: normalTextFieldStyle( + "Country*", "Country"), + onChanged: (Country? value) { + selectedCountry = value; + }, + ), + ), + ), + + FormBuilderTextField( + name: "mobile", + decoration: normalTextFieldStyle( + "Tel./Mobile *", "Tel./Mobile"), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const Expanded( + child: SizedBox(), + ), + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: + mainBtnStyle(primary, Colors.transparent, second), + child: const Text(submit), + onPressed: () { + PersonalReference? personalReference; + if (formKey.currentState!.saveAndValidate()) { + String lastname = + formKey.currentState!.value['lastname']; + String firstname = + formKey.currentState!.value['firstname']; + String middlename = + formKey.currentState!.value['middlename']; + String mobile = + formKey.currentState!.value['mobile']; + + Region? region = selectedRegion; + Province? province = Province( + code: selectedProvince?.code, + description: selectedProvince?.description, + region: region, + psgcCode: selectedProvince?.psgcCode, + shortname: selectedProvince?.shortname); + CityMunicipality? city = CityMunicipality( + code: selectedMunicipality?.code, + description: + selectedMunicipality?.description, + province: province, + psgcCode: selectedMunicipality?.psgcCode, + zipcode: selectedMunicipality?.zipcode); + + Address address = Address( + id: null, + addressCategory: selectedCategory, + country: selectedCountry, + barangay: selectedBarangay, + addressClass: null, + cityMunicipality: city); + + if (selectedCountry != null) { + personalReference = PersonalReference( + id: null, + address: Address( + id: null, + addressCategory: selectedCategory, + country: selectedCountry, + barangay: null, + cityMunicipality: null, + addressClass: null), + lastName: lastname, + contactNo: mobile, + firstName: firstname, + middleName: middlename); + } else { + personalReference = PersonalReference( + id: null, + address: address, + lastName: lastname, + contactNo: mobile, + firstName: firstname, + middleName: middlename); + } + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + context.read().add(AddReference( + profileId: widget.profileId, + reference: personalReference, + token: widget.token)); + } + }, + ), + ), + const SizedBox( + height: 20, + ), + ], + )), + ), + ), + ), + ); + } + return Container(); + }, + ); + } + + Future getProvinces() async { + try { + List newProvinces = await LocationUtils.instance + .getProvinces(regionCode: selectedRegion!.code.toString()); + setState(() { + provinces = newProvinces; + selectedProvince = provinces![0]; + provinceCall = false; + cityCall = true; + getCities(); + }); + } catch (e) { + context.read().add(CallErrorState()); + } + } + + Future getCities() async { + try { + List newCities = await LocationUtils.instance + .getCities(code: selectedProvince!.code.toString()); + citymuns = newCities; + setState(() { + selectedMunicipality = newCities[0]; + cityCall = false; + barangayCall = true; + getBarangays(); + }); + } catch (e) { + context.read().add(CallErrorState()); + } + } + + Future getBarangays() async { + try { + List newBarangays = await LocationUtils.instance + .getBarangay(code: selectedMunicipality!.code.toString()); + barangays = newBarangays; + setState(() { + selectedBarangay = newBarangays[0]; + barangayCall = false; + }); + } catch (e) { + context.read().add(CallErrorState()); + } + } +} diff --git a/lib/screens/profile/components/reference/edit_modal.dart b/lib/screens/profile/components/reference/edit_modal.dart new file mode 100644 index 0000000..136081e --- /dev/null +++ b/lib/screens/profile/components/reference/edit_modal.dart @@ -0,0 +1,625 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import '../../../../bloc/profile/references/references_bloc.dart'; +import '../../../../model/location/address_category.dart'; +import '../../../../model/location/barangay.dart'; +import '../../../../model/location/city.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../model/location/region.dart'; +import '../../../../model/profile/references.dart'; +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/location_utilities.dart'; +import '../../../../utils/text_container.dart'; + +class EditReferenceScreen extends StatefulWidget { + final String token; + final int profileId; + const EditReferenceScreen({super.key,required this.profileId, required this.token}); + + @override + State createState() => _EditReferenceScreenState(); +} + +class _EditReferenceScreenState extends State { + final formKey = GlobalKey(); + bool provinceCall = false; + bool cityCall = false; + bool barangayCall = false; + bool overseas = false; + List? provinces; + List? citymuns; + List? barangays; + ////seletected + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + Barangay? selectedBarangay; + Country? selectedCountry; + AddressCategory? selectedCategory; + + @override + Widget build(BuildContext context) { + + return BlocBuilder( + buildWhen: (previous, current) => false, + builder: (context, state) { + if (state is EditReferenceState) { + overseas = state.isOverseas; + selectedCategory = state.selectedCategory; + ////if not overseas address + //// set initial values + if (!overseas) { + selectedRegion = state.selectedRegion; + provinces = state.provinces; + selectedProvince = state.selectedProvince; + citymuns = state.cities; + selectedMunicipality = state.selectedCity; + barangays = state.barangays; + selectedBarangay = state.selectedBarangay; + } else { + selectedCountry = state.selectedCountry; + } + + return ProgressHUD( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: FormBuilder( + key: formKey, + child: Column( + children: [ + const SizedBox(height: 25), + Row( + children: [ + ////LAST NAME + Flexible( + flex: 1, + child: FormBuilderTextField( + initialValue: state.ref.lastName, + decoration: normalTextFieldStyle( + "Last name *", "Last name *"), + name: "lastname", + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ), + ), + const SizedBox( + width: 5, + ), + ////FIRST NAME + Flexible( + flex: 1, + child: FormBuilderTextField( + initialValue: state.ref.firstName, + decoration: normalTextFieldStyle( + "First name *", "First name *"), + name: "firstname", + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + Row( + children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + initialValue: state.ref.middleName, + decoration: normalTextFieldStyle( + "Middle name *", "Midlle name *"), + name: "middlename", + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ), + ), + const SizedBox( + width: 5, + ), + ////CATEGORY + Flexible( + flex: 1, + child: FormBuilderDropdown< + AddressCategory>( + name: 'category', + validator: + FormBuilderValidators.required( + errorText: ""), + decoration: normalTextFieldStyle( + "Category", "Category"), + items: state.categories.map< + DropdownMenuItem< + AddressCategory>>( + (AddressCategory cat) { + return DropdownMenuItem< + AddressCategory>( + value: cat, + child: Text(cat.name!), + ); + }).toList(), + initialValue: selectedCategory, + onChanged: (value) { + selectedCategory = value; + }, + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + + ////OVERSEAS ADDRESS + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value!; + }); + }, + decoration: + normalTextFieldStyle("", ''), + name: 'overseas', + title: + const Text("Overseas Address?"), + ), + SizedBox( + height: overseas == true ? 8 : 0, + ), + SizedBox( + child: overseas == false + ? Column( + children: [ + const SizedBox( + height: 12, + ), + ////REGION DROPDOWN + DropdownButtonFormField< + Region?>( + isExpanded: true, + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + onChanged: (Region? + region) async { + setState(() { + provinceCall = true; + + selectedRegion = + region; + }); + //// GET PROVINCES + provinces = await LocationUtils + .instance + .getProvinces( + regionCode: + selectedRegion! + .code + .toString()); + selectedProvince = + provinces![0]; + setState(() { + provinceCall = false; + cityCall = true; + }); + ////GET CITY MUNICIPALITY + citymuns = await LocationUtils + .instance + .getCities( + code: + selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = false; + barangayCall = true; + }); + //// GET BARANGAYS + barangays = + await LocationUtils + .instance + .getBarangay( + code: selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = false; + }); + }, + value: selectedRegion, + decoration: + normalTextFieldStyle( + "Region*", + "Region"), + items: state.regions.map< + DropdownMenuItem< + Region>>( + (Region region) { + return DropdownMenuItem< + Region>( + value: region, + child: Text(region + .description!)); + }).toList(), + ), + const SizedBox( + height: 8, + ), + //// PROVINCE DROPDOWN + SizedBox( + height: 60, + child: ModalProgressHUD( + color: + Colors.transparent, + inAsyncCall: + provinceCall, + child: DropdownButtonFormField< + Province?>( + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + onChanged: (Province? + province) async { + selectedProvince = + province; + setState(() { + cityCall = true; + }); + //// GET CITIES + citymuns = await LocationUtils + .instance + .getCities( + code: selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = + false; + barangayCall = + true; + }); + //// GET BARANGAY + barangays = await LocationUtils + .instance + .getBarangay( + code: selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = + false; + }); + }, + value: + selectedProvince, + items: provinces == + null + ? [] + : provinces!.map< + DropdownMenuItem< + Province>>((Province + province) { + return DropdownMenuItem( + value: + province, + child: + FittedBox( + child: + Text(province.description!), + )); + }).toList(), + decoration: + normalTextFieldStyle( + "Province*", + "Province")), + ), + ), + ////CITY MUNICIPALITY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: cityCall, + child: + DropdownButtonFormField< + CityMunicipality>( + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + isExpanded: true, + onChanged: + (CityMunicipality? + city) async { + setState(() { + barangayCall = + true; + }); + selectedMunicipality = + city; + //// GET BARANGAYS + barangays = await LocationUtils + .instance + .getBarangay( + code: selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = + false; + }); + }, + decoration: + normalTextFieldStyle( + "Municipality*", + "Municipality"), + value: + selectedMunicipality, + items: citymuns == + null + ? [] + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality + c) { + return DropdownMenuItem( + value: c, + child: Text( + c.description!)); + }).toList(), + ), + ), + ), + //// BARANGAY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: + barangayCall, + child: + DropdownButtonFormField< + Barangay>( + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + isExpanded: true, + onChanged: (Barangay? + baragay) { + selectedBarangay = + baragay; + }, + decoration: + normalTextFieldStyle( + "Barangay*", + "Barangay"), + value: + selectedBarangay, + items: barangays == + null + ? [] + : barangays!.map< + DropdownMenuItem< + Barangay>>((Barangay + barangay) { + return DropdownMenuItem( + value: + barangay, + child: Text( + barangay + .description!)); + }).toList(), + ), + ), + ), + ], + ) + //// COUNTRY DROPDOWN + : SizedBox( + height: 60, + child: + DropdownButtonFormField< + Country>( + isExpanded: true, + value: selectedCountry, + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + items: state.countries.map< + DropdownMenuItem< + Country>>( + (Country country) { + return DropdownMenuItem< + Country>( + value: country, + child: FittedBox( + child: Text( + country + .name!))); + }).toList(), + + decoration: + normalTextFieldStyle( + "Country*", + "Country"), + //// country dropdown + onChanged: + (Country? value) { + selectedCountry = value; + }, + ), + ), + ), + ], + ); + }), + + FormBuilderTextField( + initialValue: state.ref.contactNo, + name: "mobile", + decoration: normalTextFieldStyle( + "Tel./Mobile *", "Tel./Mobile"), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const Expanded( + child: SizedBox(), + ), + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + child: const Text(submit), + onPressed: () { + PersonalReference? personalReference; + if (formKey.currentState! + .saveAndValidate()) { + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Please wait..."); + String lastname = formKey + .currentState!.value['lastname']; + String firstname = formKey + .currentState!.value['firstname']; + String middlename = formKey + .currentState! + .value['middlename']; + String mobile = formKey + .currentState!.value['mobile']; + + Region? region = selectedRegion; + Province? province = Province( + code: selectedProvince?.code, + description: + selectedProvince?.description, + region: region, + psgcCode: + selectedProvince?.psgcCode, + shortname: + selectedProvince?.shortname); + CityMunicipality? city = + CityMunicipality( + code: selectedMunicipality + ?.code, + description: + selectedMunicipality + ?.description, + province: province, + psgcCode: selectedMunicipality + ?.psgcCode, + zipcode: selectedMunicipality + ?.zipcode); + + ////IF IS OVERSEAS + if (overseas) { + personalReference = + PersonalReference( + id: state.ref.id, + address: Address( + id: state + .ref.address!.id, + addressCategory: + selectedCategory, + country: + selectedCountry, + barangay: null, + cityMunicipality: null, + addressClass: null), + lastName: lastname, + contactNo: mobile, + firstName: firstname, + middleName: middlename); + } else { + //// IF NOT OVERSEAS + personalReference = + PersonalReference( + id: state.ref.id, + address: Address( + id: state + .ref.address!.id, + addressCategory: + selectedCategory, + country: Country( + id: 175, + code: null, + name: null), + barangay: + selectedBarangay, + cityMunicipality: city, + addressClass: state + .ref + .address + ?.addressClass), + lastName: lastname, + contactNo: mobile, + firstName: firstname, + middleName: middlename); + } + + context.read().add( + EditReference( + profileId: + widget.profileId, + reference: personalReference, + token: widget.token)); + } + }, + ), + ), + const SizedBox( + height: 20, + ), + ], + )), + ), + ); + } + return Container(); + }, + + ); + } +} diff --git a/lib/screens/profile/components/references_screen.dart b/lib/screens/profile/components/references_screen.dart new file mode 100644 index 0000000..f684f6c --- /dev/null +++ b/lib/screens/profile/components/references_screen.dart @@ -0,0 +1,340 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/screens/profile/components/reference/add_modal.dart'; +import 'package:unit2/screens/profile/components/reference/edit_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/Leadings/close_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; + +import '../../../bloc/profile/references/references_bloc.dart'; +import '../../../utils/alerts.dart'; + +class ReferencesScreen extends StatelessWidget { + const ReferencesScreen({super.key}); + + @override + Widget build(BuildContext context) { + int? profileId; + String? token; + return Scaffold( + resizeToAvoidBottomInset: true, + appBar: AppBar( + title: context.watch().state is AddReferenceState + ? const Text("Add Personal Reference") + : context.watch().state is EditReferenceState + ? const Text("Edit Personal Reference") + : const Text("Personal References"), + centerTitle: true, + backgroundColor: primary, + ////if state is adding or editing state show close button + actions: (context.watch().state + is AddReferenceState || + context.watch().state is EditReferenceState) + ? [ + //// close button + CloseLeading(onPressed: () { + context.read().add( + GetReferences(profileId: profileId!, token: token!)); + }), + ] + : + //// if state is loaded state show add button + context.watch().state is ReferencesLoadedState + ? [ + AddLeading(onPressed: () { + context + .read() + .add(ShowAddReferenceForm()); + }), + ] + : []), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + //userbloc + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId; + return BlocBuilder( + builder: (context, state) { + //profilebloc + if (state is ProfileLoaded) { + return BlocConsumer( + //listener + listener: (context, state) { + if (state is ReferencesLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ReferencesLoadedState || + state is AddReferenceState || + state is ReferencesErrorState || + state is DeleteReferenceState || + state is ReferencesAddedState || + state is EditReferenceState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////ADDED STATE + if (state is ReferencesAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( + )); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( + )); + }); + } + } + ////EDIT REFERENCE STATE + if (state is ReferenceEditedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( + )); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( + )); + }); + } + } + + ////DELETED STATE + if (state is DeleteReferenceState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Eligibility has been deleted successfully", + () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( +)); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting eligibility", () { + Navigator.of(context).pop(); + context.read().add( + LoadReferences( + )); + }); + } + } + }, + //builder + builder: (context, state) { + //references bloc + if (state is ReferencesLoadedState) { + if (state.references.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.references.length, + itemBuilder: + (BuildContext context, int index) { + String fullname = + "${state.references[index].firstName} ${state.references[index].middleName} ${state.references[index].lastName}"; + String addres = state.references[index] + .address!.country?.id != + 175 + ? "COUNTRY: ${state.references[index].address!.country!.name!.toUpperCase()}" + : "${state.references[index].address?.cityMunicipality?.description}, ${state.references[index].address?.cityMunicipality?.province?.description}, ${state.references[index].address?.cityMunicipality?.province?.region?.description}"; + + String mobile = state + .references[index].contactNo + .toString(); + return Column( + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + decoration: box1(), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text(fullname.toUpperCase(), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500)), + const Divider(), + const SizedBox( + height: 5, + ), + Text(addres, + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith( + fontWeight: + FontWeight + .w500)), + const SizedBox( + height: 8, + ), + Text( + "${mobileOrPhone.toUpperCase()} : $mobile", + style: Theme.of(context) + .textTheme + .labelMedium!), + ], + ), + ), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + ////delete eligibilty-= = = = = = = = =>> + if (value == 2) { + + confirmAlert(context, () { + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Please wait..."); + context + .read< + ReferencesBloc>() + .add(DeleteReference( + profileId: + profileId!, + refId: state + .references[ + index] + .id!, + references: state + .references, + token: token!)); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 1) { + ////edit reference-= = = = = = = = =>> + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Please wait..."); + context + .read() + .add(ShowEditReferenceForm( + personalReference: + state.references[ + index])); + } + }, + menuItems: [ + popMenuItem( + text: "Edit", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Delete", + value: 2, + icon: Icons.delete), + popMenuItem( + text: "Attachment", + value: 3, + icon: FontAwesome.attach) + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } + } + if (state is AddReferenceState) { + return AddReferenceScreen(profileId: profileId!, token: token!,); + } + if (state is EditReferenceState) { + return EditReferenceScreen(profileId: profileId!,token: token!,); + } + if (state is ReferencesErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () { + context.read().add(GetReferences(profileId: profileId!, token: token!)); + }); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } + + PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); + } +} diff --git a/lib/screens/profile/components/submenu.dart b/lib/screens/profile/components/submenu.dart index 72fa2d2..c412a36 100644 --- a/lib/screens/profile/components/submenu.dart +++ b/lib/screens/profile/components/submenu.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:unit2/theme-data.dart/colors.dart'; -ListTile subMenu(IconData icon, String title) { +ListTile subMenu(IconData icon, String title,Function() onTap) { return ListTile( leading: Container( margin: const EdgeInsets.only(left: 20), @@ -15,5 +15,6 @@ ListTile subMenu(IconData icon, String title) { style: const TextStyle(), ), trailing: const Icon(Icons.keyboard_arrow_right), + onTap: onTap, ); } diff --git a/lib/screens/profile/components/voluntary_works_screen.dart b/lib/screens/profile/components/voluntary_works_screen.dart new file mode 100644 index 0000000..a26ff67 --- /dev/null +++ b/lib/screens/profile/components/voluntary_works_screen.dart @@ -0,0 +1,155 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:intl/intl.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; + +import '../../../bloc/profile/voluntary_works/voluntary_work_bloc.dart'; + +class VolunataryWorkScreen extends StatelessWidget { + const VolunataryWorkScreen({super.key}); + + @override + Widget build(BuildContext context) { + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + return Scaffold( + appBar: AppBar( + title: const Text(voluntaryScreenTitle), + backgroundColor: primary, + actions: [AddLeading(onPressed: () {})], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is VoluntaryWorkLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is VoluntaryWorkLoadedState || + state is VoluntaryWorkErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is VoluntaryWorkLoadedState) { + if (state.voluntaryWorks.isNotEmpty) { + return ListView.builder( + itemCount: state.voluntaryWorks.length, + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemBuilder: + (BuildContext context, int index) { + String position = state + .voluntaryWorks[index].position!.title!; + String agency = state + .voluntaryWorks[index].agency!.name!; + String from = dteFormat2.format( + state.voluntaryWorks[index].fromDate!); + String hours = state + .voluntaryWorks[index].totalHours + .toString(); + String? to = + state.voluntaryWorks[index].toDate == + null + ? "Present" + : dteFormat2.format(state + .voluntaryWorks[index].toDate!); + return Column( + children: [ + Container( + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + position, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight + .w500), + ), + const SizedBox( + height: 5, + ), + Text( + agency, + style: Theme.of(context) + .textTheme + .titleSmall, + ), + const Divider(), + const SizedBox( + height: 3, + ), + Text( + "$duration : $from to $to"), + const SizedBox( + height: 5, + ), + Text( + "$numberOfHours : $hours hours"), + ]), + ), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.more_vert)) + ], + ), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + return const EmptyData( + message: + "You don't have any Voluntary Works added. Please click + to add."); + } + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + )), + ); + } +} diff --git a/lib/screens/profile/components/work_history/add_modal.dart b/lib/screens/profile/components/work_history/add_modal.dart new file mode 100644 index 0000000..3ba5b84 --- /dev/null +++ b/lib/screens/profile/components/work_history/add_modal.dart @@ -0,0 +1,771 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/profile/work_history.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.dart'; +import 'package:unit2/model/utils/category.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/utils/validators.dart'; + +import '../../../../model/utils/position.dart'; + +class AddWorkHistoryScreen extends StatefulWidget { + final int profileId; + final String token; + const AddWorkHistoryScreen({super.key, required this.profileId, required this.token}); + + @override + State createState() => _AddWorkHistoryScreenState(); +} + +class _AddWorkHistoryScreenState extends State { + final addAgencyController = TextEditingController(); + final addPositionController = TextEditingController(); + final toDateController = TextEditingController(); + final fromDateController = TextEditingController(); + final _formKey = GlobalKey(); + Position? selectedPosition; + Agency? selectedAgency; + AppoinemtStatus? selectedStatus; + Category? selectedAgencyCategory; + String? salary; + String? salaryGrade; + String? salaryGradeStep; + bool showAgency = false; + bool showSalaryGradeAndSalaryStep = false; + bool? isPrivate = false; + bool showIsPrivateRadio = false; + bool currentlyEmployed = false; + final agencyFocusNode = FocusNode(); + final positionFocusNode = FocusNode(); + final appointmentStatusNode = FocusNode(); + final agencyCategoryFocusNode = FocusNode(); + int? profileId; + String? token; + @override + void dispose() { + addPositionController.dispose(); + addAgencyController.dispose(); + toDateController.dispose(); + fromDateController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + + return BlocConsumer( + listener: (context, state) { + if (state is AddWorkHistoryState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, builder: (context, state) { + if (state is AddWorkHistoryState) { + return SingleChildScrollView( + child: SizedBox( + height: blockSizeVertical * 90, + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: Column( + children: [ + ////POSITIONS + StatefulBuilder(builder: (context, setState) { + return SearchField( + itemHeight: 50, + suggestionsDecoration: box1(), + suggestions: state.agencyPositions + .map((Position position) => + SearchFieldListItem(position.title!, + item: position, + child: Padding( + padding: const EdgeInsets + .symmetric( + horizontal: 10), + child: ListTile( + title: + Text(position.title!), + )))) + .toList(), + focusNode: positionFocusNode, + searchInputDecoration: + normalTextFieldStyle("Position *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + onSuggestionTap: (position) { + setState(() { + selectedPosition = position.item; + positionFocusNode.unfocus(); + }); + }, + ////EMPTY WIDGET + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found..."), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + ////ADD POSITION DIALOG + showDialog( + context: context, + builder: (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Position?"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addPositionController, + decoration: + normalTextFieldStyle( + "", + ""), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double + .infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: () { + setState( + () { + Position + newAgencyPosition = + Position(id: null, title: addPositionController.text.toUpperCase()); + + state.agencyPositions.insert(0, + newAgencyPosition); + selectedPosition = + newAgencyPosition; + addPositionController.text = + ""; + Navigator.pop(context); + }); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: + const Text("Add position")) + ]), + ), + validator: (position) { + if (position!.isEmpty) { + return "This field is required"; + } + return null; + }, + ); + }), + const SizedBox( + height: 12, + ), + ////APPOINTMENT STATUS' + SearchField( + suggestions: state.appointmentStatus + .map((AppoinemtStatus status) => + SearchFieldListItem(status.label, + item: status)) + .toList(), + focusNode: appointmentStatusNode, + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + onSuggestionTap: (status) { + selectedStatus = status.item; + appointmentStatusNode.unfocus(); + }, + searchInputDecoration: normalTextFieldStyle( + "Appointment Status", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + ), + + const SizedBox( + height: 12, + ), + + ////AGENCY + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + SearchField( + itemHeight: 70, + focusNode: agencyFocusNode, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow + .ellipsis, + ), + subtitle: Text( + agency.privateEntity == + true + ? "Private" + : agency.privateEntity == false? "Government":""), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle("Agency *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + + if (selectedAgency!.privateEntity == + null) { + showIsPrivateRadio = true; + } else { + showIsPrivateRadio = false; + } + if (selectedAgency!.privateEntity == + true) { + showSalaryGradeAndSalaryStep = + false; + } + if (selectedAgency!.privateEntity == + false) { + showSalaryGradeAndSalaryStep = + true; + } + agencyFocusNode.unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found"), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Position"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle( + "", + ""), + ), + const SizedBox( + height: + 12, + ), + SizedBox( + width: double + .infinity, + height: + 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: () { + setState(() { + Agency newAgency = Agency(id: null, name: addAgencyController.text.toUpperCase(), category: null, privateEntity: null); + + state.agencies.insert(0, newAgency); + selectedAgency = newAgency; + addAgencyController.text = ""; + showAgency = true; + + showIsPrivateRadio = true; + + Navigator.pop(context); + }); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: const Text( + "Add Agency")) + ]), + ), + ), + + SizedBox( + height: showAgency ? 12 : 0, + ), + ////SHOW CATEGORY AGENCY + SizedBox( + child: showAgency + ? SearchField( + focusNode: + agencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .agencyCategory + .map((Category category) => + SearchFieldListItem( + category.name!, + item: category, + child: ListTile( + title: Text( + category + .name!), + subtitle: Text( + category + .industryClass! + .name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: Text( + "No result found ...")), + ), + onSuggestionTap: + (agencyCategory) { + setState(() { + selectedAgencyCategory = + agencyCategory.item; + agencyCategoryFocusNode + .unfocus(); + selectedAgency = Agency( + id: null, + name: selectedAgency! + .name, + category: + selectedAgencyCategory, + privateEntity: null); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", "") + .copyWith( + suffixIcon: + const Icon(Icons + .arrow_drop_down)), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: InputDecoration( + border: InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of( + context) + .textTheme + .headlineSmall! + .copyWith( + fontSize: 24), + ), + const Icon(FontAwesome + .help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value.toString() == + "YES") { + isPrivate = true; + showSalaryGradeAndSalaryStep = + false; + } else { + isPrivate = false; + showSalaryGradeAndSalaryStep = + true; + } + selectedAgency = Agency( + id: null, + name: selectedAgency! + .name, + category: + selectedAgencyCategory, + privateEntity: value == "YES"?true:false); + agencyFocusNode.unfocus(); + agencyCategoryFocusNode + .unfocus(); + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators + .required(), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: lang)) + .toList(growable: false), + ) + : const SizedBox()), + ////SALARY GRADE AND SALARY GRADE STEP + SizedBox( + child: showSalaryGradeAndSalaryStep + ? Column( + children: [ + Row( + children: [ + Flexible( + flex: 1, + child: + FormBuilderTextField( + name: + 'salary_grade', + keyboardType: + TextInputType + .number, + decoration: + normalTextFieldStyle( + "Salary Grade (SG)", + "0"), + onChanged: (value) { + salaryGrade = + value; + }, + validator: + FormBuilderValidators + .compose([ + FormBuilderValidators + .integer( + radix: 10, + errorText: + "Please enter a number"), + FormBuilderValidators + .numeric( + errorText: + "Please enter a number") + ]), + autovalidateMode: + AutovalidateMode + .onUserInteraction, + ), + ), + const SizedBox( + width: 12, + ), + Flexible( + flex: 1, + child: + FormBuilderTextField( + name: 'salary_step', + keyboardType: + TextInputType + .number, + decoration: + normalTextFieldStyle( + "SG Step (SG)", + "0"), + validator: + FormBuilderValidators + .compose([ + FormBuilderValidators + .integer( + radix: 10, + errorText: + "Please enter a number"), + FormBuilderValidators + .numeric( + errorText: + "Please enter a number") + ]), + autovalidateMode: + AutovalidateMode + .onUserInteraction, + onChanged: (value) { + setState(() { + salaryGradeStep = + value; + }); + }, + ), + ) + ], + ) + ], + ) + : null), + ], + ); + }), + const SizedBox( + height: 12, + ), + ////MONTHLY SALARY + FormBuilderTextField( + onChanged: (value) { + setState(() { + salary = value; + }); + }, + validator: numericRequired, + name: "salary", + decoration: normalTextFieldStyle( + "Monthly Salary *", "") + .copyWith(prefix: const Text("₱ ")), + ), + + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + ////CURRENTLY EMPLOYED + FormBuilderSwitch( + initialValue: currentlyEmployed, + activeColor: second, + onChanged: (value) { + setState(() { + if (value == true) { + currentlyEmployed = true; + toDateController.text = "PRESENT"; + } else { + currentlyEmployed = false; + toDateController.text = ""; + } + }); + }, + decoration: + normalTextFieldStyle("", ''), + name: 'overseas', + title: + const Text("Currently Employed?"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators.required(errorText: "This field is required"), + use24HourFormat: false, + icon: const Icon( + Icons.date_range), + controller: + fromDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: + normalTextFieldStyle( + "From *", + "From *") + .copyWith( + prefixIcon: + const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 12, + ), + //// TO DATE + Flexible( + flex: 1, + child: currentlyEmployed + ? TextFormField( + enabled: false, + initialValue: "PRESENT", + style: const TextStyle( + color: + Colors.black45), + decoration: + normalTextFieldStyle( + "", "") + .copyWith(), + ) + : DateTimePicker( + validator: FormBuilderValidators.required(errorText: "This field is required"), + controller: + toDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "To *", "To *") + .copyWith( + prefixIcon: + const Icon( + Icons + .date_range, + color: Colors + .black87, + ), + prefixText: + currentlyEmployed + ? "PRESENT" + : ""), + initialValue: null, + ), + ), + ], + ), + ), + ], + ); + }), + const Expanded(child: SizedBox()), + ////SUBMIT BUTTON + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + + if (_formKey.currentState!.validate()) { + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Loading..."); + WorkHistory workHistory = WorkHistory( + position: selectedPosition, + id: null, + agency: selectedAgency, + fromDate: fromDateController + .text.isEmpty + ? null + : DateTime.parse( + fromDateController.text), + toDate: toDateController.text.isEmpty || + toDateController.text + .toUpperCase() == + "PRESENT" + ? null + : DateTime.parse( + toDateController.text), + salaryGrade: salaryGrade == null + ? null + : int.parse(salaryGrade!), + sgStep: salaryGradeStep == null + ? null + : int.parse(salaryGradeStep!), + monthlySalary: + double.parse(salary!), + appointmentStatus: + selectedStatus!.value); + context.read().add( + AddWorkHostory( + workHistory: workHistory, + profileId: profileId!, + token: token!, + isPrivate: isPrivate!)); + } + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ], + ), + ), + ), + ), + ); + } + return Container(); + }); + } +} diff --git a/lib/screens/profile/components/work_history/edit_modal.dart b/lib/screens/profile/components/work_history/edit_modal.dart new file mode 100644 index 0000000..bff0072 --- /dev/null +++ b/lib/screens/profile/components/work_history/edit_modal.dart @@ -0,0 +1,770 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import '../../../../bloc/profile/profile_bloc.dart'; +import '../../../../bloc/profile/workHistory/workHistory_bloc.dart'; +import '../../../../bloc/user/user_bloc.dart'; +import '../../../../model/profile/work_history.dart'; +import '../../../../model/utils/agency.dart'; +import '../../../../model/utils/agency_position.dart'; +import '../../../../model/utils/category.dart'; +import '../../../../model/utils/position.dart'; +import '../../../../theme-data.dart/box_shadow.dart'; +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; +import '../../../../utils/text_container.dart'; +import '../../../../utils/validators.dart'; + +class EditWorkHistoryScreen extends StatefulWidget { + final int profileId; + final String token; + const EditWorkHistoryScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => _EditWorkHistoryScreenState(); +} + +class _EditWorkHistoryScreenState extends State { + final addAgencyController = TextEditingController(); + final addPositionController = TextEditingController(); + final toDateController = TextEditingController(); + final fromDateController = TextEditingController(); + final oldPositionController = TextEditingController(); + final oldAppointmentStatusController = TextEditingController(); + final oldAgencyController = TextEditingController(); + final _formKey = GlobalKey(); + Position? selectedPosition; + Agency? selectedAgency; + AppoinemtStatus? selectedStatus; + Category? selectedAgencyCategory; + String? salary; + String? salaryGrade; + String? salaryGradeStep; + //show agency category is a variable to show adding of agency category if you add agency manually + bool showAgencyCategory = false; + //showSalaryGadeAndSalaryStep is a variable that will show salary + //and salary step if selected agency is government + bool showSalaryGradeAndSalaryStep = false; + //isPrivate is the value of the isPrivate radion button + bool? isPrivate = false; + //showIsPrivateRadion is a variable that will show isPrivate radio if you + //add agency manually + bool showIsPrivateRadio = false; + bool currentlyEmployed = false; + final agencyFocusNode = FocusNode(); + final positionFocusNode = FocusNode(); + final appointmentStatusNode = FocusNode(); + final agencyCategoryFocusNode = FocusNode(); + int? profileId; + String? token; + @override + void dispose() { + addPositionController.dispose(); + addAgencyController.dispose(); + toDateController.dispose(); + fromDateController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BlocBuilder(builder: (context, state) { + return BlocBuilder( + builder: (context, state) { + if (state is EditWorkHistoryState) { + oldPositionController.text = state.workHistory.position!.title!; + oldAppointmentStatusController.text = + state.workHistory.appointmentStatus!; + oldAgencyController.text = state.workHistory.agency!.name!; + currentlyEmployed = state.workHistory.toDate == null ? true : false; + showSalaryGradeAndSalaryStep = + !state.workHistory.agency!.privateEntity!; + fromDateController.text = state.workHistory.fromDate.toString(); + toDateController.text = state.workHistory.toDate.toString(); + currentlyEmployed = state.workHistory.toDate == null ? true : false; + + return SingleChildScrollView( + child: SizedBox( + height: blockSizeVertical * 90, + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: Column( + children: [ + ////POSITIONS + StatefulBuilder(builder: (context, setState) { + return SearchField( + controller: oldPositionController, + itemHeight: 50, + suggestionsDecoration: box1(), + suggestions: state.agencyPositions + .map((Position position) => SearchFieldListItem( + position.title!, + item: position, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10), + child: ListTile( + title: Text(position.title!), + )))) + .toList(), + focusNode: positionFocusNode, + searchInputDecoration: + normalTextFieldStyle("Position *", "").copyWith( + suffixIcon: + const Icon(Icons.arrow_drop_down)), + onSuggestionTap: (position) { + setState(() { + selectedPosition = position.item; + positionFocusNode.unfocus(); + }); + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found..."), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Add Position?"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addPositionController, + decoration: + normalTextFieldStyle( + "", ""), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: + double.infinity, + height: 50, + child: + ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: + () { + setState( + () { + Position + newAgencyPosition = + Position( + id: null, + title: addPositionController.text.toUpperCase()); + state.agencyPositions.insert( + 0, + newAgencyPosition); + selectedPosition = + newAgencyPosition; + addPositionController.text = + ""; + Navigator.pop( + context); + }); + }, + child: const Text( + "Add"))), + ], + ), + ), + ); + }); + }, + child: const Text("Add position")) + ]), + ), + validator: (position) { + if (position!.isEmpty) { + return "This field is required"; + } + return null; + }, + ); + }), + const SizedBox( + height: 12, + ), + ////APPOINTMENT STATUS' + SearchField( + controller: oldAppointmentStatusController, + suggestions: state.appointmentStatus + .map((AppoinemtStatus status) => + SearchFieldListItem(status.label, + item: status)) + .toList(), + focusNode: appointmentStatusNode, + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + onSuggestionTap: (status) { + selectedStatus = status.item; + appointmentStatusNode.unfocus(); + }, + searchInputDecoration: + normalTextFieldStyle("Appointment Status", "") + .copyWith( + suffixIcon: + const Icon(Icons.arrow_drop_down)), + ), + + const SizedBox( + height: 12, + ), + + ////AGENCY + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + SearchField( + controller: oldAgencyController, + itemHeight: 70, + focusNode: agencyFocusNode, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem(agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow.ellipsis, + ), + subtitle: Text( + agency.privateEntity == true + ? "Private" + : "Government"), + ))) + .toList(), + searchInputDecoration: normalTextFieldStyle( + "Agency *", "") + .copyWith( + suffixIcon: + const Icon(Icons.arrow_drop_down)), + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + if (selectedAgency!.privateEntity == null) { + showIsPrivateRadio = true; + } else { + showIsPrivateRadio = false; + } + if (selectedAgency!.privateEntity == true) { + showSalaryGradeAndSalaryStep = false; + } + if (selectedAgency!.privateEntity == + false) { + showSalaryGradeAndSalaryStep = true; + } + agencyFocusNode.unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: Container( + decoration: box1(), + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found"), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: + (BuildContext context) { + return AlertDialog( + title: const Text( + "Add Position"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle( + "", ""), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double + .infinity, + height: 50, + child: + ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: + () { + setState( + () { + Agency newAgency = Agency( + id: null, + name: addAgencyController.text.toUpperCase(), + category: null, + privateEntity: null); + state.agencies.insert(0, + newAgency); + selectedAgency = + newAgency; + addAgencyController.text = + ""; + showAgencyCategory = + true; + + showIsPrivateRadio = + true; + + Navigator.pop(context); + }); + }, + child: const Text( + "Add"))), + ], + ), + ), + ); + }); + }, + child: const Text("Add Agency")) + ]), + ), + ), + + SizedBox( + height: showAgencyCategory ? 12 : 0, + ), + ////SHOW AGENCY CATEGORY + SizedBox( + child: showAgencyCategory + ? SearchField( + focusNode: agencyCategoryFocusNode, + itemHeight: 70, + suggestions: state.agencyCategory + .map((Category category) => + SearchFieldListItem( + category.name!, + item: category, + child: ListTile( + title: + Text(category.name!), + subtitle: Text(category + .industryClass! + .name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: + Text("No result found ...")), + ), + onSuggestionTap: (agencyCategory) { + setState(() { + selectedAgencyCategory = + agencyCategory.item; + agencyCategoryFocusNode.unfocus(); + selectedAgency = Agency( + id: null, + name: selectedAgency!.name, + category: + selectedAgencyCategory, + privateEntity: null); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: InputDecoration( + border: InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(fontSize: 24), + ), + const Icon( + FontAwesome.help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value.toString() == "YES") { + isPrivate = true; + showSalaryGradeAndSalaryStep = + false; + } else { + isPrivate = false; + showSalaryGradeAndSalaryStep = + true; + } + selectedAgency = Agency( + id: null, + name: selectedAgency!.name, + category: + selectedAgencyCategory, + privateEntity: value == "YES" + ? true + : false); + agencyFocusNode.unfocus(); + agencyCategoryFocusNode.unfocus(); + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators.required(), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: lang)) + .toList(growable: false), + ) + : const SizedBox()), + SizedBox( + height: showSalaryGradeAndSalaryStep ? 12 : 0, + ), + ////SALARY GRADE AND SALARY GRADE STEP + SizedBox( + child: showSalaryGradeAndSalaryStep + ? Column( + children: [ + Row( + children: [ + ////SALARY GRADE + Flexible( + flex: 1, + child: FormBuilderTextField( + initialValue: state + .workHistory.salaryGrade + ?.toString(), + name: 'salary_grade', + keyboardType: + TextInputType.number, + decoration: + normalTextFieldStyle( + "Salary Grade (SG)", + "0"), + validator: + integerAndNumeric, + autovalidateMode: + AutovalidateMode + .onUserInteraction, + ), + ), + const SizedBox( + width: 12, + ), + //// SALARY STEP + Flexible( + flex: 1, + child: FormBuilderTextField( + initialValue: state + .workHistory.sgStep + ?.toString(), + name: 'salary_step', + keyboardType: + TextInputType.number, + decoration: + normalTextFieldStyle( + "SG Step (SG)", + "0"), + validator: + integerAndNumeric, + autovalidateMode: + AutovalidateMode + .onUserInteraction, + ), + ) + ], + ) + ], + ) + : null), + ], + ); + }), + const SizedBox( + height: 12, + ), + ////MONTHLY SALARY + FormBuilderTextField( + initialValue: + state.workHistory.monthlySalary.toString(), + onChanged: (value) { + setState(() { + salary = value; + }); + }, + validator: numericRequired, + name: "salary", + decoration: + normalTextFieldStyle("Monthly Salary *", "") + .copyWith(prefix: const Text("₱ ")), + ), + + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + ////CURRENTLY EMPLOYED + FormBuilderSwitch( + initialValue: currentlyEmployed, + activeColor: second, + onChanged: (value) { + setState(() { + if (value == true) { + currentlyEmployed = true; + toDateController.text = "PRESENT"; + } else { + currentlyEmployed = false; + toDateController.text = ""; + } + }); + }, + decoration: normalTextFieldStyle("", ''), + name: 'overseas', + title: const Text("Currently Employed?"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + use24HourFormat: false, + icon: const Icon(Icons.date_range), + controller: fromDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: normalTextFieldStyle( + "From *", "From *") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 12, + ), + //// TO DATE + Flexible( + flex: 1, + child: currentlyEmployed + ? TextFormField( + enabled: false, + initialValue: "PRESENT", + style: const TextStyle( + color: Colors.black45), + decoration: normalTextFieldStyle( + "", "") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black45, + )), + ) + : DateTimePicker( + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + controller: toDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "To *", "To *") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + ), + prefixText: + currentlyEmployed + ? "PRESENT" + : ""), + initialValue: null, + ), + ), + ], + ), + ), + ], + ); + }), + const Expanded(child: SizedBox()), + ////SUBMIT BUTTON + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (_formKey.currentState!.saveAndValidate()) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + salary = + _formKey.currentState!.value['salary']; + selectedPosition ??= + state.workHistory.position; + salaryGrade = _formKey + .currentState!.value['salary_grade']; + salaryGradeStep = _formKey + .currentState!.value['salary_step']; + selectedAgency ??= state.workHistory.agency; + + selectedStatus ??= AppoinemtStatus( + value: + state.workHistory.appointmentStatus!, + label: + state.workHistory.appointmentStatus!); + WorkHistory newWorkHistory = WorkHistory( + id: state.workHistory.id, + position: selectedPosition, + agency: selectedAgency, + fromDate: fromDateController.text.isEmpty + ? null + : DateTime.parse( + fromDateController.text), + toDate: toDateController.text.isEmpty || + toDateController.text + .toUpperCase() == + "PRESENT" || + toDateController.text + .toLowerCase() == + 'null' + ? null + : DateTime.parse(toDateController.text), + monthlySalary: double.parse(salary!), + appointmentStatus: selectedStatus!.value, + salaryGrade: salaryGrade == null + ? null + : int.parse(salaryGrade!), + sgStep: salaryGradeStep == null + ? null + : int.parse(salaryGradeStep!), + ); + context.read().add( + UpdateWorkHistory( + oldWorkHistory: state.workHistory, + profileId: profileId.toString(), + token: token!, + workHistory: newWorkHistory)); + } + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ], + ), + ), + ), + ), + ); + } + return const Center( + child: Text("Add Work History"), + ); + }, + ); + }); + } +} diff --git a/lib/screens/profile/components/work_history_screen.dart b/lib/screens/profile/components/work_history_screen.dart new file mode 100644 index 0000000..96de174 --- /dev/null +++ b/lib/screens/profile/components/work_history_screen.dart @@ -0,0 +1,335 @@ +import 'dart:io'; +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:intl/intl.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/screens/profile/components/work_history/add_modal.dart'; +import 'package:unit2/screens/profile/components/work_history/edit_modal.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/Leadings/close_leading.dart'; +import 'package:unit2/widgets/empty_data.dart'; +import 'package:unit2/widgets/error_state.dart'; + +import '../../../bloc/profile/workHistory/workHistory_bloc.dart'; +import '../../../model/profile/work_history.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; + +class WorkHistoryScreen extends StatelessWidget { + const WorkHistoryScreen({super.key}); + + @override + Widget build(BuildContext context) { + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + String? token; + int profileId; + return Scaffold( + appBar: AppBar( + title: const Text(workHistoryScreenTitle), + backgroundColor: primary, + centerTitle: true, + actions: context.watch().state is WorkHistoryLoaded?[ + AddLeading(onPressed: () { + context.read().add(ShowAddWorkHistoryForm()); + }) + ]:(context.watch().state is AddWorkHistoryState || context.watch().state is EditWorkHistoryState)?[ + CloseLeading(onPressed: (){ + context.read().add(LoadWorkHistories()); + }) + ]:[], + ), + body: + //UserBloc + ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle( + color: Colors.white, + ), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + profileId = state.userData!.user!.login!.user!.profileId!; + return BlocBuilder( + builder: (context, state) { + //ProfileBloc + if (state is ProfileLoaded) { + //WorkHistoryBloc + return BlocConsumer( + listener: (context, state) { + if (state is WorkHistoryLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is WorkHistoryLoaded || + state is WorkHistoryErrorState || + state is AddWorkHistoryState || + state is WorkHistoryAddedState || + state is EditWorkHistoryState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + //DELETED STATE + if (state is DeletedState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Work has been deleted successfully", () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting Work History", () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } + } + ////ADDED STATE + if (state is WorkHistoryAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } + } + //// EDITED STATE + if (state is WorkHistoryEditedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadWorkHistories()); + }); + } + } + }, + builder: (context, state) { + if (state is WorkHistoryLoaded) { + if (state.workExperiences.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.workExperiences.length, + itemBuilder: + (BuildContext context, int index) { + String position = state + .workExperiences[index] + .position! + .title!; + String agency = state + .workExperiences[index].agency!.name!; + String from = dteFormat2.format( + state.workExperiences[index].fromDate!); + String? to = + state.workExperiences[index].toDate == + null + ? present.toUpperCase() + : dteFormat2.format(state + .workExperiences[index] + .toDate!); + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row(children: [ + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + position, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w600), + ), + const Divider(), + const SizedBox( + height: 8, + ), + Text( + agency, + style: Theme.of(context) + .textTheme + .titleSmall! + .copyWith( + fontWeight: + FontWeight.w500), + ), + const SizedBox( + height: 5, + ), + Text( + "$from $to ", + style: Theme.of(context) + .textTheme + .bodyMedium, + ), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + ////delete workhistory-= = = = = = = = =>> + if (value == 2) { + confirmAlert(context, () { + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Loading..."); + BlocProvider.of< + WorkHistoryBloc>( + context) + .add(DeleteWorkHistory( + profileId: profileId, + token: token!, + workHistory: + state.workExperiences[ + index], + )); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 1) { + ////edit eligibilty-= = = = = = = = =>> + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Loading..."); + WorkHistory workHistory = + state.workExperiences[ + index]; + context + .read() + .add( + ShowEditWorkHistoryForm( + workHistory: + workHistory)); + } + }, + menuItems: [ + popMenuItem( + text: "Edit", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Delete", + value: 2, + icon: Icons.delete), + popMenuItem( + text: "Attachment", + value: 3, + icon: FontAwesome.attach) + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ]), + ), + const SizedBox( + height: 5, + ), + ], + ); + }); + } else { + return const EmptyData( + message: + "You don't have any work experience added. Please click + to add"); + } + } + if (state is AddWorkHistoryState) { + return AddWorkHistoryScreen(profileId: profileId, token: token!,); + } + if (state is EditWorkHistoryState) { + return EditWorkHistoryScreen(profileId: profileId,token: token!,); + } + if (state is WorkHistoryErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () { + context.read().add(GetWorkHistories(profileId: profileId,token: token!)); + }); + } + return Container(); + }, + ); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} + +PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); +} diff --git a/lib/screens/profile/profile.dart b/lib/screens/profile/profile.dart index 672d8c1..da19d56 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -1,154 +1,377 @@ import 'package:expandable_group/expandable_group_widget.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/src/widgets/container.dart'; -import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:fluttericon/brandico_icons.dart'; import 'package:fluttericon/elusive_icons.dart'; import 'package:fluttericon/entypo_icons.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; -import 'package:fluttericon/font_awesome_icons.dart'; import 'package:fluttericon/modern_pictograms_icons.dart'; -import 'package:fluttericon/typicons_icons.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; +import 'package:unit2/bloc/profile/primary_information/identification/identification_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/screens/profile/components/basic_information/address_screen.dart'; +import 'package:unit2/screens/profile/components/basic_information/citizenship_screen.dart'; +import 'package:unit2/screens/profile/components/basic_information/contact_information_screen.dart'; +import 'package:unit2/screens/profile/components/basic_information/identification_information_screen.dart'; +import 'package:unit2/screens/profile/components/basic_information/primary_information_screen.dart'; +import 'package:unit2/screens/profile/components/education_screen.dart'; +import 'package:unit2/screens/profile/components/eligibility_screen.dart'; +import 'package:unit2/screens/profile/components/family_background_screen.dart'; +import 'package:unit2/screens/profile/components/learning_and_development_screen.dart'; +import 'package:unit2/screens/profile/components/loading_screen.dart'; +import 'package:unit2/screens/profile/components/other_information/non_academic_recognition_screen.dart'; +import 'package:unit2/screens/profile/components/other_information/org_membership_screen.dart'; +import 'package:unit2/screens/profile/components/other_information/skills_and_hobbies_screen.dart'; +import 'package:unit2/screens/profile/components/references_screen.dart'; +import 'package:unit2/screens/profile/components/work_history_screen.dart'; +import 'package:unit2/screens/profile/components/voluntary_works_screen.dart'; import 'package:unit2/theme-data.dart/colors.dart'; - +import '../../bloc/profile/eligibility/eligibility_bloc.dart'; +import '../../bloc/profile/family/family_bloc.dart'; +import '../../bloc/profile/education/education_bloc.dart'; +import '../../bloc/profile/learningDevelopment/learning_development_bloc.dart'; +import '../../bloc/profile/other_information/hobbies/hoobies_bloc.dart'; +import '../../bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart'; +import '../../bloc/profile/other_information/org_membership/organization_membership_bloc.dart'; +import '../../bloc/profile/references/references_bloc.dart'; +import '../../bloc/profile/voluntary_works/voluntary_work_bloc.dart'; +import '../../bloc/profile/workHistory/workHistory_bloc.dart'; +import '../../bloc/user/user_bloc.dart'; import 'components/main_menu.dart'; import 'components/submenu.dart'; -class ProfileInfo extends StatefulWidget { +class ProfileInfo extends StatelessWidget { const ProfileInfo({super.key}); - @override - State createState() => _ProfileInfoState(); -} - -class _ProfileInfoState extends State { @override Widget build(BuildContext context) { - return SafeArea( - child: Scaffold( - appBar: AppBar( - backgroundColor: primary, - centerTitle: true, - title: const Text('Profile'), - ), - body: BlocConsumer( - listener: (context, state) { - // TODO: implement listener - }, - builder: (context, state) { - if (state is UserLoggedIn) { - return Container( - padding: const EdgeInsets.symmetric( - vertical: 12, horizontal: 12), - child: ListView( - children: [ - const Text("View and Update your Profile Information"), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - Elusive.address_book, - color: primary, + int? profileId; + + String? token; + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + centerTitle: true, + title: const Text('Profile'), + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder(builder: (context, state) { + if (state is UserLoggedIn) { + profileId = state.userData!.user!.login!.user!.profileId; + token = state.userData!.user!.login!.token!; + return BlocConsumer( + listener: (context, state,){ + if (state is ProfileLoading) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ProfileLoaded || state is ProfileErrorState) { + final progress = ProgressHUD.of(context); + progress?.dismiss(); + } + }, + builder: (context, state) { + if (state is ProfileLoaded) { + return Container( + padding: const EdgeInsets.symmetric( + vertical: 12, horizontal: 12), + child: ListView( + children: [ + Text( + "View and Update your Profile Information", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ExpandableGroup( + collapsedIcon: + const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Elusive.address_book, + color: primary, + ), + title: Text( + "Basic Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), ), - title: Text( - "Basic Information", - style: TextStyle(fontWeight: FontWeight.bold), + items: [ + subMenu(Icons.person, "Primary", () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return PrimaryInfo( + primaryInformation: state + .profileInformation + .basicInfo + .primaryInformation!); + })); + }), + subMenu(Icons.home, "Home Addresses", () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => AddressBloc() + ..add(GetAddress( + addresses: state.profileInformation + .basicInfo.addresses)), + child: const AddressScreen(), + ); + })); + }), + subMenu(Icons.contact_mail, "Identifications", + () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => IdentificationBloc() + ..add(GetIdentifications( + identificationInformation: state + .profileInformation + .basicInfo + .identifications)), + child: const IdentificationsScreen(), + ); + })); + }), + subMenu(Icons.contact_phone, "Contact Info", + () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => ContactBloc() + ..add(GetContacts( + contactInformations: state + .profileInformation + .basicInfo + .contactInformation)), + child: const ContactInformationScreen(), + ); + })); + }), + subMenu(Icons.flag, "Citizenships", () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return CitizenShipScreen( + citizenships: state.profileInformation + .basicInfo.citizenships, + ); + })); + }), + ]), + const Divider(), + MainMenu( + icon: Elusive.group, + title: "Family", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => FamilyBloc() + ..add(GetFamilies( + profileId: profileId!, token: token!)), + child: const FamilyBackgroundScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.graduation_cap, + title: "Education", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => EducationBloc() + ..add(GetEducationalBackground( + profileId: profileId!, token: token!)), + child: const EducationScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: Icons.stars, + title: "Eligibility", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => EligibilityBloc() + ..add(GetEligibilities( + profileId: profileId!, token: token!)), + child: const EligibiltyScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.shopping_bag, + title: "Work History", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => WorkHistoryBloc() + ..add(GetWorkHistories( + profileId: profileId!, token: token!)), + child: const WorkHistoryScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.walking, + title: "Voluntary Work & Civic Services", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => VoluntaryWorkBloc() + ..add(GetVoluntarWorks( + profileId: profileId!, token: token!)), + child: const VolunataryWorkScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: Elusive.lightbulb, + title: "Learning & Development", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => LearningDevelopmentBloc() + ..add(GetLearningDevelopments( + profileId: profileId!, token: token!)), + child: const LearningAndDevelopmentScreen(), + ); + })); + }, + ), + const Divider(), + MainMenu( + icon: Brandico.codepen, + title: "Personal References", + onTap: () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => ReferencesBloc() + ..add(GetReferences( + profileId: profileId!, token: token!)), + child: const ReferencesScreen(), + ); + })); + }, + ), + ExpandableGroup( + collapsedIcon: + const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Icons.info, + color: primary, + ), + title: Text( + "Other Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), ), - ), - items: [ - subMenu(Icons.person, "Primary"), - subMenu(Icons.home, "Home Addresses"), - subMenu(Icons.contact_mail, "Identifications"), - subMenu(Icons.contact_phone, "Contact Info"), - subMenu(Icons.flag, "Citizenships"), - ]), - const Divider(), - const MainMenu( - icon: Elusive.group, - title: "Family", - ), - const Divider(), - const MainMenu( - icon: FontAwesome5.graduation_cap, - title: "Education", - ), - const Divider(), - const MainMenu( - icon: Icons.stars, - title: "Eligibility", - ), - const Divider(), - const MainMenu( - icon: FontAwesome5.shopping_bag, - title: "Work History", - ), - const Divider(), - const MainMenu( - icon: FontAwesome5.walking, - title: "Voluntary Work & Civic Services", - ), - const Divider(), - const MainMenu( - icon: Elusive.lightbulb, - title: "Learning & Development", - ), - const Divider(), - const MainMenu( - icon: Brandico.codepen, - title: "Personal References", - ), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - Icons.info, - color: primary, + items: [ + subMenu( + Icons.fitness_center, "Skills & Hobbies", + () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => HoobiesBloc() + ..add(GetSkillsHobbies( + profileId: profileId!, + token: token!)), + child: const SkillHobbiesScreen(), + ); + })); + }), + subMenu(FontAwesome5.certificate, + "Organization Memberships", () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + OrganizationMembershipBloc() + ..add(GetOrganizationMembership( + profileId: profileId!, + token: token!)), + child: const OrgMembershipsScreen(), + ); + })); + }), + subMenu(Entypo.doc_text, + "Non-Academic Recognitions", () { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + NonAcademicRecognitionBloc() + ..add(GetNonAcademicRecognition( + profileId: profileId!, + token: token!)), + child: + const NonAcademicRecognitionScreen(), + ); + })); + }), + ]), + ExpandableGroup( + collapsedIcon: + const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + FontAwesome5.laptop_house, + color: primary, + ), + title: Text( + "Assets", + style: TextStyle(fontWeight: FontWeight.bold), + ), ), - title: Text( - "Other Information", - style: TextStyle(fontWeight: FontWeight.bold), - ), - ), - items: [ - subMenu(Icons.fitness_center, "Skills & Hobbies"), - subMenu(FontAwesome5.certificate, - "Organization Memberships"), - subMenu( - Entypo.doc_text, "Non-Academic Recognitions"), - ]), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - FontAwesome5.laptop_house, - color: primary, - ), - title: Text( - "Assets", - style: TextStyle(fontWeight: FontWeight.bold), - ), - ), - items: [ - subMenu( - ModernPictograms.home, "Real Property Tax"), - ]), - ], - ), - ); - } - return const Center( - child: Text("default"), - ); - }, - ))); + items: [ + subMenu(ModernPictograms.home, + "Real Property Tax", () {}), + ]), + ], + ), + ); + } + if (state is ProfileLoading) { + + return const LoadingScreen(); + } + if (state is ProfileErrorState) { + return Text(state.mesage); + } + + return Container(); + }, + ); + } + return Container(); + }), + )); } } diff --git a/lib/screens/unit2/basic-info/basic-info.dart b/lib/screens/unit2/basic-info/basic-info.dart index 7374720..6459508 100644 --- a/lib/screens/unit2/basic-info/basic-info.dart +++ b/lib/screens/unit2/basic-info/basic-info.dart @@ -5,11 +5,11 @@ import 'package:flutter_svg/svg.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; import 'package:intl/intl.dart'; import 'package:qr_flutter/qr_flutter.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; import 'package:unit2/model/login_data/user_info/user_data.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/text_container.dart'; +import '../../../bloc/user/user_bloc.dart'; import '../../../theme-data.dart/colors.dart'; import '../../../widgets/splash_screen.dart'; import './components/cover-image.dart'; diff --git a/lib/screens/unit2/basic-info/components/cover-image.dart b/lib/screens/unit2/basic-info/components/cover-image.dart index 69c734c..f0f5031 100644 --- a/lib/screens/unit2/basic-info/components/cover-image.dart +++ b/lib/screens/unit2/basic-info/components/cover-image.dart @@ -10,7 +10,8 @@ class CoverImage extends StatelessWidget { color: Colors.grey, child: CachedNetworkImage( imageUrl: - 'https://static.vecteezy.com/system/resources/thumbnails/008/074/253/small/tropical-forest-sunset-nature-background-with-coconut-trees-vector.jpg', + "https://live.staticflickr.com/7320/9052838885_af9b21c79b_b.jpg", + // 'https://static.vecteezy.com/system/resources/thumbnails/008/074/253/small/tropical-forest-sunset-nature-background-with-coconut-trees-vector.jpg', width: double.infinity, height: 220, fit: BoxFit.cover, diff --git a/lib/screens/unit2/homepage.dart/components/dashboard.dart b/lib/screens/unit2/homepage.dart/components/dashboard.dart index b1c591a..eed381c 100644 --- a/lib/screens/unit2/homepage.dart/components/dashboard.dart +++ b/lib/screens/unit2/homepage.dart/components/dashboard.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart'; - -import 'package:unit2/test_data.dart'; import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; class DashBoard extends StatelessWidget { final List roles; @@ -25,52 +24,70 @@ class DashBoard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - roles[index].name, + roles[index].name.toUpperCase(), style: Theme.of(context) .textTheme .labelLarge! - .copyWith(fontSize: 16, fontWeight: FontWeight.w700), + .copyWith(fontSize: 12), ), - const Divider(), + const SizedBox( height: 8, ), GridView.count( shrinkWrap: true, crossAxisCount: 4, - crossAxisSpacing: 5, - mainAxisSpacing: 2, + crossAxisSpacing: 8, + mainAxisSpacing: 10, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric( vertical: 5, horizontal: 5), children: roles[index].roles.map((role) { - return GestureDetector( - onTap: () { - }, - child: Column(children: [ - Icon( - role.icon, - size: 24, - color: second, - ), - const SizedBox( - height: 5, - ), - Expanded( - child: Text( + return Container( + padding: const EdgeInsetsDirectional.fromSTEB(8,5,8,13), + alignment: Alignment.center, + + decoration:const BoxDecoration( + color: Colors.white, + boxShadow:[ BoxShadow(color: Colors.black12,spreadRadius: 2,blurRadius: 3)], + borderRadius: BorderRadius.all(Radius.circular(8)) + ), + child: GestureDetector( + onTap: () { + }, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Icon( + + role.icon, + size: 20, + weight: 100, + grade: 100, + color:second, + ), + ), + const SizedBox( + height: 5, + ), + Text( + role.role.name!.toLowerCase() == "establishment point-person"?"Est. point-person": role.role.name!, textAlign: TextAlign.center, style: Theme.of(context) .textTheme - .button! + .labelLarge! .copyWith( - fontSize: 11, + fontSize: blockSizeVertical*1.1, fontWeight: FontWeight.bold), ), - ), - ]), + ]), + ), ); }).toList()), + const SizedBox(height: 8,) ], ), ); diff --git a/lib/screens/unit2/homepage.dart/components/drawer-screen.dart b/lib/screens/unit2/homepage.dart/components/drawer-screen.dart index c355f90..c1ba365 100644 --- a/lib/screens/unit2/homepage.dart/components/drawer-screen.dart +++ b/lib/screens/unit2/homepage.dart/components/drawer-screen.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_zoom_drawer/config.dart'; import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; import 'package:unit2/theme-data.dart/colors.dart'; +import '../../../../bloc/user/user_bloc.dart'; import '../../../../widgets/splash_screen.dart'; import 'menu-screen.dart'; import '../module-screen.dart'; diff --git a/lib/screens/unit2/homepage.dart/components/menu-screen.dart b/lib/screens/unit2/homepage.dart/components/menu-screen.dart index 7a059ba..312d2d0 100644 --- a/lib/screens/unit2/homepage.dart/components/menu-screen.dart +++ b/lib/screens/unit2/homepage.dart/components/menu-screen.dart @@ -21,53 +21,51 @@ class _MenuScreenState extends State { widget.userData!.user!.login!.user!.firstName!.toUpperCase(); final String lastname = widget.userData!.user!.login!.user!.lastName!.toUpperCase(); - return SafeArea( - child: Drawer( - child: SingleChildScrollView( - child: SizedBox( - height: blockSizeVertical * 96, - child: Column( - // ignore: prefer_const_literals_to_create_immutables - children: [ - UserAccountsDrawerHeader( - decoration: const BoxDecoration( - color: primary, - image: DecorationImage( - image: AssetImage('assets/pngs/bg.png'), - fit: BoxFit.cover)), - accountName: Text("$firstName $lastname"), - accountEmail: null, - currentAccountPicture: CircleAvatar( - radius: 40, - backgroundColor: fifth, - child: CircleAvatar( - radius: 33, - backgroundColor: third, - child: //Icon(Icons.person, size: 40, color: fifth), - Text( - firstName[0].toUpperCase(), - style: const TextStyle(fontSize: 45.0, color: fifth), - ), + return Drawer( + child: SingleChildScrollView( + child: SizedBox( + height: blockSizeVertical * 96, + child: Column( + // ignore: prefer_const_literals_to_create_immutables + children: [ + UserAccountsDrawerHeader( + decoration: const BoxDecoration( + color: primary, + image: DecorationImage( + image: AssetImage('assets/pngs/bg.png'), + fit: BoxFit.cover)), + accountName: Text("$firstName $lastname"), + accountEmail: null, + currentAccountPicture: CircleAvatar( + radius: 40, + backgroundColor: fifth, + child: CircleAvatar( + radius: 33, + backgroundColor: third, + child: //Icon(Icons.person, size: 40, color: fifth), + Text( + firstName[0].toUpperCase(), + style: const TextStyle(fontSize: 45.0, color: fifth), ), ), ), - getTile(FontAwesome5.user, "Basic Info", '/basic-info', context, + ), + getTile(FontAwesome5.user, "Basic Info", '/basic-info', context, + widget.userData!), + const Divider(), + getTile(FontAwesome5.user_circle, "Profile", + '/profile', context, widget.userData!), + const Divider(), + getTile(FontAwesome5.life_ring, "Request SOS", '/request-sos', + context, widget.userData!), + const Divider(), + Expanded( + child: Align( + alignment: FractionalOffset.bottomLeft, + child: getTile(WebSymbols.logout, "Logout", '/', context, widget.userData!), - const Divider(), - getTile(FontAwesome5.user_circle, "Profile", - '/profile', context, widget.userData!), - const Divider(), - getTile(FontAwesome5.life_ring, "Request SOS", '/request-sos', - context, widget.userData!), - const Divider(), - Expanded( - child: Align( - alignment: FractionalOffset.bottomLeft, - child: getTile(WebSymbols.logout, "Logout", 'login', context, - widget.userData!), - )), - ], - ), + )), + ], ), ), ), diff --git a/lib/screens/unit2/homepage.dart/components/menu.dart b/lib/screens/unit2/homepage.dart/components/menu.dart index 5bf5982..5ddc5cf 100644 --- a/lib/screens/unit2/homepage.dart/components/menu.dart +++ b/lib/screens/unit2/homepage.dart/components/menu.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:unit2/model/login_data/employee_info/employee_info.dart'; import 'package:unit2/model/login_data/user_info/user_data.dart'; import 'package:unit2/utils/alerts.dart'; import '../../../../theme-data.dart/colors.dart'; +import '../../../../utils/global.dart'; Widget getTile( IconData icondata, String title, String route, BuildContext context,UserData userData) { @@ -17,12 +19,25 @@ Widget getTile( ), onTap: () async { if (title.toLowerCase() == "logout") { - confirmAlert(context, () { + confirmAlert(context, () async{ + await CREDENTIALS!.clear(); + await CREDENTIALS!.deleteAll(['username','password','saved']); Navigator.pushReplacementNamed (context,"/"); - }); - } else { - Navigator.pushNamed(context, route); + + },"Logout","Are You sure you want to logout?"); + }if(title.toLowerCase() == 'profile'){ + ProfileArguments profileArguments = ProfileArguments(token: userData.user!.login!.token!, userID:userData.user!.login!.user!.profileId!); + Navigator.pushNamed(context, route,arguments: profileArguments); + }if(title.toLowerCase() == 'basic info'){ + Navigator.pushNamed(context, '/basic-info'); } + }, ); } + +class ProfileArguments{ + final int userID; + final String token; + const ProfileArguments({required this.token, required this.userID}); +} diff --git a/lib/screens/unit2/homepage.dart/module-screen.dart b/lib/screens/unit2/homepage.dart/module-screen.dart index 5626247..ba232cc 100644 --- a/lib/screens/unit2/homepage.dart/module-screen.dart +++ b/lib/screens/unit2/homepage.dart/module-screen.dart @@ -7,8 +7,7 @@ import 'package:fluttericon/typicons_icons.dart'; import 'package:unit2/screens/unit2/homepage.dart/components/dashboard.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/text_container.dart'; - -import '../../../bloc/bloc/user_bloc.dart'; +import '../../../bloc/user/user_bloc.dart'; import '../../../model/login_data/user_info/role.dart'; import 'components/empty_module.dart'; @@ -21,8 +20,8 @@ class MainScreen extends StatefulWidget { class _MainScreenState extends State { List roles = [ - Module(name: 'UniT2 roles', roles: []), - Module(name: 'DocSms roles', roles: []) + Module(name: 'UniT2 module operations', roles: []), + Module(name: 'DocSms module operations', roles: []) ]; @override Widget build(BuildContext context) { @@ -32,10 +31,9 @@ class _MainScreenState extends State { }, child: BlocBuilder(builder: (context, state) { if (state is UserLoggedIn) { - print(state.userData!.user!.login!.token); - state.userData!.user!.login!.user!.roles!.forEach((role) { + for (var role in state.userData!.user!.login!.user!.roles!) { Role? getRole = role; - role!.modules!.forEach((module) { + for (var module in role!.modules!) { if (module!.name!.toLowerCase() == 'unit2') { IconData iconData = iconGenerator(getRole!.name!); Roles newRole = Roles(role: getRole, icon: iconData); @@ -46,36 +44,35 @@ class _MainScreenState extends State { Roles newRole = Roles(role: getRole, icon: iconData); roles[1].roles.add(newRole); } - }); - }); - return SafeArea( - child: Scaffold( + } + } + return Scaffold( appBar: AppBar( - backgroundColor: primary, - leading: IconButton( - onPressed: () { - ZoomDrawer.of(context)!.toggle(); - }, - icon: const Icon( - Icons.menu, - color: Colors.white, - ), - ), - centerTitle: true, - title: const Text( - unit2ModuleScreen, - style: TextStyle( - fontSize: 18.0, - color: Colors.white, - ), - ), + backgroundColor: primary, + leading: IconButton( + onPressed: () { + ZoomDrawer.of(context)!.toggle(); + }, + icon: const Icon( + Icons.menu, + color: Colors.white, + ), + ), + centerTitle: true, + title: const Text( + unit2ModuleScreen, + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + ), + ), ), body: state.userData!.user!.login!.user!.roles!.isNotEmpty - ? DashBoard( - roles: roles, - ) - : const NoModule(), - )); + ? DashBoard( + roles: roles, + ) + : const NoModule(), + ); } return Container(); }), diff --git a/lib/screens/unit2/login/components/update_required.dart b/lib/screens/unit2/login/components/update_required.dart index 593169e..a5ae6b0 100644 --- a/lib/screens/unit2/login/components/update_required.dart +++ b/lib/screens/unit2/login/components/update_required.dart @@ -9,10 +9,10 @@ import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_svg/svg.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; import 'package:unit2/screens/unit2/login/components/showAlert.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; +import '../../../../bloc/user/user_bloc.dart'; import '../../../../theme-data.dart/colors.dart'; import '../../../../utils/cpu_architecture.dart'; import '../../../../utils/text_container.dart'; diff --git a/lib/screens/unit2/login/login.dart b/lib/screens/unit2/login/login.dart index bd2d590..7e2c7d9 100644 --- a/lib/screens/unit2/login/login.dart +++ b/lib/screens/unit2/login/login.dart @@ -1,15 +1,20 @@ import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; import 'package:unit2/screens/unit2/login/components/update_required.dart'; +import 'package:unit2/utils/alerts.dart'; +import 'package:unit2/utils/internet_time_out.dart'; import 'package:unit2/utils/text_container.dart'; import 'package:unit2/widgets/error_state.dart'; +import '../../../bloc/user/user_bloc.dart'; +import '../../../utils/global_context.dart'; import '../../../widgets/splash_screen.dart'; import '../../../widgets/wave.dart'; import '../../../utils/global.dart'; @@ -30,20 +35,53 @@ class _UniT2LoginState extends State { final _formKey = GlobalKey(); bool showSuffixIcon = false; bool _showPassword = true; + String? password; + String? username; @override Widget build(BuildContext context) { return WillPopScope( onWillPop: pressAgainToExit, child: Scaffold( body: ProgressHUD( + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), child: BlocConsumer(listener: (context, state) { - if (state is UserLoggedIn) { + if (state is UserLoggedIn || state is UuidLoaded) { final progress = ProgressHUD.of(context); progress!.dismiss(); - Navigator.pushReplacementNamed(context, '/module-screen'); } - if (state is UuidLoaded) { - Navigator.pushNamed(context, '/qr-login'); + if (state is UserLoggedIn) { + if (state.success == true) { + if (!state.savedCredentials!) { + confirmAlertWithCancel(context, () async { + await CREDENTIALS?.put('saved', "saved"); + await CREDENTIALS?.put('username', + state.userData!.user!.login!.user!.username!); + await CREDENTIALS?.put('password', password); + Fluttertoast.showToast( + msg: "Credentials Successfully saved", + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + Navigator.pushReplacementNamed(context, '/module-screen'); + }, + () => Navigator.pushReplacementNamed( + context, '/module-screen'), + "Save credentials?", + "Do you want to save credentials so you don't have to login again next time?."); + }else{ + Navigator.pushReplacementNamed( + context, '/module-screen'); + } + } else { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + errorAlert(context, "Error Login", state.message, () { + context.read().add(LoadVersion()); + Navigator.of(context).pop(); + }); + } } }, builder: (context, state) { if (state is VersionLoaded) { @@ -199,6 +237,7 @@ class _UniT2LoginState extends State { TextStyle(color: Colors.white), ), onPressed: () { + final progress = ProgressHUD.of(context); @@ -206,18 +245,22 @@ class _UniT2LoginState extends State { if (_formKey.currentState! .saveAndValidate()) { + password = _formKey + .currentState! + .value['password']; + username = _formKey + .currentState! + .value['username']; progress?.showWithText( 'Logging in...', ); BlocProvider.of(context) .add(UserLogin( - username: _formKey - .currentState! - .value['username'], - password: _formKey - .currentState! - .value['password'])); + + username:username, + password: password + )); } }, ), @@ -273,7 +316,9 @@ class _UniT2LoginState extends State { third, Colors.transparent, Colors.white38), - onPressed: () {}, + onPressed: () { + + }, label: const Text( requestSOS, style: @@ -290,6 +335,7 @@ class _UniT2LoginState extends State { ), ); } else { + //New update available return Update( apkVersion: state.apkVersion!, currenVersion: state.versionInfo!.version!, @@ -298,10 +344,21 @@ class _UniT2LoginState extends State { }); } if (state is UserError) { - return ErrorState( - message: state.message, + return SomethingWentWrong( + message: onError, + onpressed: () { + BlocProvider.of( + NavigationService.navigatorKey.currentContext!) + .add(GetApkVersion()); + return MaterialPageRoute(builder: (_) { + return const UniT2Login(); + }); + }, ); } + if (state is InternetTimeout) { + return const TimeOutError(); + } if (state is SplashScreen) { return const UniTSplashScreen(); } diff --git a/lib/screens/unit2/login/qr_login.dart b/lib/screens/unit2/login/qr_login.dart index 9d2f70b..6be5696 100644 --- a/lib/screens/unit2/login/qr_login.dart +++ b/lib/screens/unit2/login/qr_login.dart @@ -1,17 +1,13 @@ -import 'package:flutter/cupertino.dart'; + import 'package:flutter/material.dart'; -import 'package:flutter/src/widgets/container.dart'; -import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_svg/svg.dart'; import 'package:fluttericon/font_awesome5_icons.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; -import 'package:unit2/widgets/error_state.dart'; import 'package:unit2/widgets/wave.dart'; - -import '../../../bloc/bloc/user_bloc.dart'; +import '../../../bloc/user/user_bloc.dart'; import '../../../theme-data.dart/colors.dart'; import '../../../theme-data.dart/form-style.dart'; import '../../../utils/global.dart'; @@ -187,8 +183,6 @@ class _QRLoginState extends State { ], ), ); - }if(state is UserError){ - return ErrorState(message: state.message,); } return Container(); }, diff --git a/lib/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart b/lib/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart index 907993f..0255d85 100644 --- a/lib/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart +++ b/lib/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart @@ -24,6 +24,7 @@ final int initialLabelIndex; padding: const EdgeInsets.all(15), height: 80, child: ToggleSwitch( + animate: true, minWidth: 150.0, cornerRadius: 25.0, activeBgColors: [ @@ -37,7 +38,7 @@ final int initialLabelIndex; totalSwitches: 2, labels: labels, icons: icons, - radiusStyle: false, + radiusStyle: true, onToggle: onToggle), ); } diff --git a/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart b/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart index 72b3f18..57081ed 100644 --- a/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart +++ b/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart @@ -94,7 +94,7 @@ class _QRCodeScannerSettingsState extends State { ), FittedBox( child: CostumToggleSwitch( - activeBGColors: [Colors.green[800]!, Colors.red[800]!], + activeBGColors: [ Colors.red[800]!,Colors.green[800]!], initialLabelIndex: scanMode == 'INCOMING' ? 0 : 1, icons: const [ Entypo.down_bold, diff --git a/lib/sevices/login_service/auth_service.dart b/lib/sevices/login_service/auth_service.dart index 82b47a5..497e8f4 100644 --- a/lib/sevices/login_service/auth_service.dart +++ b/lib/sevices/login_service/auth_service.dart @@ -1,8 +1,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; - -import 'package:flutter/material.dart'; import 'package:unit2/model/login_data/user_info/user_data.dart'; import 'package:unit2/model/login_data/version_info.dart'; import 'package:http/http.dart' as http; @@ -22,41 +20,40 @@ class AuthService { 'X-User': "" }; try { - http.Response response = await http.get( - Uri.https('unitylb1.agusandelnorte.gov.ph', - '/unit2/api/sys/apk_version/latest/'), - headers: headers); + String path = Url.instance.latestApk(); + http.Response response = await Request.instance.getRequest(path: path,headers: headers,param: {}); + if (response.statusCode == 200) { Map data = jsonDecode(response.body); versionInfo = VersionInfo.fromJson(data['data']); } - } on TimeoutException catch (_) { - throw (timeoutError); - } on SocketException catch (_) { - throw (timeoutError); - } catch (e) { + }catch (e) { throw (e.toString()); } return versionInfo; } - Future webLogin({String? username, String? password})async{ + Future> webLogin({String? username, String? password})async{ Map body ={'username':username!,'password':password!}; Map baseHeaders = { 'Content-Type': 'application/json' }; + Map responseStatus = {}; String path = Url.instance.authentication(); UserData? userData; try{ http.Response response = await Request.instance.postRequest(path: path,param: {},headers: baseHeaders,body: body); - if(response.statusCode == 200){ + Map data = jsonDecode(response.body); - userData = UserData.fromJson(data['data']); - } + + responseStatus = data; + + + return responseStatus; }catch(e){ throw (e.toString()); } - return userData!; + } Future qrLogin({String? uuid, String? password})async{ Map body ={'uuid':uuid!,'password':password!}; diff --git a/lib/sevices/profile/contact_services.dart b/lib/sevices/profile/contact_services.dart new file mode 100644 index 0000000..f3fd302 --- /dev/null +++ b/lib/sevices/profile/contact_services.dart @@ -0,0 +1,142 @@ +import 'dart:convert'; + +import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; +import 'package:http/http.dart' as http; + +class ContactService { + static final ContactService _instance = ContactService(); + static ContactService get instance => _instance; + + Future> getServiceProvider( + {required int serviceTypeId}) async { + String path = Url.instance.getCommunicationProvider(); + Map params = {"service_type__id": serviceTypeId.toString()}; + List serviceProviders = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(param: params, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var element in data['data']) { + CommService commService = CommService.fromJson(element); + serviceProviders.add(commService); + } + } + } + } catch (e) { + throw e.toString(); + } + return serviceProviders; + } + +//// update + Future> update( + {required int profileId, + required String token, + required ContactInfo contactInfo}) async { + String path = "${Url.instance.contactPath()}$profileId/"; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map body = { + "personid": profileId, + "contactinfoid": contactInfo.id, + "_numbermail": contactInfo.numbermail, + "_active": contactInfo.active, + "_primary": contactInfo.primary, + "_commServiceId": contactInfo.commService!.id + }; + Map responseStatus = {}; + try { + http.Response response = await Request.instance + .putRequest(path: path, headers: headers, body: body, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + responseStatus = data; + } else { + responseStatus.addAll({'success': false}); + } + return responseStatus; + } catch (e) { + throw e.toString(); + } + } + + //// add + Future> add( + {required int profileId, + required String token, + required ContactInfo contactInfo}) async { + String path = "${Url.instance.contactPath()}$profileId/"; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map responseStatus = {}; + Map body = { + "personid": profileId, + "_numbermail": contactInfo.numbermail, + "_active": contactInfo.active, + "_primary": contactInfo.primary, + "_commServiceId": contactInfo.commService!.id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, headers: headers, body: body, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + responseStatus = data; + } else { + responseStatus.addAll({'success': false}); + } + return responseStatus; + } catch (e) { + throw e.toString(); + } + } + +////delete + Future deleteContact( + {required int profileId, + required String token, + required ContactInfo contactInfo}) async { + String path = "${Url.instance.deleteContact()}$profileId/"; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'mode': 'same-origin', + 'include': 'credentials', + 'Authorization': authToken + }; + bool success = false; + Map params = {"force_mode": "true"}; + Map body = { + "personid": profileId, + "contactinfoid": contactInfo.id, + "_numbermail": contactInfo.numbermail, + "_active": contactInfo.active, + "_primary": contactInfo.primary, + "_commServiceId": contactInfo.commService!.id + }; + 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']; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/profile/education_services.dart b/lib/sevices/profile/education_services.dart new file mode 100644 index 0000000..1d6d93e --- /dev/null +++ b/lib/sevices/profile/education_services.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; + +import 'package:unit2/model/profile/educational_background.dart'; +import 'package:unit2/utils/request.dart'; + +import '../../utils/urls.dart'; +import 'package:http/http.dart' as http; + +class EducationService { + static final EducationService _instance = EducationService(); + static EducationService get instace => _instance; + + Future> getEducationalBackground( + int profileId, String token) async { + List educationalBackgrounds = []; + String authToken = "Token $token"; + String path = "${Url.instance.getEducationalBackgrounds()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var education) { + EducationalBackground educationalBackground = + EducationalBackground.fromJson(education); + educationalBackgrounds.add(educationalBackground); + }); + } + } + } catch (e) { + throw e.toString(); + } + + return educationalBackgrounds; + } +} diff --git a/lib/sevices/profile/eligibility_services.dart b/lib/sevices/profile/eligibility_services.dart new file mode 100644 index 0000000..adfdb8d --- /dev/null +++ b/lib/sevices/profile/eligibility_services.dart @@ -0,0 +1,143 @@ +import 'dart:convert'; + +import 'package:unit2/model/profile/eligibility.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; +import 'package:http/http.dart' as http; + +class EligibilityService { + static final EligibilityService _instance = EligibilityService(); + static EligibilityService get instance => _instance; + + + Future> getEligibilities(int profileId, String token)async{ + List eligibilities = []; + String authToken = "Token $token"; + String path = "${Url.instance.getEligibilities()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + + }; + + try{ + http.Response response = await Request.instance.getRequest(path: path,headers: headers,param: {}); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if (data['data']!= null) { + data['data'].forEach((var cert) { + EligibityCert eligibility = EligibityCert.fromJson(cert); + eligibilities.add(eligibility); + }); + } + } + }catch(e){ + throw e.toString(); + } + return eligibilities; + } + + Future delete( + {required int eligibilityId, + required int profileId, + required String token}) async { + bool? success; + String authtoken = "Token $token"; + String path = "${Url.instance.deleteEligibility()}$profileId/"; + Map body = {"eligibility_id": eligibilityId}; + Map params = {"force_mode": "true"}; + Map 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!; + } + + Future> add( + {required EligibityCert eligibityCert, + required String token, + required int profileId}) async { + Map? _response={}; + String authtoken = "Token $token"; + String path = '${Url.instance.addEligibility()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + + Map body = { + 'eligibility_id': eligibityCert.eligibility!.id, + 'license_number': eligibityCert.licenseNumber, + 'exam_date': eligibityCert.examDate?.toString(), + 'validity_date': eligibityCert.validityDate?.toString(), + 'rating': eligibityCert.rating, + '_citymunCode': eligibityCert.examAddress?.cityMunicipality?.code, + '_countryId': eligibityCert.examAddress?.country!.id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + _response = data; + } else { + _response.addAll({'success':false}); + } + + return _response; + } catch (e) { + throw e.toString(); + } + } + + Future> update( + {required EligibityCert eligibityCert, + required String token, + required int profileId, required int oldEligibility}) async { + Map? response={}; + String authtoken = "Token $token"; + String path = '${Url.instance.addEligibility()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + + Map body = { + 'eligibility_id': eligibityCert.eligibility!.id, + 'license_number': eligibityCert.licenseNumber, + 'exam_date': eligibityCert.examDate?.toString(), + 'validity_date': eligibityCert.validityDate?.toString(), + 'rating': eligibityCert.rating, + '_citymunCode': eligibityCert.examAddress?.cityMunicipality?.code, + '_countryId': eligibityCert.examAddress?.country!.id, + '_oldEligibilityId': oldEligibility + }; + try { + http.Response res = await Request.instance + .putRequest(path: path, body: body, headers: headers, param: {}); + if (res.statusCode == 200) { + Map data = jsonDecode(res.body); + response = data; + } else { + response.addAll({'success':false}); + } + + return response; + } catch (e) { + throw e.toString(); + } + } +} diff --git a/lib/sevices/profile/family_services.dart b/lib/sevices/profile/family_services.dart new file mode 100644 index 0000000..f48bc91 --- /dev/null +++ b/lib/sevices/profile/family_services.dart @@ -0,0 +1,38 @@ + + + +import 'dart:convert'; + +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/family_backround.dart'; +import '../../utils/urls.dart'; +import 'package:http/http.dart' as http; +class FamilyService{ + static final FamilyService _instance = FamilyService(); + static FamilyService get instance => _instance; + Future< List> getFamilies(int profileId, String token)async{ + List families = []; + String authToken = "Token $token"; + String path = "${Url.instance.getFamilies()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; +try{ + http.Response response = await Request.instance.getRequest(path:path, param: {},headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + data['data'].forEach((var family){ + FamilyBackground familyBackground = FamilyBackground.fromJson(family); + families.add(familyBackground); + }); + } + } +}catch(e){ + throw e.toString(); +} +return families; + } +} \ No newline at end of file diff --git a/lib/sevices/profile/learningDevelopment_service.dart b/lib/sevices/profile/learningDevelopment_service.dart new file mode 100644 index 0000000..9cf8154 --- /dev/null +++ b/lib/sevices/profile/learningDevelopment_service.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; + +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/learning_development.dart'; +import '../../utils/urls.dart'; +import 'package:http/http.dart' as http; + +class LearningDevelopmentServices { + static final LearningDevelopmentServices _instance = + LearningDevelopmentServices(); + static LearningDevelopmentServices get instance => _instance; + + Future> getLearningDevelopments( + int profileId, String token) async { + List learningsAndDevelopments = []; + String authToken = "Token $token"; + String path = "${Url.instance.getLearningAndDevelopments()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + // try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var learnings) { + LearningDevelopement learningDevelopement = + LearningDevelopement.fromJson(learnings); + learningsAndDevelopments.add(learningDevelopement); + }); + } + } + // } catch (e) { + // throw e.toString(); + // } + return learningsAndDevelopments; + } +} diff --git a/lib/sevices/profile/non_academic_services.dart b/lib/sevices/profile/non_academic_services.dart new file mode 100644 index 0000000..fb08bf8 --- /dev/null +++ b/lib/sevices/profile/non_academic_services.dart @@ -0,0 +1,143 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:unit2/bloc/profile/other_information/non_academic_recognition.dart/non_academic_recognition_bloc.dart'; +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/other_information/non_acedimic_recognition.dart'; +import '../../utils/urls.dart'; + +class NonAcademicRecognitionServices { + static final NonAcademicRecognitionServices _instance = + NonAcademicRecognitionServices(); + static NonAcademicRecognitionServices get instance => _instance; +////GET + Future> getNonAcademicRecognition( + int profileId, String token) async { + List nonAcademicRecognitions = []; + String authToken = "Token $token"; + String path = "${Url.instance.getNonAcademicRecognition()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var recognition) { + NonAcademicRecognition nonAcademicRecognition = + NonAcademicRecognition.fromJson(recognition); + nonAcademicRecognitions.add(nonAcademicRecognition); + }); + } + } + } catch (e) { + throw e.toString(); + } + return nonAcademicRecognitions; + } + +////ADD + Future> add( + {required String token, + required int profileId, + required NonAcademicRecognition nonAcademicRecognition}) async { + String authToken = "Token $token"; + String path = "${Url.instance.getNonAcademicRecognition()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map body = { + "title": nonAcademicRecognition.title, + "presenter_id": nonAcademicRecognition.presenter?.id, + "_presenterName": nonAcademicRecognition.presenter!.name, + "_presenterCatId": nonAcademicRecognition.presenter!.category!.id, + "_privateEntity": nonAcademicRecognition.presenter!.privateEntity, + }; + + Map statusResponse = {}; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, param: {}, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({"success": false}); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + ////UPDATE + Future> update( + {required NonAcademicRecognition nonAcademicRecognition, + required int profileId, + required String token}) async { + String authToken = "Token $token"; + String path = "${Url.instance.getNonAcademicRecognition()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map statusResponse = {}; + Map body = { + "id": nonAcademicRecognition.id, + "title": nonAcademicRecognition.title, + "presenter_id": nonAcademicRecognition.presenter?.id, + "_presenterName": nonAcademicRecognition.presenter!.name, + "_presenterCatId": nonAcademicRecognition.presenter!.category!.id, + "_privateEntity": nonAcademicRecognition.presenter!.privateEntity + }; + try { + http.Response response = await Request.instance + .putRequest(path: path, headers: headers, body: body, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({'success': false}); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + +////DELETE + Future delete( + {required String title, + required int id, + required String token, + required int profileId}) async { + String authToken = "Token $token"; + Map params = {"force_mode": "true"}; + String path = "${Url.instance.getNonAcademicRecognition()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + bool success = false; + Map body = { + "id": id, + "title": title, + }; + 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']; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/profile/orgmembership_services.dart b/lib/sevices/profile/orgmembership_services.dart new file mode 100644 index 0000000..424646e --- /dev/null +++ b/lib/sevices/profile/orgmembership_services.dart @@ -0,0 +1,95 @@ +import 'dart:convert'; + +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/other_information/organization_memberships.dart'; +import 'package:http/http.dart' as http; + +import '../../model/utils/agency.dart'; +import '../../utils/urls.dart'; + +class OrganizationMembershipServices { + static final OrganizationMembershipServices _instance = + OrganizationMembershipServices(); + static OrganizationMembershipServices get instance => _instance; + + Future> getOrgMemberships( + int profileId, String token) async { + List orgMemberships = []; + String authToken = "Token $token"; + String path = "${Url.instance.getOrgMemberShips()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var org) { + OrganizationMembership organizationMembership = + OrganizationMembership.fromJson(org); + orgMemberships.add(organizationMembership); + }); + } + } + } catch (e) { + throw e.toString(); + } + return orgMemberships; + } + Future>add({required Agency? agency,required String token, required String profileId})async{ + String authToken = "Token $token"; + String path = "${Url.instance.getOrgMemberShips()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map statusResponse = {}; + Map body = { + "agency_id": agency?.id, + "_agencyName": agency!.name, + "_agencyCatId": agency.category!.id, + "_privateEntity": agency.privateEntity + }; + try{ + http.Response response = await Request.instance.postRequest(path: path,body: body,headers: headers,param: {}); + if(response.statusCode == 201){ + Map data = jsonDecode(response.body); + statusResponse = data; + }else{ + statusResponse.addAll({"success":false}); + } + }catch(e){ + throw e.toString(); + } + return statusResponse; + + } + + Future delete({required Agency agency, required int profileId, required String token})async{ + bool success = false; + Map params = {"force_mode": "true"}; + String authToken = "Token $token"; + String path = "${Url.instance.getOrgMemberShips()}$profileId/"; + Map body ={ + "agency_id": agency.id + }; + Map 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"]; + } + }catch(e){ + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/profile/profile_service.dart b/lib/sevices/profile/profile_service.dart new file mode 100644 index 0000000..d085a98 --- /dev/null +++ b/lib/sevices/profile/profile_service.dart @@ -0,0 +1,210 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:unit2/model/login_data/employee_info/employee_info.dart'; +import 'package:unit2/model/profile/basic_info.dart'; +import 'package:unit2/model/profile/basic_information/adress.dart'; +import 'package:unit2/model/profile/basic_information/citizenship.dart'; +import 'package:unit2/model/profile/basic_information/contact_information.dart'; +import 'package:unit2/model/profile/basic_information/identification_information.dart'; +import 'package:unit2/model/profile/educational_background.dart'; +import 'package:unit2/model/profile/eligibility.dart'; +import 'package:unit2/model/profile/family_backround.dart'; +import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/model/profile/other_information/non_acedimic_recognition.dart'; +import 'package:unit2/model/profile/profileInfomation.dart'; +import 'package:unit2/model/profile/references.dart'; +import 'package:unit2/model/profile/other_information/skills_and_hobbies.dart'; +import 'package:unit2/model/profile/voluntary_works.dart'; +import 'package:unit2/model/profile/work_history.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; + +import '../../model/profile/basic_information/primary-information.dart'; +import '../../model/profile/other_information/organization_memberships.dart'; + +class ProfileService { + static final ProfileService _instance = ProfileService(); + static ProfileService get instance => _instance; + + Future getProfile(String token, int id) async { + String url = Url.instance.profileInformation(); + String path = url + id.toString(); + ProfileInformation? profileInformation0; + PrimaryInformation? primaryInformation; + List addresses = []; + List identificationInformation = []; + List contactInformation = []; + List citizenships = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': "Token $token" + }; + Map param={"basic":"true"}; + // try{ + http.Response response = await Request.instance + .getRequest(path: path, param: param, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + + // get primary information + if (data['data']['basic_information']['primary_information'] != null) { + primaryInformation = PrimaryInformation.fromJson( + data['data']['basic_information']['primary_information']); + } else { + primaryInformation = null; + } + + // get all contacts + if (data['data']['basic_information']['contact_information'] != null) { + data['data']['basic_information']['contact_information'] + .forEach((var contact) { + ContactInfo contactInfo = + ContactInfo.fromJson(contact['contact_info']); + contactInformation.add(contactInfo); + }); + } + + // get all addresses + if (data['data']['basic_information']['addresses'] != null) { + data['data']['basic_information']['addresses'].forEach((var address) { + MainAdress mainAdress = MainAdress.fromJson(address); + addresses.add(mainAdress); + }); + } + + // get all identifications + if (data['data']['basic_information']['identification_records'] != null) { + data['data']['basic_information']['identification_records']! + .forEach((var identity) { + Identification identification = Identification.fromJson(identity); + identificationInformation.add(identification); + }); + } + + // get all family background + // if(data['data']['family_background'] != null){ + // data['data']['family_background'].forEach((var family){ + // FamilyBackground familyBackground = FamilyBackground.fromJson(family); + // families.add(familyBackground); + // }); + // } + + //get all eligibilities + // if (data['data']['eligibilities'] != null) { + // data['data']['eligibilities']!.forEach((var cert) { + // EligibityCert eligibility = EligibityCert.fromJson(cert); + // eligibilities.add(eligibility); + // }); + // } + + // get all citizenships + // if (data['data']['citizenship'] != null) { + // data['data']['citizenships']!.forEach((var citizenship) { + // Citizenship person = Citizenship.fromJson(citizenship); + // citizenships.add(person); + // }); + // } + // get all references; + // if (data['data']['personal_references'] != null) { + // data['data']['personal_references'].forEach((var person) { + // PersonalReference reference = PersonalReference.fromJson(person); + // references.add(reference); + // }); + // } + + //get all learning and developments + // if (data['data']['learning_development'] != null) { + // data['data']['learning_development'].forEach((var training) { + // LearningDevelopement learnings = + // LearningDevelopement.fromJson(training); + // learningsDevelopments.add(learnings); + // }); + // } + + //get all educational background + // if (data['data']['education_background'] != null) { + // data['data']['education_background'].forEach((var education) { + // EducationalBackground educationalBackground = + // EducationalBackground.fromJson(education); + // educationalBackgrounds.add(educationalBackground); + // }); + // } + + // get all work history + // if (data['data']['work_experiences'] != null) { + // data['data']['work_experiences'].forEach((var work) { + // WorkHistory experience = WorkHistory.fromJson(work); + // workExperiences.add(experience); + // }); + // } + + // get all voluntary works + // if (data['data']['voluntary_works'] != null) { + // data['data']['voluntary_works'].forEach((var work) { + // VoluntaryWork vwork = VoluntaryWork.fromJson(work); + // voluntaryWorks.add(vwork); + // }); + // } + + // get all hobbies + // if (data['data']['other_information']['skills_hobbies'] != null) { + // data['data']['other_information']['skills_hobbies'] + // .forEach((var skills_hobbies) { + // SkillsHobbies skillsAndHobbies = + // SkillsHobbies.fromJson(skills_hobbies); + // skillsHobbies.add(skillsAndHobbies); + // }); + // } + + //get all organization memberships + // if (data['data']['other_information']['organization_memberships'] != + // null) { + // data['data']['other_information']['organization_memberships'] + // .forEach((var org) { + // OrganizationMembership organization = + // OrganizationMembership.fromJson(org); + // orgMemberships.add(organization); + // }); + // } + +//get all non academic recognition + // if (data['data']['other_information']['non_academic_records'] != null) { + // data['data']['other_information']['non_academic_records'] + // .forEach((var recognition) { + // NonAcademicRecognition nonAcademicRecognition = + // NonAcademicRecognition.fromJson(recognition); + // nonAcademicRecognitions.add(nonAcademicRecognition); + // }); + // } + + BasicInfo basicInfo = BasicInfo( + contactInformation: contactInformation, + primaryInformation: primaryInformation, + identifications: identificationInformation, + citizenships: citizenships, + addresses: addresses); + // OtherInformation otherInformation = OtherInformation( + // skillsAndHobbies: skillsHobbies, + // orgMemberships: orgMemberships, + // nonAcademicRecognition: nonAcademicRecognitions); + ProfileInformation profileInformation = ProfileInformation( + // families: families, + // otherInformation: otherInformation, + // workExperiences: workExperiences, + basicInfo: basicInfo, + // eligibilities: eligibilities, + // references: references, + // learningsAndDevelopment: learningsDevelopments, + // educationalBackgrounds: educationalBackgrounds, + // voluntaryWorks: voluntaryWorks + ); + profileInformation0 = profileInformation; + } + // }catch(e){ + // throw(e.toString()); + // } + return profileInformation0; + } +} + + diff --git a/lib/sevices/profile/references_services.dart b/lib/sevices/profile/references_services.dart new file mode 100644 index 0000000..ee215ba --- /dev/null +++ b/lib/sevices/profile/references_services.dart @@ -0,0 +1,136 @@ + + + +import 'dart:convert'; + +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/references.dart'; +import '../../utils/urls.dart'; +import 'package:http/http.dart' as http; +class ReferencesServices{ + static final ReferencesServices _instance = ReferencesServices(); + static ReferencesServices get instace => _instance; + + Future> getRefences(int profileId, String token)async{ + +List references = []; + String authToken = "Token $token"; + String path = "${Url.instance.reference()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try{ + http.Response response = await Request.instance.getRequest(path: path,param: {},headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + data['data'].forEach((var ref){ + PersonalReference reference = PersonalReference.fromJson(ref); + references.add(reference); + }); + } + } + }catch(e){ + throw e.toString(); + } + return references; + } + Future>addReference({required PersonalReference ref, required String token, required int profileId})async{ + String authToken = "Token $token"; + String path = "${Url.instance.reference()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map responseStatus ={}; + bool overseas = ref.address!.country !=null?true:false; + Map body = { + "first_name": ref.firstName, + "middle_name": ref.middleName, + "last_name": ref.lastName, + "contact_no":ref.contactNo, + "_addressCatId": ref.address!.addressCategory!.id, + "_areaClass": "Village", + "_citymunCode": overseas?null: ref.address?.cityMunicipality?.code, + "_brgyCode": overseas?null:ref.address?.barangay?.code, + "_countryId": overseas?ref.address!.country!.id:175 + }; + try{ + http.Response response = await Request.instance.postRequest(path: path,body: body,param: {},headers: headers); + if(response.statusCode == 201){ + Map data = jsonDecode(response.body); + responseStatus = data; + }else{ + responseStatus.addAll({'success':false}); + } + return responseStatus; + }catch(e){ + throw e.toString(); + } +} +Future> update({required PersonalReference ref,required String token, required int profileId})async{ + String authToken = "Token $token"; + String path = "${Url.instance.reference()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map responseStatus ={}; + bool overseas = ref.address!.country!.id != 175; + Map body = { + "id":ref.id, + "related_person_id": profileId, + "first_name": ref.firstName, + "middle_name": ref.middleName, + "last_name": ref.lastName, + "contact_no":ref.contactNo, + "_addressCatId": ref.address!.addressCategory!.id, + "_areaClass": "Village", + "_citymunCode": overseas?null: ref.address?.cityMunicipality?.code, + "_brgyCode": overseas?null:ref.address?.barangay?.code, + "_countryId": overseas?ref.address!.country!.id:175 + }; + // try{ + http.Response response = await Request.instance.putRequest(path: path,body: body,param: {},headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + responseStatus = data; + }else{ + responseStatus.addAll({'success':false}); + } + return responseStatus; + // }catch(e){ + // throw e.toString(); + // } +} + +Futuredelete({required int profileId, required String token, required int id })async{ + bool? success; + String authtoken = "Token $token"; + String path = "${Url.instance.reference()}$profileId/"; + Map params = {"force_mode": "true"}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + try{ + http.Response response = await Request.instance.deleteRequest(path: path, headers: headers, body: {"id":id}, param: params); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + success=data['success']; + }else{ + success = false; + } + return success!; + }catch(e){ + throw e.toString(); + } + +} + +} + + + diff --git a/lib/sevices/profile/volunatary_services.dart b/lib/sevices/profile/volunatary_services.dart new file mode 100644 index 0000000..41d4974 --- /dev/null +++ b/lib/sevices/profile/volunatary_services.dart @@ -0,0 +1,39 @@ + +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../model/profile/voluntary_works.dart'; +import '../../utils/urls.dart'; + +class VoluntaryService{ + static final VoluntaryService _instance = VoluntaryService(); + static VoluntaryService get instance => _instance; + + Future< List> getVoluntaryWorks(int profileId, String token)async{ + List voluntaryWorks = []; + String authToken = "Token $token"; + String path = "${Url.instance.getVoluntaryWorks()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + + try{ + http.Response response = await Request.instance.getRequest(path: path,param: {},headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + data['data'].forEach((var work){ + VoluntaryWork voluntaryWork = VoluntaryWork.fromJson(work); + voluntaryWorks.add(voluntaryWork); + }); + } + } + }catch(e){ + throw(e.toString()); + } + +return voluntaryWorks; + } +} \ No newline at end of file diff --git a/lib/sevices/profile/work_history_services.dart b/lib/sevices/profile/work_history_services.dart new file mode 100644 index 0000000..8e45820 --- /dev/null +++ b/lib/sevices/profile/work_history_services.dart @@ -0,0 +1,205 @@ +import 'dart:convert'; + +import 'package:unit2/model/profile/work_history.dart'; + +import 'package:http/http.dart' as http; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.dart'; +import 'package:unit2/model/utils/category.dart'; +import 'package:unit2/model/utils/position.dart'; +import 'package:unit2/utils/request.dart'; + +import '../../utils/urls.dart'; + +class WorkHistoryService { + static final WorkHistoryService _instance = WorkHistoryService(); + static WorkHistoryService get instance => _instance; + +//get all workhistories + Future> getWorkExperiences( + int profileId, String token) async { + List workExperiences = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + String path = Url.instance.workhistory() + profileId.toString(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var workHistory) { + workExperiences.add(WorkHistory.fromJson(workHistory)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return workExperiences; + } + + +////delete workhistory + Future delete( + {required int profileId, + required String token, + required WorkHistory work}) async { + bool? success; + Map params = {"force_mode": "true"}; + String authToken = "Token $token"; + String path = "${Url.instance.workhistory()}$profileId/"; + Map body = { + "id": work.id, + "position_id": work.position!.id, + "agency_id": work.agency!.id, + "from_date": work.fromDate?.toString(), + "to_date": work.toDate?.toString(), + "monthly_salary": work.monthlySalary, + "appointment_status": work.appointmentStatus, + "salary_step": work.sgStep, + "salary_grade": work.salaryGrade, + }; + Map 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!; + } + + + ////edit work history + Future> update({required WorkHistory oldWorkHistory, required WorkHistory newWorkHistory, required String token, required String profileId})async{ + Map? statusResponse={}; + String authtoken = "Token $token"; + String path = '${Url.instance.workhistory()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + Map body = { + "id":newWorkHistory.id, + "position_id":newWorkHistory.position!.id, + "agency_id":newWorkHistory.agency!.id, + "from_date":newWorkHistory.fromDate?.toString(), + "to_date":newWorkHistory.toDate?.toString(), + "monthly_salary":newWorkHistory.monthlySalary, + "appointment_status":newWorkHistory.appointmentStatus, + "salary_grade":newWorkHistory.salaryGrade, + "sg_step":newWorkHistory.sgStep, + "_positionName":newWorkHistory.position!.title!, + "_agencyName":newWorkHistory.agency!.name!, + "_agencyCatId":newWorkHistory.agency!.category!.id!, + "_privateEntity":newWorkHistory.agency!.privateEntity, + "oldPosId":oldWorkHistory.position!.id, + "_oldAgencyId":oldWorkHistory.agency!.id, + "oldFromDate":oldWorkHistory.fromDate?.toString(), + }; + try{ + http.Response response = await Request.instance.putRequest(path: path, headers: headers, body: body, param: {}); + if(response.statusCode == 200 ){ + Map data = jsonDecode(response.body); + statusResponse = data; + }else{ + statusResponse.addAll({'success':false}); + } + return statusResponse; + }catch(e){ + throw e.toString(); + } + } + + ////Add work history + Future>add({required WorkHistory workHistory, required String token, required int profileId , required bool isPrivate})async{ + String authtoken = "Token $token"; + String path = '${Url.instance.workhistory()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + Map statusResponse = {}; + Map body = { + 'position_id':workHistory.position?.id, + 'agency_id': workHistory.agency?.id, + 'from_date': workHistory.fromDate?.toString(), + 'to_date': workHistory.toDate?.toString(), + 'monthly_salary': workHistory.monthlySalary, + 'appointment_status': workHistory.appointmentStatus, + 'salary_grade': workHistory.salaryGrade, + 'sg_step':workHistory.sgStep, + '_positionName':workHistory.position?.title, + '_agencyName':workHistory.agency?.name, + '_agencyCatId':workHistory.agency?.category?.id, + '_privateEntity':workHistory.agency?.privateEntity, + }; + try{ + http.Response response = await Request.instance.postRequest(path: path,param: {},body: body,headers: headers); + if(response.statusCode == 201){ + Map data = jsonDecode(response.body); + statusResponse = data; + + }else{ + statusResponse.addAll({'success':false}); + } + return statusResponse; + }catch(e){ + throw e.toString(); + } + + } + +//get agency position + Future> getAgencyPosition() async { + List agencyPositions = []; + String path = Url.instance.getPositions(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var agencyPosition) { + Position position = Position.fromJson(agencyPosition); + agencyPositions.add(position); + }); + } + } + } catch (e) { + throw (e.toString()); + } + return agencyPositions; + } + +//get appointment status + List getAppointmentStatusList() { + return [ + AppoinemtStatus(value: "Appointed", label: "Appointed"), + AppoinemtStatus(value: "Casual", label: "Casual"), + AppoinemtStatus( + value: "Contact of Service", label: "Contract of Service"), + AppoinemtStatus(value: "Coterminous", label: "Coterminous"), + AppoinemtStatus(value: "Elected", label: "Elected"), + AppoinemtStatus(value: "Job Order", label: "Permanent"), + AppoinemtStatus(value: "Elected", label: "Elected"), + ]; + } +} diff --git a/lib/sevices/skillshobbies_services.dart b/lib/sevices/skillshobbies_services.dart new file mode 100644 index 0000000..f998dcc --- /dev/null +++ b/lib/sevices/skillshobbies_services.dart @@ -0,0 +1,129 @@ +import 'dart:convert'; + +import 'package:unit2/utils/request.dart'; + +import '../model/profile/other_information/skills_and_hobbies.dart'; +import '../utils/urls.dart'; +import 'package:http/http.dart' as http; + +class SkillsHobbiesServices { + static final SkillsHobbiesServices _instance = SkillsHobbiesServices(); + static SkillsHobbiesServices get instance => _instance; +////GET + Future> getSkillsHobbies( + int profileId, String token) async { + List skillsAndHobbies = []; + String authToken = "Token $token"; + String path = "${Url.instance.skillsHobbies()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data']['skill_hobby'] != null) { + data['data']['skill_hobby'].forEach((var hobby) { + SkillsHobbies skillsHobby = SkillsHobbies.fromJson(hobby); + skillsAndHobbies.add(skillsHobby); + }); + } + } + } catch (e) { + throw e.toString(); + } + return skillsAndHobbies; + } + +////ADD + Future> add( + {required List skillsHobbies, + required int profileId, + required String token}) async { + String authToken = "Token $token"; + String path = "${Url.instance.skillsHobbies()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + List> skillsHobbiesBody=[]; + for(var element in skillsHobbies){ + skillsHobbiesBody.add({"id":element.id,"name":element.name}); + } + Map body = {"skill_hobby": skillsHobbiesBody}; + Map statusResponse = {}; + try { + http.Response response = await Request.instance + .postRequest(path: path, param: {}, headers: headers, body: body); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({'success': false}); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future delete( + {required int profileId, + required String token, + required List skillsHobbies}) async { + String authToken = "Token $token"; + bool success = false; + String path = "${Url.instance.skillsHobbies()}$profileId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + Map params = {"force_mode": "true"}; + + Map body = { + "skill_hobby": [{"id":skillsHobbies[0].id, "name":skillsHobbies[0].name}] + + }; + // 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']; + } + // } catch (e) { + // throw e.toString(); + // } + return success; + } + + ////GET ALL + Future> getAllSkillsHobbies() async { + List skillsAndHobbies = []; + String path = Url.instance.getAllSkillsHobbies(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance.getRequest( + param: {}, + path: path, + headers: headers, + ); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var element) { + SkillsHobbies skillsHobbies = SkillsHobbies.fromJson(element); + skillsAndHobbies.add(skillsHobbies); + }); + } + } + } catch (e) { + throw e.toString(); + } + return skillsAndHobbies; + } +} diff --git a/lib/theme-data.dart/box_shadow.dart b/lib/theme-data.dart/box_shadow.dart new file mode 100644 index 0000000..1df168d --- /dev/null +++ b/lib/theme-data.dart/box_shadow.dart @@ -0,0 +1,8 @@ + import 'package:flutter/material.dart'; + +BoxDecoration box1(){ + return const BoxDecoration( + boxShadow: [BoxShadow(color: Colors.black12,spreadRadius: 5,blurRadius: 5)] , + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(3))); +} \ No newline at end of file diff --git a/lib/theme-data.dart/form-style.dart b/lib/theme-data.dart/form-style.dart index 7089e98..22d1e79 100644 --- a/lib/theme-data.dart/form-style.dart +++ b/lib/theme-data.dart/form-style.dart @@ -49,6 +49,8 @@ InputDecoration normalTextFieldStyle(String labelText, String hintText) { filled: false); } + + InputDecoration loginTextFieldStyle() { return InputDecoration( floatingLabelBehavior: FloatingLabelBehavior.never, diff --git a/lib/utils/alerts.dart b/lib/utils/alerts.dart index a9d488d..1cd6a82 100644 --- a/lib/utils/alerts.dart +++ b/lib/utils/alerts.dart @@ -1,9 +1,10 @@ import 'package:awesome_dialog/awesome_dialog.dart'; import 'package:flutter/material.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/global.dart'; -confirmAlert(context, Function() yes) { +confirmAlert(context, Function() yes,String title, String subtitle) { AwesomeDialog( context: context, dialogType: DialogType.question, @@ -26,8 +27,8 @@ confirmAlert(context, Function() yes) { // }, headerAnimationLoop: false, animType: AnimType.bottomSlide, - title: 'LOGOUT!', - desc: 'Are you sure you want to logout?', + title: title, + desc: subtitle, btnOkText: "Yes", btnCancelText: "No", showCloseIcon: false, @@ -36,7 +37,41 @@ confirmAlert(context, Function() yes) { ).show(); } -errorAlert(context, title, description) { +confirmAlertWithCancel(context, Function() yes,Function() no,String title, String subtitle) { + AwesomeDialog( + context: context, + dialogType: DialogType.question, + borderSide: const BorderSide( + color: Colors.green, + width: 0, + ), + width: blockSizeHorizontal * 90, + buttonsBorderRadius: const BorderRadius.all( + Radius.circular(2), + ), + dismissOnTouchOutside: false, + dismissOnBackKeyPress: false, + // onDismissCallback: (type) { + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text('Dismissed by $type'), + // ), + // ); + // }, + headerAnimationLoop: false, + animType: AnimType.bottomSlide, + title: title, + desc: subtitle, + btnOkText: "Yes", + btnCancelText: "No", + showCloseIcon: false, + btnCancelOnPress: no, + btnOkOnPress: yes, + ).show(); +} + + +errorAlert(context, title, description,Function() func) { AwesomeDialog( width: blockSizeHorizontal * 90, context: context, @@ -45,7 +80,30 @@ errorAlert(context, title, description) { headerAnimationLoop: false, title: title, desc: description, - btnOkOnPress: () {}, - btnOkColor: Colors.red, + btnOk: SizedBox(height: 50,child: ElevatedButton(onPressed:func, style: mainBtnStyle(primary, Colors.transparent, second), child: const Text("OK")), ) + ).show(); +} +successAlert(context, title, description,Function() func) { + AwesomeDialog( + width: blockSizeHorizontal * 90, + context: context, + dialogType: DialogType.success, + animType: AnimType.scale, + headerAnimationLoop: false, + title: title, + desc: description, + btnOk: SizedBox(height: 50,child: ElevatedButton(style: mainBtnStyle(success2, Colors.transparent, success), onPressed: func, child: const Text("OK")), ) + ).show(); +} +okAlert(context,title,description){ + AwesomeDialog( + width: blockSizeHorizontal * 90, + context: context, + dialogType: DialogType.error, + animType: AnimType.scale, + headerAnimationLoop: false, + title: title, + desc: description, + btnOkOnPress: () {}, ).show(); } diff --git a/lib/utils/app_router.dart b/lib/utils/app_router.dart index e6bc31b..7e6d33c 100644 --- a/lib/utils/app_router.dart +++ b/lib/utils/app_router.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:unit2/bloc/bloc/user_bloc.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/menu.dart'; import 'package:unit2/screens/unit2/login/login.dart'; import 'package:unit2/utils/global_context.dart'; +import '../bloc/user/user_bloc.dart'; import '../screens/profile/profile.dart'; import '../screens/unit2/basic-info/basic-info.dart'; import '../screens/unit2/homepage.dart/components/drawer-screen.dart'; @@ -32,6 +34,10 @@ class AppRouter { return const QRLogin(); }); case '/profile': + ProfileArguments arguments = routeSettings.arguments as ProfileArguments; + BlocProvider.of( + NavigationService.navigatorKey.currentContext!) + .add(LoadProfile(token:arguments.token ,userID:arguments.userID )); return MaterialPageRoute(builder: (_) { return const ProfileInfo(); }); diff --git a/lib/utils/custom_dropdown_button.dart b/lib/utils/custom_dropdown_button.dart new file mode 100644 index 0000000..308c72b --- /dev/null +++ b/lib/utils/custom_dropdown_button.dart @@ -0,0 +1,149 @@ +// import 'package:dropdown_button2/dropdown_button2.dart'; +// import 'package:flutter/material.dart'; + +// class CustomDropdownButton2 extends StatelessWidget { +// final String hint; +// final String? value; +// final List dropdownItems; +// final ValueChanged? onChanged; +// final DropdownButtonBuilder? selectedItemBuilder; +// final Alignment? hintAlignment; +// final Alignment? valueAlignment; +// final double? buttonHeight, buttonWidth; +// final EdgeInsetsGeometry? buttonPadding; +// final BoxDecoration? buttonDecoration; +// final int? buttonElevation; +// final Widget? icon; +// final double? iconSize; +// final Color? iconEnabledColor; +// final Color? iconDisabledColor; +// final double? itemHeight; +// final EdgeInsetsGeometry? itemPadding; +// final double? dropdownHeight, dropdownWidth; +// final EdgeInsetsGeometry? dropdownPadding; +// final BoxDecoration? dropdownDecoration; +// final int? dropdownElevation; +// final Radius? scrollbarRadius; +// final double? scrollbarThickness; +// final bool? scrollbarAlwaysShow; +// final Offset offset; + +// const CustomDropdownButton2({ +// required this.hint, +// required this.value, +// required this.dropdownItems, +// required this.onChanged, +// this.selectedItemBuilder, +// this.hintAlignment, +// this.valueAlignment, +// this.buttonHeight, +// this.buttonWidth, +// this.buttonPadding, +// this.buttonDecoration, +// this.buttonElevation, +// this.icon, +// this.iconSize, +// this.iconEnabledColor, +// this.iconDisabledColor, +// this.itemHeight, +// this.itemPadding, +// this.dropdownHeight, +// this.dropdownWidth, +// this.dropdownPadding, +// this.dropdownDecoration, +// this.dropdownElevation, +// this.scrollbarRadius, +// this.scrollbarThickness, +// this.scrollbarAlwaysShow, +// this.offset = const Offset(0, 0), +// Key? key, +// }) : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return DropdownButtonHideUnderline( +// child: DropdownButton2( +// //To avoid long text overflowing. +// isExpanded: true, +// hint: Container( +// alignment: hintAlignment, +// child: Text( +// hint, +// overflow: TextOverflow.ellipsis, +// maxLines: 1, +// style: TextStyle( +// fontSize: 14, +// color: Theme.of(context).hintColor, +// ), +// ), +// ), +// value: value, +// items: dropdownItems +// .map((item) => DropdownMenuItem( +// value: item, +// child: Container( +// alignment: valueAlignment, +// child: Text( +// item, +// overflow: TextOverflow.ellipsis, +// maxLines: 1, +// style: const TextStyle( +// fontSize: 14, +// ), +// ), +// ), +// )) +// .toList(), +// onChanged: onChanged, +// selectedItemBuilder: selectedItemBuilder, +// buttonStyleData: ButtonStyleData( +// height: buttonHeight ?? 40, +// width: buttonWidth ?? 140, +// padding: buttonPadding ?? const EdgeInsets.only(left: 14, right: 14), +// decoration: buttonDecoration ?? +// BoxDecoration( +// borderRadius: BorderRadius.circular(14), +// border: Border.all( +// color: Colors.black45, +// ), +// ), +// elevation: buttonElevation, +// ), +// iconStyleData: IconStyleData( +// icon: icon ?? const Icon(Icons.arrow_forward_ios_outlined), +// iconSize: iconSize ?? 12, +// iconEnabledColor: iconEnabledColor, +// iconDisabledColor: iconDisabledColor, +// ), +// dropdownStyleData: DropdownStyleData( +// //Max height for the dropdown menu & becoming scrollable if there are more items. If you pass Null it will take max height possible for the items. +// maxHeight: dropdownHeight ?? 200, +// width: dropdownWidth ?? 140, +// padding: dropdownPadding, +// decoration: dropdownDecoration ?? +// BoxDecoration( +// borderRadius: BorderRadius.circular(14), +// ), +// elevation: dropdownElevation ?? 8, +// //Null or Offset(0, 0) will open just under the button. You can edit as you want. +// offset: offset, +// //Default is false to show menu below button +// isOverButton: false, +// scrollbarTheme: ScrollbarThemeData( +// radius: scrollbarRadius ?? const Radius.circular(40), +// thickness: scrollbarThickness != null +// ? MaterialStateProperty.all(scrollbarThickness!) +// : null, +// thumbVisibility: scrollbarAlwaysShow != null +// ? MaterialStateProperty.all(scrollbarAlwaysShow!) +// : null, +// ), +// ), +// menuItemStyleData: MenuItemStyleData( +// height: itemHeight ?? 40, +// padding: itemPadding ?? const EdgeInsets.only(left: 14, right: 14), +// ), +// ), +// ); +// } +// } \ No newline at end of file diff --git a/lib/utils/global.dart b/lib/utils/global.dart index ccbabf2..de816db 100644 --- a/lib/utils/global.dart +++ b/lib/utils/global.dart @@ -1,3 +1,5 @@ +import 'package:hive/hive.dart'; + double screenWidth = 0; double screenHeight = 0; double blockSizeHorizontal = 0; @@ -5,4 +7,9 @@ double blockSizeVertical = 0; double safeAreaHorizontal = 0; double safeAreaVertical = 0; double safeBlockHorizontal = 0; -double safeBlockVertical = 0; \ No newline at end of file +double safeBlockVertical = 0; + + +//// hive boxes +Box? CREDENTIALS; +Box? SOSCONTACTS; \ No newline at end of file diff --git a/lib/utils/internet_time_out.dart b/lib/utils/internet_time_out.dart new file mode 100644 index 0000000..b4a0359 --- /dev/null +++ b/lib/utils/internet_time_out.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; + +import '../theme-data.dart/colors.dart'; + +class TimeOutError extends StatelessWidget { + const TimeOutError({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/svgs/timeout.svg', + height: 200.0, + width: 200.0, + allowDrawingOutsideViewBox: true, + ), + const SizedBox( + height: 25, + ), + const Text( + 'Connection Timeout! Pls check your internet connectivity.', + textAlign: TextAlign.center,), + + const SizedBox( + height: 25, + ), + SizedBox( + height: 50, + child: ElevatedButton.icon( + style: mainBtnStyle( + primary, Colors.transparent, primary.withOpacity(.5)), + onPressed:(){ + }, + icon: const Icon( + Icons.refresh, + color: Colors.white, + ), + label: const Text( + "try again", + style: TextStyle(color: Colors.white), + )), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/utils/location_utilities.dart b/lib/utils/location_utilities.dart new file mode 100644 index 0000000..e52c10b --- /dev/null +++ b/lib/utils/location_utilities.dart @@ -0,0 +1,142 @@ +import 'dart:convert'; + +import 'package:unit2/model/location/address_category.dart'; +import 'package:unit2/model/location/barangay.dart'; +import 'package:unit2/model/location/city.dart'; +import 'package:unit2/model/location/country.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/model/location/provinces.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; + +import '../model/location/region.dart'; + +class LocationUtils { + static final LocationUtils _instance = LocationUtils(); + static LocationUtils get instance => _instance; + + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + + Future> getCountries() async { + List countries = []; + String path = Url.instance.getCounties(); + + try{ + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var country) { + Country newCOuntry = Country.fromJson(country); + countries.add(newCOuntry); + }); + } + } + }catch(e){ + throw(e.toString()); + } + return countries; + } + + Future> getRegions() async { + List regions = []; + String path = Url.instance.getRegions(); + + try{ + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var region) { + Region newRegion = Region.fromJson(region); + regions.add(newRegion); + }); + } + } + }catch(e){ + throw(e.toString()); + } + return regions; + } + + Future> getProvinces({required String regionCode}) async { + List provinces = []; + String path = Url.instance.getProvinces() + regionCode; + + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var province) { + Province newProvince = Province.fromJson(province); + provinces.add(newProvince); + }); + } + } catch (e) { + throw (e.toString()); + } + return provinces; + } + + Future> getCities({required String code}) async { + List cities = []; + String path = Url.instance.getCities() + code; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var city) { + CityMunicipality cityMun = CityMunicipality.fromJson(city); + cities.add(cityMun); + }); + } + } catch (e) { + throw (e.toString()); + } + return cities; + } + + Future> getBarangay({required String code}) async { + List barangays = []; + String path = Url.instance.getBarangays() + code; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var city) { + Barangay barangay = Barangay.fromJson(city); + barangays.add(barangay); + }); + } + } catch (e) { + throw (e.toString()); + } + return barangays; + } + Future>getAddressCategory()async{ + List categories = []; + String path = Url.instance.getAddressCategory(); + try{ + http.Response response = await Request.instance.getRequest(path: path,param: {},headers:headers ); + Map data = jsonDecode(response.body); + if(data['data'] != null){ + data['data'].forEach((var cat){ + categories.add(AddressCategory.fromJson(cat)); + }); + } + categories; + return categories; + }catch(e){ + throw e.toString(); + } + } + + +} diff --git a/lib/utils/profile_utilities.dart b/lib/utils/profile_utilities.dart new file mode 100644 index 0000000..310dc61 --- /dev/null +++ b/lib/utils/profile_utilities.dart @@ -0,0 +1,118 @@ + +import 'dart:convert'; + +import 'package:unit2/model/location/country.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/model/location/region.dart'; +import 'package:unit2/model/utils/eligibility.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; + +import '../model/profile/basic_information/contact_information.dart'; +import '../model/utils/agency.dart'; +import '../model/utils/category.dart'; +class ProfileUtilities { + static final ProfileUtilities _instance = ProfileUtilities(); + static ProfileUtilities get instance => _instance; + + Future>getEligibilities()async{ + List eligibilities=[]; + String path = Url.instance.eligibilities(); + + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try{ + http.Response response = await Request.instance.getRequest(path: path, param: {},headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + data['data'].forEach((var eligibility){ + Eligibility newEligibilities = Eligibility.fromJson(eligibility); + eligibilities.add(newEligibilities); + }); + } + } + }catch(e){ + throw(e.toString()); + } + return eligibilities; + } + + //get agencies + Future> getAgecies() async { + List agencies = []; + String path = Url.instance.getAgencies(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var agency) { + Agency newAgency = Agency.fromJson(agency); + agencies.add(newAgency); + }); + } + } + } catch (e) { + throw e.toString(); + } + return agencies; + } + + +//get agency category + Future> agencyCategory() async { + List agencyCategory = []; + String path = Url.instance.getAgencyCategory(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var agency) { + Category category = Category.fromJson(agency); + agencyCategory.add(category); + }); + } + } + } catch (e) { + throw e.toString(); + } + return agencyCategory; + } + +//// get service type + Future> getServiceType()async{ + List serviceTypes = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + String path = Url.instance.getServiceTypes(); + + try{ + http.Response response = await Request.instance.getRequest(param: {},path:path,headers: headers ); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + for(var element in data['data']){ + ServiceType newServiceType = ServiceType.fromJson(element); + serviceTypes.add(newServiceType); + } + } + } + }catch(e){ + throw e.toString(); + } + return serviceTypes; + } + +} \ No newline at end of file diff --git a/lib/utils/request.dart b/lib/utils/request.dart index d698418..c224af0 100644 --- a/lib/utils/request.dart +++ b/lib/utils/request.dart @@ -19,7 +19,7 @@ class Request { Map? param}) async { Response response; try { - response = await get(Uri.https(host, path!, param), headers: headers) + response = await get(Uri.http(host, path!, param), headers: headers) .timeout(Duration(seconds: requestTimeout)); } on TimeoutException catch (_) { Fluttertoast.showToast( @@ -61,7 +61,8 @@ class Request { Map? param}) async { Response response; try { - response = await post(Uri.https(host, path!, param), headers: headers,body: jsonEncode(body)) + response = await post(Uri.http(host, path!, param), + headers: headers, body: jsonEncode(body)) .timeout(Duration(seconds: requestTimeout)); } on TimeoutException catch (_) { Fluttertoast.showToast( @@ -95,4 +96,87 @@ class Request { } return response; } + + Future putRequest( + {required String path, + required Map? headers, + required Map? body, + required Map? param}) async { + Response response; + try { + response =await put(Uri.http(host,path,param),headers: headers,body: jsonEncode(body)); + } on TimeoutException catch (_) { + Fluttertoast.showToast( + msg: timeoutError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (timeoutError); + } on SocketException catch (_) { + Fluttertoast.showToast( + msg: timeoutError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (timeoutError); + } on FormatException catch (_) { + throw const FormatException(formatError); + } on HttpException catch (_) { + throw const HttpException(httpError); + } on Error catch (e) { + debugPrint("post request error: $e"); + Fluttertoast.showToast( + msg: onError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (e.toString()); + } + return response; + } + + Future deleteRequest( + {required String path, + required Map? headers, + required Map? body, + required Map? param}) async { + Response response; + try { + response = await delete(Uri.http(host, path, param), + headers: headers, body: jsonEncode(body)) + .timeout(Duration(seconds: requestTimeout)); + } on TimeoutException catch (_) { + Fluttertoast.showToast( + msg: timeoutError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (timeoutError); + } on SocketException catch (_) { + Fluttertoast.showToast( + msg: timeoutError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (timeoutError); + } on FormatException catch (_) { + throw const FormatException(formatError); + } on HttpException catch (_) { + throw const HttpException(httpError); + } on Error catch (e) { + Fluttertoast.showToast( + msg: onError, + toastLength: Toast.LENGTH_LONG, + gravity: ToastGravity.BOTTOM, + backgroundColor: Colors.black, + ); + throw (e.toString()); + } + return response; + } } diff --git a/lib/utils/text_container.dart b/lib/utils/text_container.dart index 8363228..2e72c43 100644 --- a/lib/utils/text_container.dart +++ b/lib/utils/text_container.dart @@ -69,6 +69,50 @@ const String timeoutError = "Internet timeout! Please Check your connection"; const String formatError = "Invalid Error"; const String httpError = "Error getting requested data"; const String onError = "Something went wrong! Please try again."; -// +const String adressScreenTitle = "Addresses"; +const String citizenshipScreenTitle = "Citizenship"; +const String contactScreenTitle = "Contact Information"; +const String identificationScreenTitle = "Identifications"; +const String idNumberText = "ID number"; +const String privateText = 'private'; +const String governmentText = "government"; +const String primaryInformationScreenTitle = "Primary Information"; +const String lastname = "lastname"; +const String firstname = "firstname"; +const String middlename = "middlename"; +const String extensionName = 'extension-name'; +const String birthDat = 'bday'; +const String sex = 'sex'; +const String bloodType = 'bloodtype'; +const String civilStatus = 'civil-status'; +const String gender = 'gender'; +const String height = 'height'; +const String width = 'width'; +const String prefixSuffix = 'prefix&suffix'; +const String nonAcademicRecTitle = "Non Academic Recognition"; +const String orgMembershipTitle = "Organization Membership"; +const String skillAndHobbiesTitle = "Skills and Hobbies"; +const String educationScreenTitle = "Educational Background"; +const String honorsText = 'Honors'; +const String elibilityScreenTitle = "Eligibility"; +const String licenseNumber = "LicenseNumber"; +const String rating = "Rating"; +const String familyBackgroundScreenTitle = "Family Background"; +const String fatherText = "Father"; +const String fullname = "Full name"; +const String incaseOfEmergency = "Incase of emergency"; +const String motherText = 'Mother'; +const String spouseText = "Spouse"; +const String childrenText = "Children"; +const String otherRelatedText = "Other related person"; +const String learningAndDevelopmentScreenTitle = "Learning and Development"; +const String duration = "Duration"; +const String type = "Type"; +const String referencesScreenTitle = "Personal References"; +const String mobileOrPhone = "phone / mobile number"; +const String voluntaryScreenTitle = "Voluntary Work & Civic Services"; +const String numberOfHours = "Worked/Involved for"; +const String workHistoryScreenTitle = "Work History"; +const String present = "present"; // diff --git a/lib/utils/urls.dart b/lib/utils/urls.dart index 438d113..8849535 100644 --- a/lib/utils/urls.dart +++ b/lib/utils/urls.dart @@ -1,19 +1,140 @@ -class Url{ +class Url { static final Url _instance = Url(); static Url get instance => _instance; - String host(){ - // return '192.168.10.219:3000'; - return 'agusandelnorte.gov.ph'; + String host() { + // return '192.168.10.221:3003'; + return 'agusandelnorte.gov.ph'; + // return "192.168.10.219:3000"; + // return "devweb.agusandelnorte.gov.ph"; + // return 'devapi.agusandelnorte.gov.ph:3004'; } - - String authentication(){ + String authentication() { return '/api/account/auth/login/'; } - - String apkUrl(){ - return ""; + + String profileInformation(){ + return 'api/jobnet_app/profile/pds/'; } + String latestApk(){ + return "/api/system_app/apk_version/latest"; + } + +////ELIGIBILITIES PATHS +String eligibilities(){ + return "/api/jobnet_app/eligibilities/"; +} + +String getEligibilities(){ + return "/api/jobnet_app/profile/pds/eligibility/"; +} + +String addEligibility(){ + return "/api/jobnet_app/profile/pds/eligibility/"; +} +String deleteEligibility(){ + return "/api/jobnet_app/profile/pds/eligibility/"; +} + +String updateEligibility(){ + return "/api/jobnet_app/profile/pds/eligibility/"; +} +//// work history paths +String workhistory(){ + return "/api/jobnet_app/profile/pds/work/"; +} +String getPositions(){ + return "/api/jobnet_app/positions/"; +} +String getAgencies(){ + return "/api/jobnet_app/agencies/"; +} + + + +String getAgencyCategory(){ + return "api/jobnet_app/agency_categories/"; +} + + +////educational background paths +String getEducationalBackgrounds(){ + return "/api/jobnet_app/profile/pds/education/"; +} + +//// learning and development paths + +String getLearningAndDevelopments(){ + return "api/jobnet_app/profile/pds/learning_development/"; +} + +//// references paths +String reference(){ + return "/api/jobnet_app/profile/pds/personal_reference/"; +} + + +////voluntary works +String getVoluntaryWorks(){ + return "/api/jobnet_app/profile/pds/voluntary_work/"; +} + +//// skills hobbies +String skillsHobbies(){ + return "/api/jobnet_app/profile/pds/other/skill_hobby/"; +} +String getAllSkillsHobbies(){ + return "/api/jobnet_app/skill_hobby/"; +} +//// orgmemberships +String getOrgMemberShips(){ + return "/api/jobnet_app/profile/pds/other/org_membership/"; +} + +////non academic recognition +String getNonAcademicRecognition(){ + return "/api/jobnet_app/profile/pds/other/non_acad_recognition/"; +} + +////family paths +String getFamilies(){ + return "/api/jobnet_app/profile/pds/family/"; +} + +//// contacts path +String getServiceTypes(){ + return "/api/jobnet_app/comm_service_type/"; + +} +String contactPath(){ + return "/api/jobnet_app/profile/pds/basic/contact/"; +} +String getCommunicationProvider(){ + return "/api/jobnet_app/comm_services/"; +} +String deleteContact (){ + return "/api/jobnet_app/profile/pds/basic/contact/"; +} + + // location utils path + String getCounties(){ + return "/api/jobnet_app/countries/"; + } + String getRegions(){ + return "/api/web_app/location/region/"; + } + String getProvinces(){ + return "api/web_app/location/province/"; + } + String getCities(){ + return "/api/web_app/location/citymun/"; + } + String getBarangays(){ + return "/api/web_app/location/barangay/"; + } + String getAddressCategory(){ + return "/api/jobnet_app/address_categories/"; + } } \ No newline at end of file diff --git a/lib/utils/validators.dart b/lib/utils/validators.dart index 52f4c1f..b2c05e6 100644 --- a/lib/utils/validators.dart +++ b/lib/utils/validators.dart @@ -6,9 +6,29 @@ final mobileNumberValidator = FormBuilderValidators.compose([ FormBuilderValidators.required(errorText: mobileNumberRequired), FormBuilderValidators.numeric(errorText: numericValidator) ]); +final numericRequired = FormBuilderValidators.compose([ + FormBuilderValidators.required(errorText: "This field is required"), + FormBuilderValidators.numeric(errorText: numericValidator) +]); final registerPasswordValidator = FormBuilderValidators.compose([ FormBuilderValidators.required(errorText: "Password is required"), FormBuilderValidators.minLength(6, errorText: "Password must be equal or greater than 6 characters"), ]); + +final integerAndNumeric = + FormBuilderValidators + .compose([ + FormBuilderValidators + .integer( + radix: 10, + errorText: + "Please enter a number"), + FormBuilderValidators + .numeric( + errorText: + "Please enter a number") + ]); + + diff --git a/lib/widgets/Leadings/add_leading.dart b/lib/widgets/Leadings/add_leading.dart new file mode 100644 index 0000000..b053d1a --- /dev/null +++ b/lib/widgets/Leadings/add_leading.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; + +class AddLeading extends StatelessWidget { + final Function() onPressed; + const AddLeading({super.key, required this.onPressed}); + + @override + Widget build(BuildContext context) { + return IconButton(onPressed: onPressed, icon: const Icon(Icons.add)); + } +} \ No newline at end of file diff --git a/lib/widgets/Leadings/close_leading.dart b/lib/widgets/Leadings/close_leading.dart new file mode 100644 index 0000000..f4ea312 --- /dev/null +++ b/lib/widgets/Leadings/close_leading.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; + +class CloseLeading extends StatelessWidget { + final Function() onPressed; + const CloseLeading({super.key, required this.onPressed}); + + @override + Widget build(BuildContext context) { + return IconButton(onPressed: onPressed, icon: const Icon(Icons.close)); + } +} \ No newline at end of file diff --git a/lib/widgets/custom_switch.dart b/lib/widgets/custom_switch.dart new file mode 100644 index 0000000..907993f --- /dev/null +++ b/lib/widgets/custom_switch.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:toggle_switch/toggle_switch.dart'; + +class CostumToggleSwitch extends StatelessWidget { + final List activeBGColors; + final List icons; +final int initialLabelIndex; + final void Function(int?)? onToggle; + final List labels; + const CostumToggleSwitch( + {Key? key, + required this.activeBGColors, + required this.icons, + required this.onToggle, + required this.labels, + required this.initialLabelIndex + + }) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(15), + height: 80, + child: ToggleSwitch( + minWidth: 150.0, + cornerRadius: 25.0, + activeBgColors: [ + [Colors.green[800]!], + [Colors.red[800]!] + ], + activeFgColor: Colors.white, + inactiveBgColor: Colors.grey, + inactiveFgColor: Colors.white, + initialLabelIndex: initialLabelIndex, + totalSwitches: 2, + labels: labels, + icons: icons, + radiusStyle: false, + onToggle: onToggle), + ); + } +} diff --git a/lib/widgets/empty_data.dart b/lib/widgets/empty_data.dart new file mode 100644 index 0000000..78a4515 --- /dev/null +++ b/lib/widgets/empty_data.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:unit2/utils/global.dart'; + + +class EmptyData extends StatelessWidget { + final String message; + const EmptyData({Key? key, required this.message,}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/svgs/empty.svg', + height: 200.0, + width: 200.0, + allowDrawingOutsideViewBox: true, + ), + const SizedBox( + height: 20, + ), + Text( + message,style: Theme.of(context).textTheme.displaySmall!.copyWith(fontSize: blockSizeVertical * 2), + textAlign: TextAlign.center, + ), + + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/widgets/error_state.dart b/lib/widgets/error_state.dart index ede9ef3..b23027f 100644 --- a/lib/widgets/error_state.dart +++ b/lib/widgets/error_state.dart @@ -1,13 +1,58 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/src/widgets/container.dart'; -import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; -class ErrorState extends StatelessWidget { +import '../theme-data.dart/colors.dart'; + +class SomethingWentWrong extends StatelessWidget { final String? message; - const ErrorState({super.key,this.message}); + final Function()? onpressed; + const SomethingWentWrong({Key? key, required this.message, required this.onpressed}) + : super(key: key); @override Widget build(BuildContext context) { - return Center(child: Text(message!)); + return Container( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/svgs/timeout.svg', + height: 200.0, + width: 200.0, + allowDrawingOutsideViewBox: true, + ), + const SizedBox( + height: 10, + ), + Text( + message??'', + textAlign: TextAlign.center, + ), + const SizedBox( + height: 20, + ), + SizedBox( + height: 50, + child: ElevatedButton.icon( + style: mainBtnStyle( + primary, Colors.transparent, primary.withOpacity(.5)), + onPressed: onpressed, + icon: const Icon( + Icons.refresh, + color: Colors.white, + ), + label: const Text( + "try again", + style: TextStyle(color: Colors.white), + )), + ) + ], + ), + ), + ); } } \ No newline at end of file diff --git a/lib/widgets/splash_screen.dart b/lib/widgets/splash_screen.dart index 41a2a8d..364c8ac 100644 --- a/lib/widgets/splash_screen.dart +++ b/lib/widgets/splash_screen.dart @@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/container.dart'; import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/global.dart'; @@ -14,7 +15,7 @@ class UniTSplashScreen extends StatelessWidget { Widget build(BuildContext context) { return Container( height: MediaQuery.of(context).size.height, - color: Colors.white, + color: Colors.black12, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -44,6 +45,19 @@ class UniTSplashScreen extends StatelessWidget { height: 1, color: Colors.black)), ), + const SizedBox(height: 150,), + const SpinKitCircle(color: primary,size: 42,) + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Flexible( + // flex: 2, + // child: Text("Please Wait ",style: Theme.of(context).textTheme.labelLarge!.copyWith(fontSize: 18))), + // const SizedBox(width: 5,), + // const SpinKitDoubleBounce(color: primary,size: 32,) + // ],) + ], ), ), diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..a124bbe 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,6 +6,10 @@ #include "generated_plugin_registrant.h" +#include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) modal_progress_hud_nsn_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "ModalProgressHudNsnPlugin"); + modal_progress_hud_nsn_plugin_register_with_registrar(modal_progress_hud_nsn_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..f6f1987 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + modal_progress_hud_nsn ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 46d0540..4567379 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,14 @@ import FlutterMacOS import Foundation +import modal_progress_hud_nsn import package_info_plus -import path_provider_macos -import shared_preferences_macos +import path_provider_foundation +import shared_preferences_foundation import sqflite func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + ModalProgressHudNsnPlugin.register(with: registry.registrar(forPlugin: "ModalProgressHudNsnPlugin")) FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..42d76d9 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,57 @@ +PODS: + - FlutterMacOS (1.0.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - modal_progress_hud_nsn (0.0.1): + - FlutterMacOS + - package_info_plus (0.0.1): + - FlutterMacOS + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite (0.0.2): + - FlutterMacOS + - FMDB (>= 2.7.5) + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - modal_progress_hud_nsn (from `Flutter/ephemeral/.symlinks/plugins/modal_progress_hud_nsn/macos`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`) + - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) + +SPEC REPOS: + trunk: + - FMDB + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + modal_progress_hud_nsn: + :path: Flutter/ephemeral/.symlinks/plugins/modal_progress_hud_nsn/macos + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos + sqflite: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + modal_progress_hud_nsn: 8099d46c2cf9de7af8fe0a3f8f5d2aa32cf956c3 + package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce + path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 + shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca + sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 + +COCOAPODS: 1.11.3 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 83583de..7b7cf22 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 0B42AD366C3C28D47C2AEC89 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6C623098EB8995A39C4964E /* Pods_Runner.framework */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; @@ -52,9 +53,10 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2023D02FF0211CAEE16878C9 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* unit2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "unit2.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* unit2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = unit2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -66,8 +68,11 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 5BC0F6D90E7D68DE5330DF33 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 7FF1BC1DFB4A45BAC2293138 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + D6C623098EB8995A39C4964E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -75,6 +80,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0B42AD366C3C28D47C2AEC89 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,6 +105,7 @@ 33CEB47122A05771004F2AC0 /* Flutter */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + 64DE41DBDE00B8F8F94614A7 /* Pods */, ); sourceTree = ""; }; @@ -145,9 +152,21 @@ path = Runner; sourceTree = ""; }; + 64DE41DBDE00B8F8F94614A7 /* Pods */ = { + isa = PBXGroup; + children = ( + 5BC0F6D90E7D68DE5330DF33 /* Pods-Runner.debug.xcconfig */, + 7FF1BC1DFB4A45BAC2293138 /* Pods-Runner.release.xcconfig */, + 2023D02FF0211CAEE16878C9 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + D6C623098EB8995A39C4964E /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -159,11 +178,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + C3E6A8BAF2259AABAF243D8C /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + F31D2B687E220EE9896D3A25 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -235,6 +256,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -270,6 +292,45 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + C3E6A8BAF2259AABAF243D8C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + F31D2B687E220EE9896D3A25 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -344,7 +405,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +531,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index fdc4170..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,975 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - animate_do: - dependency: "direct main" - description: - name: animate_do - sha256: "9aeacc1a7238f971c039bdf45d13c628be554a242e0251c4ddda09d19a1a923f" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - archive: - dependency: transitive - description: - name: archive - sha256: ed7cc591a948744994714375caf9a2ce89e1d82e8243997c8a2994d57181c212 - url: "https://pub.dev" - source: hosted - version: "3.3.5" - async: - dependency: transitive - description: - name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dev" - source: hosted - version: "2.10.0" - auto_size_text: - dependency: "direct main" - description: - name: auto_size_text - sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" - url: "https://pub.dev" - source: hosted - version: "3.0.0" - awesome_dialog: - dependency: "direct main" - description: - name: awesome_dialog - sha256: ac08268b991f228fc6b8880b68ec030d2941bcc8df8b6a6551fb79f2bd36b7da - url: "https://pub.dev" - source: hosted - version: "3.0.2" - azlistview: - dependency: "direct main" - description: - name: azlistview - sha256: "93e865f11777a271b439f0d6b00799c0797e9daeec2e082a2e01373809c4b90d" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - barcode_scan2: - dependency: "direct main" - description: - name: barcode_scan2 - sha256: f9af9252b8f3f5fa446f5456fd45f8871d09f883d8389a1d608b39231bfbc3fa - url: "https://pub.dev" - source: hosted - version: "4.2.3" - bloc: - dependency: transitive - description: - name: bloc - sha256: bd4f8027bfa60d96c8046dec5ce74c463b2c918dce1b0d36593575995344534a - url: "https://pub.dev" - source: hosted - version: "8.1.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 - url: "https://pub.dev" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 - url: "https://pub.dev" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 - url: "https://pub.dev" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dev" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dev" - source: hosted - version: "1.17.0" - convert: - dependency: transitive - description: - name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" - url: "https://pub.dev" - source: hosted - version: "3.1.1" - convex_bottom_bar: - dependency: "direct main" - description: - name: convex_bottom_bar - sha256: "6c9d23fa309b2cf2cb4804a6318e34694f4714c29fac79621ff88b71266fbe57" - url: "https://pub.dev" - source: hosted - version: "3.1.0+1" - cool_alert: - dependency: "direct main" - description: - name: cool_alert - sha256: "48a0b6c04914b6dc7e8d7eaccf2adf21bace6533a3eda0aeb412e0d7a03dc00a" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - crypto: - dependency: transitive - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - date_time_picker: - dependency: "direct main" - description: - name: date_time_picker - sha256: "6923c568bcb67a66ab7e083708d0adbcae8214b41bb84d49febc17e89e06fc4a" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - device_frame: - dependency: transitive - description: - name: device_frame - sha256: afe76182aec178d171953d9b4a50a43c57c7cf3c77d8b09a48bf30c8fa04dd9d - url: "https://pub.dev" - source: hosted - version: "1.1.0" - device_preview: - dependency: "direct main" - description: - name: device_preview - sha256: "2f097bf31b929e15e6756dbe0ec1bcb63952ab9ed51c25dc5a2c722d2b21fdaf" - url: "https://pub.dev" - source: hosted - version: "1.1.0" - dio: - dependency: "direct main" - description: - name: dio - sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" - url: "https://pub.dev" - source: hosted - version: "4.0.6" - easy_app_installer: - dependency: "direct main" - description: - name: easy_app_installer - sha256: d7287bf247fe6bc85ad07dfb85804757a6dd2f47e61b0e7ce9195ec7f13e09eb - url: "https://pub.dev" - source: hosted - version: "1.0.0" - equatable: - dependency: "direct main" - description: - name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 - url: "https://pub.dev" - source: hosted - version: "2.0.5" - expandable_group: - dependency: "direct main" - description: - name: expandable_group - sha256: "874f9c2daef8a21366fb1df85405f80ee8e8be6e3c2ced727c303641b33b9a95" - url: "https://pub.dev" - source: hosted - version: "0.0.8" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - file_utils: - dependency: transitive - description: - name: file_utils - sha256: d1e64389a22649095c8405c9e177272caf05139255931c9ff30d53b5c9bcaa34 - url: "https://pub.dev" - source: hosted - version: "1.0.1" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec" - url: "https://pub.dev" - source: hosted - version: "1.0.1" - flare_flutter: - dependency: transitive - description: - name: flare_flutter - sha256: "99d63c60f00fac81249ce6410ee015d7b125c63d8278a30da81edf3317a1f6a0" - url: "https://pub.dev" - source: hosted - version: "3.0.2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_bloc: - dependency: "direct main" - description: - name: flutter_bloc - sha256: "890c51c8007f0182360e523518a0c732efb89876cb4669307af7efada5b55557" - url: "https://pub.dev" - source: hosted - version: "8.1.1" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" - url: "https://pub.dev" - source: hosted - version: "3.3.0" - flutter_custom_clippers: - dependency: "direct main" - description: - name: flutter_custom_clippers - sha256: "473e3daf61c2a6cee0ad137393259a25223239d519a131c7ec1cac04d06e5407" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - flutter_form_builder: - dependency: "direct main" - description: - name: flutter_form_builder - sha256: "768b11307e71c60cb66351a87984815bd438b50aa58b5de02c9256a8f2964bee" - url: "https://pub.dev" - source: hosted - version: "7.7.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.dev" - source: hosted - version: "2.0.1" - flutter_localizations: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" - url: "https://pub.dev" - source: hosted - version: "2.0.7" - flutter_progress_hud: - dependency: "direct main" - description: - name: flutter_progress_hud - sha256: "19a4889460b7482c5026a936b768996dade4daad8570e8c0493e292d57121dbb" - url: "https://pub.dev" - source: hosted - version: "2.0.2" - flutter_spinkit: - dependency: "direct main" - description: - name: flutter_spinkit - sha256: "77a2117c0517ff909221f3160b8eb20052ab5216107581168af574ac1f05dff8" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" - url: "https://pub.dev" - source: hosted - version: "1.1.6" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_zoom_drawer: - dependency: "direct main" - description: - name: flutter_zoom_drawer - sha256: "93c4f2cfe1edfe2f9e48b94a7f9538520d2f2593e202b8e89c394b7d27137a8e" - url: "https://pub.dev" - source: hosted - version: "3.0.3" - fluttericon: - dependency: "direct main" - description: - name: fluttericon - sha256: "252fa8043826e93d972a602497a260cb3d62b5aea6d045793e4381590f2c1e99" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - fluttertoast: - dependency: "direct main" - description: - name: fluttertoast - sha256: "7cc92eabe01e3f1babe1571c5560b135dfc762a34e41e9056881e2196b178ec1" - url: "https://pub.dev" - source: hosted - version: "8.1.2" - form_builder_validators: - dependency: "direct main" - description: - name: form_builder_validators - sha256: e4d54c0c513e3e36ae4e4905994873a0a907585407212effeef39a68e759670c - url: "https://pub.dev" - source: hosted - version: "8.4.0" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - sha256: aeac15850ef1b38ee368d4c53ba9a847e900bb2c53a4db3f6881cbb3cb684338 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - globbing: - dependency: transitive - description: - name: globbing - sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - graphs: - dependency: transitive - description: - name: graphs - sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 - url: "https://pub.dev" - source: hosted - version: "2.2.0" - http: - dependency: transitive - description: - name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" - url: "https://pub.dev" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - image: - dependency: transitive - description: - name: image - sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" - url: "https://pub.dev" - source: hosted - version: "3.3.0" - intl: - dependency: "direct main" - description: - name: intl - sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" - url: "https://pub.dev" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dev" - source: hosted - version: "0.6.5" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "3520fa844009431b5d4491a5a778603520cdc399ab3406332dcc50f93547258c" - url: "https://pub.dev" - source: hosted - version: "4.7.0" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - lottie: - dependency: transitive - description: - name: lottie - sha256: "893da7a0022ec2fcaa616f34529a081f617e86cc501105b856e5a3184c58c7c2" - url: "https://pub.dev" - source: hosted - version: "1.4.3" - matcher: - dependency: transitive - description: - name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dev" - source: hosted - version: "0.12.13" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dev" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" - octo_image: - dependency: transitive - description: - name: octo_image - sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - package_info_plus: - dependency: "direct main" - description: - name: package_info_plus - sha256: f619162573096d428ccde2e33f92e05b5a179cd6f0e3120c1005f181bee8ed16 - url: "https://pub.dev" - source: hosted - version: "3.0.2" - package_info_plus_platform_interface: - dependency: transitive - description: - name: package_info_plus_platform_interface - sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - path: - dependency: transitive - description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dev" - source: hosted - version: "1.8.2" - path_drawing: - dependency: transitive - description: - name: path_drawing - sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 - url: "https://pub.dev" - source: hosted - version: "1.0.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf - url: "https://pub.dev" - source: hosted - version: "1.0.1" - path_provider: - dependency: "direct main" - description: - name: path_provider - sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd" - url: "https://pub.dev" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e - url: "https://pub.dev" - source: hosted - version: "2.0.22" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8" - url: "https://pub.dev" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 - url: "https://pub.dev" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 - url: "https://pub.dev" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c - url: "https://pub.dev" - source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - permission_handler: - dependency: "direct main" - description: - name: permission_handler - sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" - url: "https://pub.dev" - source: hosted - version: "10.2.0" - permission_handler_android: - dependency: transitive - description: - name: permission_handler_android - sha256: "8028362b40c4a45298f1cbfccd227c8dd6caf0e27088a69f2ba2ab15464159e2" - url: "https://pub.dev" - source: hosted - version: "10.2.0" - permission_handler_apple: - dependency: transitive - description: - name: permission_handler_apple - sha256: "9c370ef6a18b1c4b2f7f35944d644a56aa23576f23abee654cf73968de93f163" - url: "https://pub.dev" - source: hosted - version: "9.0.7" - permission_handler_platform_interface: - dependency: transitive - description: - name: permission_handler_platform_interface - sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" - url: "https://pub.dev" - source: hosted - version: "3.9.0" - permission_handler_windows: - dependency: transitive - description: - name: permission_handler_windows - sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b - url: "https://pub.dev" - source: hosted - version: "0.1.2" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" - url: "https://pub.dev" - source: hosted - version: "5.1.0" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a - url: "https://pub.dev" - source: hosted - version: "2.1.3" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 - url: "https://pub.dev" - source: hosted - version: "3.6.2" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" - protobuf: - dependency: transitive - description: - name: protobuf - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - provider: - dependency: transitive - description: - name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f - url: "https://pub.dev" - source: hosted - version: "6.0.5" - qr: - dependency: transitive - description: - name: qr - sha256: "5c4208b4dc0d55c3184d10d83ee0ded6212dc2b5e2ba17c5a0c0aab279128d21" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - qr_flutter: - dependency: "direct main" - description: - name: qr_flutter - sha256: c5c121c54cb6dd837b9b9d57eb7bc7ec6df4aee741032060c8833a678c80b87e - url: "https://pub.dev" - source: hosted - version: "4.0.0" - rive: - dependency: transitive - description: - name: rive - sha256: "22e3755b75f4ea4492d2fecf4fc2acf1c8d0073df39781d290a20cbfe74c3760" - url: "https://pub.dev" - source: hosted - version: "0.9.1" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.dev" - source: hosted - version: "0.27.7" - scrollable_positioned_list: - dependency: transitive - description: - name: scrollable_positioned_list - sha256: "9566352ab9ba05794ee6c8864f154afba5d36c5637d0e3e32c615ba4ceb92772" - url: "https://pub.dev" - source: hosted - version: "0.2.3" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - sha256: "76917b7d4b9526b2ba416808a7eb9fb2863c1a09cf63ec85f1453da240fa818a" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: "8e251f3c986002b65fed6396bce81f379fb63c27317d49743cf289fd0fd1ab97" - url: "https://pub.dev" - source: hosted - version: "2.0.14" - shared_preferences_ios: - dependency: transitive - description: - name: shared_preferences_ios - sha256: "585a14cefec7da8c9c2fb8cd283a3bb726b4155c0952afe6a0caaa7b2272de34" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: fbc3cd6826896b66a5f576b025e4f344f780c84ea7f8203097a353370607a2c8 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - sha256: "81b6a60b2d27020eb0fc41f4cebc91353047309967901a79ee8203e40c42ed46" - url: "https://pub.dev" - source: hosted - version: "2.0.5" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 - url: "https://pub.dev" - source: hosted - version: "2.0.4" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "07c274c2115d4d5e4280622abb09f0980e2c5b1fcdc98ae9f59a3bad5bfc1f26" - url: "https://pub.dev" - source: hosted - version: "2.1.2" - signature: - dependency: "direct main" - description: - name: signature - sha256: ad23383717dfa926204695ef6928ff513a77387be1b4a8c685099ce3ec35e5f8 - url: "https://pub.dev" - source: hosted - version: "5.3.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - sqflite: - dependency: transitive - description: - name: sqflite - sha256: "2b1697c7b78576fdc722c358f16f62171bd56e92dc13422d9e44be3fc446c276" - url: "https://pub.dev" - source: hosted - version: "2.2.2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: "0c21a187d645aa65da5be6997c0c713eed61e049158870ae2de157e6897067ab" - url: "https://pub.dev" - source: hosted - version: "2.4.0+2" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - synchronized: - dependency: transitive - description: - name: synchronized - sha256: "7b530acd9cb7c71b0019a1e7fa22c4105e675557a4400b6a401c71c5e0ade1ac" - url: "https://pub.dev" - source: hosted - version: "3.0.0+3" - system_info2: - dependency: "direct main" - description: - name: system_info2 - sha256: "90621f3ba586e1f268e38cc7951b172cd4d997e43dc1fbed12eb334c8a22a886" - url: "https://pub.dev" - source: hosted - version: "2.0.4" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dev" - source: hosted - version: "0.4.16" - toggle_switch: - dependency: "direct main" - description: - name: toggle_switch - sha256: "82c778c4bfe93af154a41e346ccd1d5b0cb6a50f8f187941412edd0a9bbf51ee" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - uuid: - dependency: transitive - description: - name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" - url: "https://pub.dev" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - win32: - dependency: transitive - description: - name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 - url: "https://pub.dev" - source: hosted - version: "3.1.3" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f" - url: "https://pub.dev" - source: hosted - version: "0.2.0+2" - xml: - dependency: transitive - description: - name: xml - sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb - url: "https://pub.dev" - source: hosted - version: "6.1.0" -sdks: - dart: ">=2.18.5 <3.0.0" - flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index f989e51..5cd2be5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,11 +62,20 @@ dependencies: equatable: ^2.0.5 package_info_plus: ^3.0.2 easy_app_installer: ^1.0.0 - path_provider: ^2.0.11 + path_provider: ^2.0.14 dio: ^4.0.6 cool_alert: ^1.1.0 permission_handler: ^10.2.0 expandable_group: ^0.0.8 + badges: ^3.0.2 + app_popup_menu: ^1.0.0 + modal_progress_hud_nsn: ^0.3.0 + searchfield: ^0.7.5 + filter_list: ^1.0.2 + simple_chips_input: ^1.0.0 + hive: ^2.0.5 + hive_flutter: ^1.1.0 + mask_text_input_formatter: ^2.4.0 dev_dependencies: flutter_test: @@ -78,6 +87,8 @@ dev_dependencies: # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 + build_runner: ^2.1.7 + hive_generator: ^1.1.2 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 48de52b..c1aa7e0 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,12 @@ #include "generated_plugin_registrant.h" +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ModalProgressHudNsnPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ModalProgressHudNsnPlugin")); PermissionHandlerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 0e69e40..2446653 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + modal_progress_hud_nsn permission_handler_windows )