diff --git a/app/assets/icon/ic_google.png b/app/assets/icon/ic_google.png new file mode 100644 index 00000000..b066f52e Binary files /dev/null and b/app/assets/icon/ic_google.png differ diff --git a/app/assets/images/ic_login.png b/app/assets/images/ic_login.png new file mode 100644 index 00000000..9dd675b3 Binary files /dev/null and b/app/assets/images/ic_login.png differ diff --git a/app/assets/images/ic_onboard_1.png b/app/assets/images/ic_onboard_1.png new file mode 100644 index 00000000..336f12b3 Binary files /dev/null and b/app/assets/images/ic_onboard_1.png differ diff --git a/app/assets/images/ic_onboard_2.png b/app/assets/images/ic_onboard_2.png new file mode 100644 index 00000000..14a60f7b Binary files /dev/null and b/app/assets/images/ic_onboard_2.png differ diff --git a/app/assets/images/ic_onboard_3.png b/app/assets/images/ic_onboard_3.png new file mode 100644 index 00000000..819ad700 Binary files /dev/null and b/app/assets/images/ic_onboard_3.png differ diff --git a/app/ios/Runner.xcodeproj/project.pbxproj b/app/ios/Runner.xcodeproj/project.pbxproj index 32397e96..b4a27b4a 100644 --- a/app/ios/Runner.xcodeproj/project.pbxproj +++ b/app/ios/Runner.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 0FFE518CAEBAD37D34FC8AA1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCDE8B9550C2FA926339506A /* Pods_Runner.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3145B37EC9670CE9D4963125 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DC47F7B4990611DFB7DF4E2 /* Pods_RunnerTests.framework */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 5D0A3E952B00EDE5008A0A74 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5D0A3E942B00EDE5008A0A74 /* GoogleService-Info.plist */; }; @@ -16,7 +17,11 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +<<<<<<< HEAD + A69B663EAD0FDAD46BCA1D96 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F70F8EEB6BCED7529E336A68 /* Pods_Runner.framework */; }; +======= E7499B58F8E767A2BE777F86 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42CC067AD269DE9DD5A9CECD /* Pods_RunnerTests.framework */; }; +>>>>>>> main /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -43,7 +48,11 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ +<<<<<<< HEAD + 0DC47F7B4990611DFB7DF4E2 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +======= 00DA7237EC5E1639B428DEEC /* 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 = ""; }; +>>>>>>> main 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 = ""; }; 1AD4FBFB4F6442CA32A31A62 /* 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 = ""; }; @@ -51,12 +60,23 @@ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; +<<<<<<< HEAD + 40DB1EF5EB63129F38FAC2C2 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 442D3DE505A04C01D8D9BBC6 /* 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 = ""; }; + 51154218C02FC3653B50ADBF /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 59D2B83FA1CF35D1FB69A543 /* 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 = ""; }; + 5D0A3E942B00EDE5008A0A74 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; 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 = ""; }; + 7983E82B71C22A1553702ADC /* 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 = ""; }; +======= 42CC067AD269DE9DD5A9CECD /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54ED3700E7BFA509D831AE15 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 5D0A3E942B00EDE5008A0A74 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; 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 = ""; }; 76E6D5E674F0B996969AE18D /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; +>>>>>>> main 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9575A7EBA22A63F872EB57FF /* 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 = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; @@ -66,7 +86,12 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +<<<<<<< HEAD + C583D477E54D9A3AAF62E3D4 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + F70F8EEB6BCED7529E336A68 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +======= DCDE8B9550C2FA926339506A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +>>>>>>> main /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,7 +107,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( +<<<<<<< HEAD + A69B663EAD0FDAD46BCA1D96 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CF6D52A3382C8B59F47AB3B8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3145B37EC9670CE9D4963125 /* Pods_RunnerTests.framework in Frameworks */, +======= 0FFE518CAEBAD37D34FC8AA1 /* Pods_Runner.framework in Frameworks */, +>>>>>>> main ); runOnlyForDeploymentPostprocessing = 0; }; @@ -119,6 +156,29 @@ path = RunnerTests; sourceTree = ""; }; + 49ABF78958ECB85B0D420E7F /* Frameworks */ = { + isa = PBXGroup; + children = ( + F70F8EEB6BCED7529E336A68 /* Pods_Runner.framework */, + 0DC47F7B4990611DFB7DF4E2 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8E19E9CDF49D11CB9E0EA6F3 /* Pods */ = { + isa = PBXGroup; + children = ( + 7983E82B71C22A1553702ADC /* Pods-Runner.debug.xcconfig */, + 59D2B83FA1CF35D1FB69A543 /* Pods-Runner.release.xcconfig */, + 442D3DE505A04C01D8D9BBC6 /* Pods-Runner.profile.xcconfig */, + 40DB1EF5EB63129F38FAC2C2 /* Pods-RunnerTests.debug.xcconfig */, + 51154218C02FC3653B50ADBF /* Pods-RunnerTests.release.xcconfig */, + C583D477E54D9A3AAF62E3D4 /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -137,8 +197,13 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, +<<<<<<< HEAD + 8E19E9CDF49D11CB9E0EA6F3 /* Pods */, + 49ABF78958ECB85B0D420E7F /* Frameworks */, +======= 29342FF3574560C2359DD14C /* Pods */, 1D61508B21999149F00851FE /* Frameworks */, +>>>>>>> main ); sourceTree = ""; }; @@ -174,10 +239,17 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( +<<<<<<< HEAD + 1153DD233293A7219291340F /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + CF6D52A3382C8B59F47AB3B8 /* Frameworks */, +======= 339E7C3ACD284CFEB4066CBE /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, 6209795B903CD1AE58C86330 /* Frameworks */, +>>>>>>> main ); buildRules = ( ); @@ -193,14 +265,22 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( +<<<<<<< HEAD + DA12135C7CBCF8A50F751670 /* [CP] Check Pods Manifest.lock */, +======= 323B978BFF923700AC884F61 /* [CP] Check Pods Manifest.lock */, +>>>>>>> main 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, +<<<<<<< HEAD + E2815BAD59CB78458208729D /* [CP] Embed Pods Frameworks */, +======= C55559B376FF4972972B6E34 /* [CP] Embed Pods Frameworks */, +>>>>>>> main ); buildRules = ( ); @@ -272,6 +352,9 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ +<<<<<<< HEAD + 1153DD233293A7219291340F /* [CP] Check Pods Manifest.lock */ = { +======= 323B978BFF923700AC884F61 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -295,6 +378,7 @@ showEnvVarsInLog = 0; }; 339E7C3ACD284CFEB4066CBE /* [CP] Check Pods Manifest.lock */ = { +>>>>>>> main isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -347,7 +431,33 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; +<<<<<<< HEAD + DA12135C7CBCF8A50F751670 /* [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; + }; + E2815BAD59CB78458208729D /* [CP] Embed Pods Frameworks */ = { +======= C55559B376FF4972972B6E34 /* [CP] Embed Pods Frameworks */ = { +>>>>>>> main isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -489,7 +599,11 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; +<<<<<<< HEAD + baseConfigurationReference = 40DB1EF5EB63129F38FAC2C2 /* Pods-RunnerTests.debug.xcconfig */; +======= baseConfigurationReference = 76E6D5E674F0B996969AE18D /* Pods-RunnerTests.debug.xcconfig */; +>>>>>>> main buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -507,7 +621,11 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; +<<<<<<< HEAD + baseConfigurationReference = 51154218C02FC3653B50ADBF /* Pods-RunnerTests.release.xcconfig */; +======= baseConfigurationReference = 258C70F55133C40067AD15A9 /* Pods-RunnerTests.release.xcconfig */; +>>>>>>> main buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -523,7 +641,11 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; +<<<<<<< HEAD + baseConfigurationReference = C583D477E54D9A3AAF62E3D4 /* Pods-RunnerTests.profile.xcconfig */; +======= baseConfigurationReference = 54ED3700E7BFA509D831AE15 /* Pods-RunnerTests.profile.xcconfig */; +>>>>>>> main buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/app/lib/core/bases/widgets/atoms/button.dart b/app/lib/core/bases/widgets/atoms/button.dart index 932e057b..30aaf0e1 100644 --- a/app/lib/core/bases/widgets/atoms/button.dart +++ b/app/lib/core/bases/widgets/atoms/button.dart @@ -16,6 +16,7 @@ class Button extends StatelessWidget { final Color customButtonColor; final Color customTextColor; final Color customBorderColor; + final String icon; final double borderRadius; const Button({ @@ -29,8 +30,9 @@ class Button extends StatelessWidget { this.fontSize = 16, this.customButtonColor = Colors.transparent, this.customTextColor = BaseColors.black, - this.borderRadius = 16, this.customBorderColor = Colors.transparent, + this.icon = '', + this.borderRadius = 16, super.key, }); @@ -77,15 +79,25 @@ class Button extends StatelessWidget { border: Border.all(color: customBorderColor), ), width: double.infinity, - child: AutoSizeText( - text, - textAlign: TextAlign.center, - style: TextStyle( - color: textColor, - fontSize: fontSize, - fontWeight: FontWeight.w600, - ), - minFontSize: 2, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (icon != '') + Image.asset( + icon, + ), + SizedBox(width: icon != '' ? 9.0 : 0), + AutoSizeText( + text, + textAlign: TextAlign.center, + style: TextStyle( + color: textColor, + fontSize: fontSize, + fontWeight: FontWeight.w600, + ), + minFontSize: 2, + ), + ], ), ), ), diff --git a/app/lib/core/constants/assets.dart b/app/lib/core/constants/assets.dart index 49c311de..f2a37f0f 100644 --- a/app/lib/core/constants/assets.dart +++ b/app/lib/core/constants/assets.dart @@ -4,6 +4,8 @@ class Assets { static const flagDir = 'assets/images/flags/'; static const icon = 'assets/icon/icon.png'; static const logo = 'assets/images/logo.png'; + static const iconGoogle = 'assets/icon/ic_google.png'; + static const iconLogin = 'assets/images/ic_login.png'; static const bebrasPandaiText = 'assets/images/bebras-banner.png'; static const bLogo = 'assets/images/b-logo.webp'; static const studyBackground = 'assets/images/study-background.jpg'; diff --git a/app/lib/core/constants/get_started.dart b/app/lib/core/constants/get_started.dart new file mode 100644 index 00000000..1df87168 --- /dev/null +++ b/app/lib/core/constants/get_started.dart @@ -0,0 +1,23 @@ +List> getStartedList = [ + { + 'image': 'assets/images/ic_onboard_1.png', + 'title': 'Temukan Dunia Pengetahuanmu!', + 'description': + 'Selamat datang di Bebras Pandai, tempat di mana kamu dapat membuka ' + 'pintu menuju pengetahuan yang tak terbatas.' + }, + { + 'image': 'assets/images/ic_onboard_2.png', + 'title': 'Pintu Gerbang Kecerdasan Terbuka', + 'description': + 'Setiap langkah akan membawa kita lebih dekat dengan pengetahuan ' + 'yang tak terbatas.' + }, + { + 'image': 'assets/images/ic_onboard_3.png', + 'title': 'Temukan Keajaiban!', + 'description': + 'Setiap momen belajar menjadi petualangan yang penuh keceriaan. ' + 'Ayo bergabung dalam dan nikmati manfaat yang luar biasa' + } +]; diff --git a/app/lib/core/theme/base_colors.dart b/app/lib/core/theme/base_colors.dart index c5864376..5e186629 100644 --- a/app/lib/core/theme/base_colors.dart +++ b/app/lib/core/theme/base_colors.dart @@ -26,4 +26,7 @@ class BaseColors { static const Color yellow = Color(0xFFfeb451); static const Color asparagus = Color(0xFF6da34d); static const Color grey = Colors.grey; + static const Color brightBlue = Color(0xFF1BB8E1); + static const Color greyCustome = Color(0xFFD9D9D9); + } diff --git a/app/lib/features/authentication/signin/presentation/pages/_pages.dart b/app/lib/features/authentication/signin/presentation/pages/_pages.dart index c3065f51..833d5a1d 100644 --- a/app/lib/features/authentication/signin/presentation/pages/_pages.dart +++ b/app/lib/features/authentication/signin/presentation/pages/_pages.dart @@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart'; import '../../../../../core/bases/enum/button_type.dart'; import '../../../../../core/bases/widgets/atoms/button.dart'; import '../../../../../core/constants/assets.dart'; +import '../../../../../core/theme/base_colors.dart'; import '../../../../../services/di.dart'; import '../bloc/sign_in_bloc.dart'; diff --git a/app/lib/features/authentication/signin/presentation/pages/sign_in_page.dart b/app/lib/features/authentication/signin/presentation/pages/sign_in_page.dart index 149be5ba..a46ca898 100644 --- a/app/lib/features/authentication/signin/presentation/pages/sign_in_page.dart +++ b/app/lib/features/authentication/signin/presentation/pages/sign_in_page.dart @@ -25,28 +25,29 @@ class _LoginPageState extends State { child: Stack( children: [ Image.asset( - Assets.studyBackground, + Assets.iconLogin, fit: BoxFit.cover, - height: size.height * 0.45, + height: size.height * 0.30, + width: double.infinity, ), Align( alignment: Alignment.bottomCenter, child: Container( padding: const EdgeInsets.all(32), - height: size.height * 0.6, + height: size.height * 0.55, width: size.width, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(32), - color: Colors.white, - ), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(32), + // color: Colors.white, + // ), child: Column( children: [ - Image.asset( - Assets.bebrasPandaiText, - ), - const SizedBox( - height: 100, - ), + // Image.asset( + // Assets.bebrasPandaiText, + // ), + // const SizedBox( + // height: 100, + // ), const Text( 'Selamat Datang di Aplikasi Bebras Pandai!', textAlign: TextAlign.center, @@ -62,7 +63,7 @@ class _LoginPageState extends State { 'Yuk cari tahu seberapa tajam logikamu!', ), const SizedBox( - height: 24, + height: 50, ), BlocConsumer( bloc: _signInBloc, @@ -79,7 +80,9 @@ class _LoginPageState extends State { width: 200, child: Button( text: 'Login with Google', - buttonType: ButtonType.primary, + buttonType: ButtonType.secondary, + customBorderColor: BaseColors.black, + icon: Assets.iconGoogle, onTap: () { if (state is! SignInLoadingState) { _signInBloc.add( diff --git a/app/lib/features/main/presentation/pages/setting_page.dart b/app/lib/features/main/presentation/pages/setting_page.dart index 6a64d58f..4857d089 100644 --- a/app/lib/features/main/presentation/pages/setting_page.dart +++ b/app/lib/features/main/presentation/pages/setting_page.dart @@ -116,7 +116,7 @@ class _SettingPageState extends State { onTap: () async { await FirebaseAuth.instance.signOut(); await GoogleSignIn().signOut(); - context.go('/onboarding'); + context.go('/login'); }, customButtonColor: Colors.red.shade900, customTextColor: Colors.white, diff --git a/app/lib/features/onboarding/presentation/pages/_pages.dart b/app/lib/features/onboarding/presentation/pages/_pages.dart index 6341c7fd..bc19d889 100644 --- a/app/lib/features/onboarding/presentation/pages/_pages.dart +++ b/app/lib/features/onboarding/presentation/pages/_pages.dart @@ -2,11 +2,16 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:page_view_indicators/circle_page_indicator.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../../../../core/bases/widgets/atoms/button.dart'; import '../../../../core/constants/assets.dart'; +import '../../../../core/constants/get_started.dart'; +import '../../../../core/theme/base_colors.dart'; +import '../../../../core/theme/font_theme.dart'; import '../bloc/user_initialization_bloc.dart'; -part 'splash_screen.dart'; part 'onboarding_page.dart'; +part 'splash_screen.dart'; part 'update_dialog.dart'; diff --git a/app/lib/features/onboarding/presentation/pages/onboarding_page.dart b/app/lib/features/onboarding/presentation/pages/onboarding_page.dart index fa1e3ffb..455c88df 100644 --- a/app/lib/features/onboarding/presentation/pages/onboarding_page.dart +++ b/app/lib/features/onboarding/presentation/pages/onboarding_page.dart @@ -8,10 +8,142 @@ class OnboardingPage extends StatefulWidget { } class _OnboardingPageState extends State { - final nama = 'dummy'; + + int selectedIndex = 0; + void setPage(int index) { + selectedIndex = index; + } + final PageController pageController = PageController(); + final currentPageNotifier = ValueNotifier(0); @override Widget build(BuildContext context) { - return const Placeholder(); + return Scaffold( + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: PageView.builder( + controller: pageController, + itemCount: getStartedList.length, + itemBuilder: (BuildContext context, int index) { + final item = getStartedList[index]; + return buildOnboardPage( + index, + item['image'] as String, + item['title'] as String, + item['description'] as String + ); + }, + onPageChanged: (int index) { + currentPageNotifier.value = index; + setPage(index); + } + ), + ), + ], + ), + ), + ); + } + + Widget buildOnboardPage( + int index, + String image, + String title, + String description + ) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 40), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${index + 1}/${getStartedList.length}', + style: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold + ), + ), + buildIndicator(), + ], + ), + + Visibility( + visible: image.isNotEmpty, + child: Expanded( + flex: 2, + child: Container( + alignment: Alignment.bottomCenter, + child: Center( + child: Image.asset( + image, + height: 200, + width: 200, + ), + ), + ), + ), + ), + Expanded( + child: Center( + child: Column( + children: [ + Text( + title, + style: FontTheme.blackSubtitleBold(), + textAlign: TextAlign.center, + ), + const SizedBox(height: 24), + Text( + description, + style: FontTheme.greyNormal14(), + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + + FractionallySizedBox( + widthFactor: 0.6, // Set the width to 80% + child: Button( + onTap: () async { + if ( selectedIndex != 2 ) { + await pageController.nextPage( + duration: const Duration(milliseconds: 300), + curve: Curves.easeIn, + ); + } else { + await context.push('/login'); + } + }, + customButtonColor: BaseColors.brightBlue, + customTextColor: Colors.white, + text: (index != 2 ? 'Selanjutnya' : 'Masuk'), + ), + ), + ], + ), + ); +} + + + Widget buildIndicator() { + return Container( + padding: const EdgeInsets.only(top: 5), + child: CirclePageIndicator( + dotColor: BaseColors.greyCustome, + selectedDotColor: BaseColors.brightBlue, + itemCount: getStartedList.length, + currentPageNotifier: currentPageNotifier, + ), + ); } } diff --git a/app/lib/services/router_service.dart b/app/lib/services/router_service.dart index 7b8a330c..f47541a6 100644 --- a/app/lib/services/router_service.dart +++ b/app/lib/services/router_service.dart @@ -23,6 +23,10 @@ GoRouter router = GoRouter( ), GoRoute( path: '/onboarding', + builder: (context, state) => const OnboardingPage(), + ), + GoRoute( + path: '/login', builder: (context, state) => const LoginPage(), ), GoRoute( diff --git a/app/pubspec.lock b/app/pubspec.lock index 00c0289b..1dce1f7a 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -1000,6 +1000,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + page_view_indicators: + dependency: "direct main" + description: + name: page_view_indicators + sha256: d2ebf6c26d1b065f137e88a2b88181dea6b96d7a34abe9a237fbf214888d0f3f + url: "https://pub.dev" + source: hosted + version: "2.0.0" path: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index c9cb7207..ddffc519 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -2,7 +2,7 @@ name: bebras_pandai description: Aplikasi belajar Computational Thinking oleh bebras.org # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+13 environment: - sdk: '>=3.0.5 <4.0.0' + sdk: ">=3.0.5 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -65,6 +65,7 @@ dependencies: printing: ^5.11.0 cached_network_image: ^3.3.0 firebase_messaging: ^14.7.3 + page_view_indicators: ^2.0.0 carousel_slider: ^4.2.1 font_awesome_flutter: ^10.6.0 cached_network_svg_image: ^0.0.7 @@ -89,8 +90,6 @@ permission: # The following section is specific to Flutter packages. flutter: - - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class.