diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 9cbac3c..9fe0770 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -29,6 +29,8 @@ + diff --git a/assets/font/Poppins-Bold.ttf b/assets/font/Poppins-Bold.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/assets/font/Poppins-Bold.ttf differ diff --git a/assets/font/Poppins-Medium.ttf b/assets/font/Poppins-Medium.ttf new file mode 100644 index 0000000..6bcdcc2 Binary files /dev/null and b/assets/font/Poppins-Medium.ttf differ diff --git a/assets/font/Poppins-Regular.ttf b/assets/font/Poppins-Regular.ttf new file mode 100644 index 0000000..9f0c71b Binary files /dev/null and b/assets/font/Poppins-Regular.ttf differ diff --git a/assets/img/Activity_tab.svg b/assets/img/Activity_tab.svg new file mode 100644 index 0000000..d0304db --- /dev/null +++ b/assets/img/Activity_tab.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/img/Activity_tab_select.svg b/assets/img/Activity_tab_select.svg new file mode 100644 index 0000000..2db3444 --- /dev/null +++ b/assets/img/Activity_tab_select.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/img/Camera_tab.svg b/assets/img/Camera_tab.svg new file mode 100644 index 0000000..96879b2 --- /dev/null +++ b/assets/img/Camera_tab.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/img/Camera_tab_select.svg b/assets/img/Camera_tab_select.svg new file mode 100644 index 0000000..0829dbf --- /dev/null +++ b/assets/img/Camera_tab_select.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/img/Home_tab.svg b/assets/img/Home_tab.svg new file mode 100644 index 0000000..92f7447 --- /dev/null +++ b/assets/img/Home_tab.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/img/Home_tab_select.svg b/assets/img/Home_tab_select.svg new file mode 100644 index 0000000..0845568 --- /dev/null +++ b/assets/img/Home_tab_select.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/img/Profile_tab.svg b/assets/img/Profile_tab.svg new file mode 100644 index 0000000..d35c124 --- /dev/null +++ b/assets/img/Profile_tab.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/img/Profile_tab_select.svg b/assets/img/Profile_tab_select.svg new file mode 100644 index 0000000..cdb3acc --- /dev/null +++ b/assets/img/Profile_tab_select.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/img/Search_tab.svg b/assets/img/Search_tab.svg new file mode 100644 index 0000000..ba4aefd --- /dev/null +++ b/assets/img/Search_tab.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/img/SleepGraph.png b/assets/img/SleepGraph.png new file mode 100644 index 0000000..aa4bda1 Binary files /dev/null and b/assets/img/SleepGraph.png differ diff --git a/assets/img/bg_dots.png b/assets/img/bg_dots.png new file mode 100644 index 0000000..eca6f23 Binary files /dev/null and b/assets/img/bg_dots.png differ diff --git a/assets/img/black_btn.png b/assets/img/black_btn.png new file mode 100644 index 0000000..c8d80e1 Binary files /dev/null and b/assets/img/black_btn.png differ diff --git a/assets/img/email.svg b/assets/img/email.svg new file mode 100644 index 0000000..7cccbd9 --- /dev/null +++ b/assets/img/email.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/img/google.png b/assets/img/google.png new file mode 100644 index 0000000..0a765fa Binary files /dev/null and b/assets/img/google.png differ diff --git a/assets/img/lock.svg b/assets/img/lock.svg new file mode 100644 index 0000000..e96154f --- /dev/null +++ b/assets/img/lock.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/img/logoSM.svg b/assets/img/logoSM.svg new file mode 100644 index 0000000..07707ba --- /dev/null +++ b/assets/img/logoSM.svg @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/more_btn.png b/assets/img/more_btn.png new file mode 100644 index 0000000..107a1e8 Binary files /dev/null and b/assets/img/more_btn.png differ diff --git a/assets/img/notification_active.png b/assets/img/notification_active.png new file mode 100644 index 0000000..a87658d Binary files /dev/null and b/assets/img/notification_active.png differ diff --git a/assets/img/on_1.svg b/assets/img/on_1.svg new file mode 100644 index 0000000..076cf1b --- /dev/null +++ b/assets/img/on_1.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/on_2.svg b/assets/img/on_2.svg new file mode 100644 index 0000000..fce3f8f --- /dev/null +++ b/assets/img/on_2.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/on_3.svg b/assets/img/on_3.svg new file mode 100644 index 0000000..30dcb79 --- /dev/null +++ b/assets/img/on_3.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/img/p_achi.png b/assets/img/p_achi.png new file mode 100644 index 0000000..556d0b1 Binary files /dev/null and b/assets/img/p_achi.png differ diff --git a/assets/img/p_activity.png b/assets/img/p_activity.png new file mode 100644 index 0000000..418e7a1 Binary files /dev/null and b/assets/img/p_activity.png differ diff --git a/assets/img/p_contact.png b/assets/img/p_contact.png new file mode 100644 index 0000000..1243afc Binary files /dev/null and b/assets/img/p_contact.png differ diff --git a/assets/img/p_next.png b/assets/img/p_next.png new file mode 100644 index 0000000..7898515 Binary files /dev/null and b/assets/img/p_next.png differ diff --git a/assets/img/p_notification.png b/assets/img/p_notification.png new file mode 100644 index 0000000..ec50c03 Binary files /dev/null and b/assets/img/p_notification.png differ diff --git a/assets/img/p_personal.png b/assets/img/p_personal.png new file mode 100644 index 0000000..26333e5 Binary files /dev/null and b/assets/img/p_personal.png differ diff --git a/assets/img/p_privacy.png b/assets/img/p_privacy.png new file mode 100644 index 0000000..3416e78 Binary files /dev/null and b/assets/img/p_privacy.png differ diff --git a/assets/img/p_setting.png b/assets/img/p_setting.png new file mode 100644 index 0000000..9ff665c Binary files /dev/null and b/assets/img/p_setting.png differ diff --git a/assets/img/p_workout.png b/assets/img/p_workout.png new file mode 100644 index 0000000..1107148 Binary files /dev/null and b/assets/img/p_workout.png differ diff --git a/assets/img/show_password.svg b/assets/img/show_password.svg new file mode 100644 index 0000000..fda0dff --- /dev/null +++ b/assets/img/show_password.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/img/sleep_graph.png b/assets/img/sleep_graph.png new file mode 100644 index 0000000..1a60324 Binary files /dev/null and b/assets/img/sleep_graph.png differ diff --git a/assets/img/sub_menu.svg b/assets/img/sub_menu.svg new file mode 100644 index 0000000..1a23749 --- /dev/null +++ b/assets/img/sub_menu.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/img/suunto.png b/assets/img/suunto.png new file mode 100644 index 0000000..42c1293 Binary files /dev/null and b/assets/img/suunto.png differ diff --git a/assets/img/u1.png b/assets/img/u1.png new file mode 100644 index 0000000..6c320c9 Binary files /dev/null and b/assets/img/u1.png differ diff --git a/assets/img/user_text.svg b/assets/img/user_text.svg new file mode 100644 index 0000000..513a01c --- /dev/null +++ b/assets/img/user_text.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/img/workout1.svg b/assets/img/workout1.svg new file mode 100644 index 0000000..19998e4 --- /dev/null +++ b/assets/img/workout1.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..fdcc671 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 7c925b2..75c36c7 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -7,13 +7,15 @@ objects = { /* Begin PBXBuildFile section */ + 090A4C6C8906E11919410FA6 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F76E532CB27CF8D8887ECB6E /* Pods_RunnerTests.framework */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 36896C85B5E41F2885C5D932 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C735E611E261E1BF013228AF /* 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 */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,9 +42,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 09348B77084D874324AEC997 /* 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 = ""; }; 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 = ""; }; + 32B6F252772E4C3A1E8B239E /* 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 = ""; }; + 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 = ""; }; + 6740291438833939DFD9003B /* 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 = ""; }; 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 = ""; }; @@ -53,8 +60,11 @@ 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 = ""; }; - 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; }; + A8F045B4CEA19433140475EB /* 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 = ""; }; + C735E611E261E1BF013228AF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E76986DA08EDD70E087193D6 /* 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 = ""; }; + E91D209A9470765F2FEBB894 /* 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 = ""; }; + F76E532CB27CF8D8887ECB6E /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -62,21 +72,28 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 36896C85B5E41F2885C5D932 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C20D5A983965DE7EB2050FCA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 090A4C6C8906E11919410FA6 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { + 0A4AC663BEDD83585E36DE85 /* Frameworks */ = { isa = PBXGroup; children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, + C735E611E261E1BF013228AF /* Pods_Runner.framework */, + F76E532CB27CF8D8887ECB6E /* Pods_RunnerTests.framework */, ); - name = Flutter; + name = Frameworks; sourceTree = ""; }; 331C8082294A63A400263BE5 /* RunnerTests */ = { @@ -87,6 +104,17 @@ path = RunnerTests; sourceTree = ""; }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( @@ -94,6 +122,8 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + BAB296CAADE49C59AA4EDFA3 /* Pods */, + 0A4AC663BEDD83585E36DE85 /* Frameworks */, ); sourceTree = ""; }; @@ -121,6 +151,19 @@ path = Runner; sourceTree = ""; }; + BAB296CAADE49C59AA4EDFA3 /* Pods */ = { + isa = PBXGroup; + children = ( + 09348B77084D874324AEC997 /* Pods-Runner.debug.xcconfig */, + E76986DA08EDD70E087193D6 /* Pods-Runner.release.xcconfig */, + A8F045B4CEA19433140475EB /* Pods-Runner.profile.xcconfig */, + E91D209A9470765F2FEBB894 /* Pods-RunnerTests.debug.xcconfig */, + 6740291438833939DFD9003B /* Pods-RunnerTests.release.xcconfig */, + 32B6F252772E4C3A1E8B239E /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -128,9 +171,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 22EFA3186238D5A133183F0E /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, - 331C807E294A63A400263BE5 /* Frameworks */, 331C807F294A63A400263BE5 /* Resources */, + C20D5A983965DE7EB2050FCA /* Frameworks */, ); buildRules = ( ); @@ -146,12 +190,15 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 249602BB0C79B391B98FDF9B /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 89C3C3975243E680DCEA2427 /* [CP] Embed Pods Frameworks */, + FC691EB0E8FFD75241B9C7A8 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -223,6 +270,50 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 22EFA3186238D5A133183F0E /* [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-RunnerTests-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; + }; + 249602BB0C79B391B98FDF9B /* [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; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -239,6 +330,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 89C3C3975243E680DCEA2427 /* [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; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -254,6 +362,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + FC691EB0E8FFD75241B9C7A8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -361,6 +486,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = C9862MYS3A; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -377,7 +503,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = E91D209A9470765F2FEBB894 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -395,7 +521,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 6740291438833939DFD9003B /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -411,7 +537,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 32B6F252772E4C3A1E8B239E /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -539,6 +665,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = C9862MYS3A; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -561,6 +688,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = C9862MYS3A; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( 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/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4..68e99d6 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,5 +1,6 @@ import UIKit import Flutter +import GoogleMaps @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -7,7 +8,8 @@ import Flutter _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + GMSServices.provideAPIKey("AIzaSyD2Jgh9NXhtKaH8qRyGfkCeMDusBJ4xcRY") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } -} +} \ No newline at end of file diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard index f3c2851..1aec8f3 100644 --- a/ios/Runner/Base.lproj/Main.storyboard +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -1,8 +1,10 @@ - - + + + - + + @@ -14,13 +16,14 @@ - + - + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 303dbea..dd50948 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,10 @@ + NSLocationAlwaysAndWhenInUseUsageDescription + Utilisé pour afficher votre emplacement actuel sur la carte. + NSLocationWhenInUseUsageDescription + Utilisé pour afficher votre emplacement actuel sur la carte. CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName diff --git a/lib/Modele/Mds/DeviceConnectionStatus.dart b/lib/Modele/Mds/DeviceConnectionStatus.dart index b2a97d0..8443751 100644 --- a/lib/Modele/Mds/DeviceConnectionStatus.dart +++ b/lib/Modele/Mds/DeviceConnectionStatus.dart @@ -1,5 +1,6 @@ /* enum DeviceConnectionStatus { NOT_CONNECTED, CONNECTING, CONNECTED } +enum DeviceConnectionStatus { NOT_CONNECTED, CONNECTING, CONNECTED } extension DeviceConnectionStatusExtenstion on DeviceConnectionStatus { String get statusName { diff --git a/lib/Modele/Mds/DeviceModel.dart b/lib/Modele/Mds/DeviceModel.dart index 8ad30be..a9a9363 100644 --- a/lib/Modele/Mds/DeviceModel.dart +++ b/lib/Modele/Mds/DeviceModel.dart @@ -18,4 +18,5 @@ class DeviceModel extends ChangeNotifier { notifyListeners(); } } +*/ */ \ No newline at end of file diff --git a/lib/View/activity/activity.dart b/lib/View/activity/activity.dart new file mode 100644 index 0000000..8f46e03 --- /dev/null +++ b/lib/View/activity/activity.dart @@ -0,0 +1,28 @@ +import 'package:smartfit_app_mobile/common_widget/steps.dart'; +import 'package:smartfit_app_mobile/common_widget/dates.dart'; +import 'package:smartfit_app_mobile/common_widget/graph.dart'; +import 'package:smartfit_app_mobile/common_widget/info.dart' hide Stats; +import 'package:smartfit_app_mobile/common_widget/stats.dart'; +import 'package:flutter/material.dart'; + +class Activity extends StatelessWidget { + const Activity({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: Column( + children: const [ + Divider(height: 80), + Steps(), + Graph(), + Info(), + Divider(height: 30), + Stats(), + SizedBox(height: 30), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/View/home/activity_tracker.dart b/lib/View/home/activity_tracker.dart new file mode 100644 index 0000000..d87d351 --- /dev/null +++ b/lib/View/home/activity_tracker.dart @@ -0,0 +1,431 @@ +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../common/colo_extension.dart'; +import '../../common_widget/latest_activity_row.dart'; +import '../../common_widget/today_target_cell.dart'; + +class ActivityTrackerView extends StatefulWidget { + const ActivityTrackerView({super.key}); + + @override + State createState() => _ActivityTrackerViewState(); +} + +class _ActivityTrackerViewState extends State { + int touchedIndex = -1; + + List latestArr = [ + { + "image": "assets/img/workout1.svg", + "title": "Drinking 300ml Water", + "time": "About 1 minutes ago" + }, + { + "image": "assets/img/workout1.svg", + "title": "Eat Snack (Fitbar)", + "time": "About 3 hours ago" + }, + ]; + + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + return Scaffold( + appBar: AppBar( + backgroundColor: TColor.white, + centerTitle: true, + elevation: 0, + leading: InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Container( + margin: const EdgeInsets.all(8), + height: 40, + width: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.lightGray, + borderRadius: BorderRadius.circular(10)), + child: Image.asset( + "assets/img/black_btn.png", + width: 15, + height: 15, + fit: BoxFit.contain, + ), + ), + ), + title: Text( + "Suivi d'activité", + style: TextStyle( + color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), + ), + actions: [ + InkWell( + onTap: () {}, + child: Container( + margin: const EdgeInsets.all(8), + height: 40, + width: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.lightGray, + borderRadius: BorderRadius.circular(10)), + child: Image.asset( + "assets/img/more_btn.png", + width: 15, + height: 15, + fit: BoxFit.contain, + ), + ), + ) + ], + ), + backgroundColor: TColor.white, + body: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 25), + child: Column( + children: [ + Container( + padding: + const EdgeInsets.symmetric(vertical: 15, horizontal: 15), + decoration: BoxDecoration( + gradient: LinearGradient(colors: [ + TColor.primaryColor2.withOpacity(0.3), + TColor.primaryColor1.withOpacity(0.3) + ]), + borderRadius: BorderRadius.circular(15), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Objectif d'aujourd'hui", + style: TextStyle( + color: TColor.black, + fontSize: 14, + fontWeight: FontWeight.w700), + ), + SizedBox( + width: 30, + height: 30, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: TColor.primaryG, + ), + borderRadius: BorderRadius.circular(10), + ), + child: MaterialButton( + onPressed: () {}, + padding: EdgeInsets.zero, + height: 30, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25)), + textColor: TColor.primaryColor1, + minWidth: double.maxFinite, + elevation: 0, + color: Colors.transparent, + child: const Icon( + Icons.add, + color: Colors.white, + size: 15, + )), + ), + ) + ], + ), + const SizedBox( + height: 15, + ), + const Row( + children: [ + Expanded( + child: TodayTargetCell( + icon: "assets/img/workout1.svg", + value: "800", + title: "Calories", + ), + ), + SizedBox( + width: 15, + ), + Expanded( + child: TodayTargetCell( + icon: "assets/img/workout1.svg", + value: "2400", + title: "Nombre pas", + ), + ), + ], + ) + ], + ), + ), + SizedBox( + height: media.width * 0.1, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Activité journalière", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700), + ), + Container( + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + gradient: LinearGradient(colors: TColor.primaryG), + borderRadius: BorderRadius.circular(15), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + items: ["Semaine", "Mois"] + .map((name) => DropdownMenuItem( + value: name, + child: Text( + name, + style: TextStyle( + color: TColor.gray, fontSize: 14), + ), + )) + .toList(), + onChanged: (value) {}, + icon: Icon(Icons.expand_more, color: TColor.white), + hint: Text( + "Semaine", + textAlign: TextAlign.center, + style: TextStyle(color: TColor.white, fontSize: 12), + ), + ), + )), + ], + ), + + SizedBox( + height: media.width * 0.05, + ), + + Container( + height: media.width * 0.5, + padding: const EdgeInsets.symmetric(vertical: 15 , horizontal: 0), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 3) + ]), + child: BarChart( + + BarChartData( + barTouchData: BarTouchData( + touchTooltipData: BarTouchTooltipData( + tooltipBgColor: Colors.grey, + tooltipHorizontalAlignment: FLHorizontalAlignment.right, + tooltipMargin: 10, + getTooltipItem: (group, groupIndex, rod, rodIndex) { + String weekDay; + switch (group.x) { + case 0: + weekDay = 'Monday'; + break; + case 1: + weekDay = 'Tuesday'; + break; + case 2: + weekDay = 'Wednesday'; + break; + case 3: + weekDay = 'Thursday'; + break; + case 4: + weekDay = 'Friday'; + break; + case 5: + weekDay = 'Saturday'; + break; + case 6: + weekDay = 'Sunday'; + break; + default: + throw Error(); + } + return BarTooltipItem( + '$weekDay\n', + const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 14, + ), + children: [ + TextSpan( + text: (rod.toY - 1).toString(), + style: TextStyle( + color: TColor.white, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ); + }, + ), + touchCallback: (FlTouchEvent event, barTouchResponse) { + setState(() { + if (!event.isInterestedForInteractions || + barTouchResponse == null || + barTouchResponse.spot == null) { + touchedIndex = -1; + return; + } + touchedIndex = + barTouchResponse.spot!.touchedBarGroupIndex; + }); + }, + ), + titlesData: FlTitlesData( + show: true, + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: getTitles, + reservedSize: 38, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: false, + ), + ), + ), + borderData: FlBorderData( + show: false, + ), + barGroups: showingGroups(), + gridData: FlGridData(show: false), + ) + + ), + ), + + SizedBox( + height: media.width * 0.05, + ), + + SizedBox( + height: media.width * 0.1, + ), + ], + ), + ), + ), + ); + } + + Widget getTitles(double value, TitleMeta meta) { + var style = TextStyle( + color: TColor.gray, + fontWeight: FontWeight.w500, + fontSize: 12, + ); + Widget text; + switch (value.toInt()) { + case 0: + text = Text('Dim', style: style); + break; + case 1: + text = Text('Lun', style: style); + break; + case 2: + text = Text('Mar', style: style); + break; + case 3: + text = Text('Mer', style: style); + break; + case 4: + text = Text('Jeu', style: style); + break; + case 5: + text = Text('Ven', style: style); + break; + case 6: + text = Text('Sam', style: style); + break; + default: + text = Text('', style: style); + break; + } + return SideTitleWidget( + axisSide: meta.axisSide, + space: 16, + child: text, + ); + } + List showingGroups() => List.generate(7, (i) { + switch (i) { + case 0: + return makeGroupData(0, 5, TColor.primaryG , isTouched: i == touchedIndex); + case 1: + return makeGroupData(1, 10.5, TColor.secondaryG, isTouched: i == touchedIndex); + case 2: + return makeGroupData(2, 5, TColor.primaryG , isTouched: i == touchedIndex); + case 3: + return makeGroupData(3, 7.5, TColor.secondaryG, isTouched: i == touchedIndex); + case 4: + return makeGroupData(4, 15, TColor.primaryG , isTouched: i == touchedIndex); + case 5: + return makeGroupData(5, 5.5, TColor.secondaryG, isTouched: i == touchedIndex); + case 6: + return makeGroupData(6, 8.5, TColor.primaryG , isTouched: i == touchedIndex); + default: + return throw Error(); + } + }); + + BarChartGroupData makeGroupData( + int x, + double y, + List barColor, + { + bool isTouched = false, + + double width = 22, + List showTooltips = const [], + }) { + + return BarChartGroupData( + x: x, + barRods: [ + BarChartRodData( + toY: isTouched ? y + 1 : y, + gradient: LinearGradient(colors: barColor, begin: Alignment.topCenter, end: Alignment.bottomCenter ), + width: width, + borderSide: isTouched + ? const BorderSide(color: Colors.green) + : const BorderSide(color: Colors.white, width: 0), + backDrawRodData: BackgroundBarChartRodData( + show: true, + toY: 20, + color: TColor.lightGray, + ), + ), + ], + showingTooltipIndicators: showTooltips, + ); + } + +} \ No newline at end of file diff --git a/lib/View/home/blank_view.dart b/lib/View/home/blank_view.dart new file mode 100644 index 0000000..427d01a --- /dev/null +++ b/lib/View/home/blank_view.dart @@ -0,0 +1,19 @@ + +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:flutter/material.dart'; + +class BlankView extends StatefulWidget { + const BlankView({super.key}); + + @override + State createState() => _BlankViewState(); +} + +class _BlankViewState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: TColor.white, + ); + } +} \ No newline at end of file diff --git a/lib/View/home/home_view.dart b/lib/View/home/home_view.dart new file mode 100644 index 0000000..64d0df2 --- /dev/null +++ b/lib/View/home/home_view.dart @@ -0,0 +1,1072 @@ + import 'package:dotted_dashed_line/dotted_dashed_line.dart'; +import 'package:smartfit_app_mobile/common_widget/round_button.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; +import 'package:simple_animation_progress_bar/simple_animation_progress_bar.dart'; +import 'package:simple_circular_progress_bar/simple_circular_progress_bar.dart'; +import 'package:smartfit_app_mobile/view/home/activity_tracker.dart'; +import 'package:smartfit_app_mobile/view/home/blank_view.dart'; +import 'package:smartfit_app_mobile/view/home/notification_view.dart'; +import '../../common/colo_extension.dart'; +//import 'activity_tracker_view.dart'; +//import 'finished_workout_view.dart'; +//import 'notification_view.dart'; + +class HomeView extends StatefulWidget { + const HomeView({super.key}); + + @override + State createState() => _HomeViewState(); +} + +class _HomeViewState extends State { + List lastWorkoutArr = [ + { + "name": "Full Body Workout", + "image": "assets/img/Workout1.png", + "kcal": "180", + "time": "20", + "progress": 0.3 + }, + { + "name": "Lower Body Workout", + "image": "assets/img/Workout2.png", + "kcal": "200", + "time": "30", + "progress": 0.4 + }, + { + "name": "Ab Workout", + "image": "assets/img/Workout3.png", + "kcal": "300", + "time": "40", + "progress": 0.7 + }, + ]; + List showingTooltipOnSpots = [21]; + + List allSpots = [FlSpot(0, 20)]; + + List waterArr = [ + {"title": "6am - 8am", "subtitle": "600ml"}, + {"title": "9am - 11am", "subtitle": "500ml"}, + {"title": "11am - 2pm", "subtitle": "1000ml"}, + {"title": "2pm - 4pm", "subtitle": "700ml"}, + {"title": "4pm - now", "subtitle": "900ml"}, + ]; + + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + + final lineBarsData = [ + LineChartBarData( + showingIndicators: showingTooltipOnSpots, + spots: allSpots, + isCurved: false, + barWidth: 2, + belowBarData: BarAreaData( + show: true, + gradient: LinearGradient(colors: [ + TColor.secondaryColor1.withOpacity(0.4), + TColor.secondaryColor2.withOpacity(0.1), + ], begin: Alignment.topCenter, end: Alignment.bottomCenter), + ), + dotData: FlDotData(show: false), + gradient: LinearGradient( + colors: TColor.secondaryG , + ), + ), + ]; + + final tooltipsOnBar = lineBarsData[0]; + + return Scaffold( + backgroundColor: TColor.white, + body: SingleChildScrollView( + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Bienvenue,", + style: TextStyle(color: TColor.gray, fontSize: 12), + ), + Text( + "Benjelloun Othmane", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + ], + ), + IconButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const NotificationView(), + ), + ); + }, + icon: Image.asset( + "assets/img/notification_active.png", + width: 25, + height: 25, + fit: BoxFit.fitHeight, + )) + ], + ), + SizedBox( + height: media.width * 0.05, + ), + Container( + height: media.width * 0.4, + decoration: BoxDecoration( + gradient: LinearGradient(colors: TColor.primaryG), + borderRadius: BorderRadius.circular(media.width * 0.075)), + child: Stack(alignment: Alignment.center, children: [ + Image.asset( + "assets/img/bg_dots.png", + height: media.width * 0.4, + width: double.maxFinite, + fit: BoxFit.fitHeight, + ), + Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 25), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Graph 1", + style: TextStyle( + color: TColor.white, + fontSize: 14, + fontWeight: FontWeight.w700), + ), + Text( + "Sous titre 1", + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontSize: 12), + ), + SizedBox( + height: media.width * 0.05, + ), + SizedBox( + width: 120, + height: 35, + child: RoundButton( + title: "Voir plus", + type: RoundButtonType.bgSGradient, + fontSize: 12, + fontWeight: FontWeight.w400, + onPressed: () {})) + ], + ), + AspectRatio( + aspectRatio: 1, + child: PieChart( + PieChartData( + pieTouchData: PieTouchData( + touchCallback: + (FlTouchEvent event, pieTouchResponse) {}, + ), + startDegreeOffset: 250, + borderData: FlBorderData( + show: false, + ), + sectionsSpace: 1, + centerSpaceRadius: 0, + sections: showingSections(), + ), + ), + ), + ], + ), + ) + ]), + ), + SizedBox( + height: media.width * 0.05, + ), + Container( + padding: + const EdgeInsets.symmetric(vertical: 15, horizontal: 15), + decoration: BoxDecoration( + color: TColor.primaryColor2.withOpacity(0.3), + borderRadius: BorderRadius.circular(15), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Suivi d'activité", + style: TextStyle( + color: TColor.black, + fontSize: 14, + fontWeight: FontWeight.w700), + ), + SizedBox( + width: 70, + height: 25, + child: RoundButton( + title: "Voir", + type: RoundButtonType.bgGradient, + fontSize: 12, + fontWeight: FontWeight.w400, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const ActivityTrackerView(), + ), + ); + }, + ), + ) + ], + ), + ), + SizedBox( + height: media.width * 0.05, + ), + Text( + "Status d'activité", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.02, + ), + ClipRRect( + borderRadius: BorderRadius.circular(25), + child: Container( + height: media.width * 0.4, + width: double.maxFinite, + decoration: BoxDecoration( + color: TColor.primaryColor2.withOpacity(0.3), + borderRadius: BorderRadius.circular(25), + ), + child: Stack( + alignment: Alignment.topLeft, + children: [ + Padding( + padding: const EdgeInsets.symmetric( + vertical: 20, horizontal: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Graph 2 ( rhythme cardiaque )", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700), + ), + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader(Rect.fromLTRB( + 0, 0, bounds.width, bounds.height)); + }, + child: Text( + "78 BPM", + style: TextStyle( + color: TColor.primaryColor1.withOpacity(0.7), + fontWeight: FontWeight.w700, + fontSize: 18), + ), + ), + ], + ), + ), + LineChart( + LineChartData( + showingTooltipIndicators: + showingTooltipOnSpots.map((index) { + return ShowingTooltipIndicators([ + LineBarSpot( + tooltipsOnBar, + lineBarsData.indexOf(tooltipsOnBar), + tooltipsOnBar.spots[index], + ), + ]); + }).toList(), + lineTouchData: LineTouchData( + enabled: true, + handleBuiltInTouches: false, + touchCallback: (FlTouchEvent event, + LineTouchResponse? response) { + if (response == null || + response.lineBarSpots == null) { + return; + } + if (event is FlTapUpEvent) { + final spotIndex = + response.lineBarSpots!.first.spotIndex; + showingTooltipOnSpots.clear(); + setState(() { + showingTooltipOnSpots.add(spotIndex); + }); + } + }, + mouseCursorResolver: (FlTouchEvent event, + LineTouchResponse? response) { + if (response == null || + response.lineBarSpots == null) { + return SystemMouseCursors.basic; + } + return SystemMouseCursors.click; + }, + getTouchedSpotIndicator: + (LineChartBarData barData, + List spotIndexes) { + return spotIndexes.map((index) { + return TouchedSpotIndicatorData( + FlLine( + color: TColor.secondaryColor1, + ), + FlDotData( + show: true, + getDotPainter: + (spot, percent, barData, index) => + FlDotCirclePainter( + radius: 3, + color: Colors.white, + strokeWidth: 3, + strokeColor: TColor.secondaryColor1, + ), + ), + ); + }).toList(); + }, + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: TColor.secondaryColor1, + tooltipRoundedRadius: 20, + getTooltipItems: + (List lineBarsSpot) { + return lineBarsSpot.map((lineBarSpot) { + return LineTooltipItem( + "il y a ${lineBarSpot.x.toInt()} minutes", + const TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.bold, + ), + ); + }).toList(); + }, + ), + ), + lineBarsData: lineBarsData, + minY: 0, + maxY: 130, + titlesData: FlTitlesData( + show: false, + ), + gridData: FlGridData(show: false), + borderData: FlBorderData( + show: true, + border: Border.all( + color: Colors.transparent, + ), + ), + ), + ) + ], + ), + ), + ), + SizedBox( + height: media.width * 0.05, + ), + Row( + children: [ + Expanded( + child: Container( + height: media.width * 0.95, + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(25), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Row( + children: [ + SimpleAnimationProgressBar( + height: media.width * 0.85, + width: media.width * 0.07, + backgroundColor: Colors.grey.shade100, + foregrondColor: Colors.purple, + ratio: 0.5, + direction: Axis.vertical, + curve: Curves.fastLinearToSlowEaseIn, + duration: const Duration(seconds: 3), + borderRadius: BorderRadius.circular(15), + gradientColor: LinearGradient( + colors: TColor.primaryG, + begin: Alignment.bottomCenter, + end: Alignment.topCenter), + ), + const SizedBox( + width: 10, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Graph 3", + style: TextStyle( + color: TColor.black, + fontSize: 12, + fontWeight: FontWeight.w700), + ), + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader(Rect.fromLTRB( + 0, 0, bounds.width, bounds.height)); + }, + child: Text( + "ex : objectif", + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontWeight: FontWeight.w700, + fontSize: 14), + ), + ), + const SizedBox( + height: 10, + ), + Text( + "Mis à jour en temps réel", + style: TextStyle( + color: TColor.gray, + fontSize: 12, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: waterArr.map((wObj) { + var isLast = wObj == waterArr.last; + return Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Container( + margin: + const EdgeInsets.symmetric( + vertical: 4), + width: 10, + height: 10, + decoration: BoxDecoration( + color: TColor.secondaryColor1 + .withOpacity(0.5), + borderRadius: + BorderRadius.circular(5), + ), + ), + if (!isLast) + DottedDashedLine( + height: media.width * 0.078, + width: 0, + dashColor: TColor + .secondaryColor1 + .withOpacity(0.5), + axis: Axis.vertical) + ], + ), + const SizedBox( + width: 10, + ), + Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + wObj["title"].toString(), + style: TextStyle( + color: TColor.gray, + fontSize: 10, + ), + ), + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: + TColor.secondaryG, + begin: Alignment + .centerLeft, + end: Alignment + .centerRight) + .createShader(Rect.fromLTRB( + 0, + 0, + bounds.width, + bounds.height)); + }, + child: Text( + wObj["subtitle"].toString(), + style: TextStyle( + color: TColor.white + .withOpacity(0.7), + fontSize: 12), + ), + ), + ], + ) + ], + ); + }).toList(), + ) + ], + )) + ], + ), + ), + ), + SizedBox( + width: media.width * 0.05, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: double.maxFinite, + height: media.width * 0.45, + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(25), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Graph 4", + style: TextStyle( + color: TColor.black, + fontSize: 12, + fontWeight: FontWeight.w700), + ), + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader(Rect.fromLTRB( + 0, 0, bounds.width, bounds.height)); + }, + child: Text( + "durée", + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontWeight: FontWeight.w700, + fontSize: 14), + ), + ), + const Spacer(), + Image.asset("assets/img/sleep_graph.png", + width: double.maxFinite, + height: 80, + fit: BoxFit.fitWidth) + ]), + ), + SizedBox( + height: media.width * 0.05, + ), + Container( + width: double.maxFinite, + height: media.width * 0.45, + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(25), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Calories", + style: TextStyle( + color: TColor.black, + fontSize: 12, + fontWeight: FontWeight.w700), + ), + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader(Rect.fromLTRB( + 0, 0, bounds.width, bounds.height)); + }, + child: Text( + "760 kCal", + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontWeight: FontWeight.w700, + fontSize: 14), + ), + ), + const Spacer(), + Container( + alignment: Alignment.center, + child: SizedBox( + width: media.width * 0.2, + height: media.width * 0.2, + child: Stack( + alignment: Alignment.center, + children: [ + Container( + width: media.width * 0.15, + height: media.width * 0.15, + alignment: Alignment.center, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: TColor.primaryG), + borderRadius: BorderRadius.circular( + media.width * 0.075), + ), + child: FittedBox( + child: Text( + "230kCal\nrestantes", + textAlign: TextAlign.center, + style: TextStyle( + color: TColor.white, + fontSize: 11), + ), + ), + ), + SimpleCircularProgressBar( + progressStrokeWidth: 10, + backStrokeWidth: 10, + progressColors: TColor.primaryG, + backColor: Colors.grey.shade100, + valueNotifier: ValueNotifier(50), + startAngle: -180, + ), + ], + ), + ), + ) + ]), + ), + ], + )) + ], + ), + SizedBox( + height: media.width * 0.1, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "graph 5", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700), + ), + Container( + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + gradient: LinearGradient(colors: TColor.primaryG), + borderRadius: BorderRadius.circular(15), + ), + child: DropdownButtonHideUnderline( + child: DropdownButton( + items: ["Semaine", "Mois"] + .map((name) => DropdownMenuItem( + value: name, + child: Text( + name, + style: TextStyle( + color: TColor.gray, fontSize: 14), + ), + )) + .toList(), + onChanged: (value) {}, + icon: Icon(Icons.expand_more, color: TColor.white), + hint: Text( + "Semaine", + textAlign: TextAlign.center, + style: + TextStyle(color: TColor.white, fontSize: 12), + ), + ), + )), + ], + ), + SizedBox( + height: media.width * 0.05, + ), + Container( + padding: const EdgeInsets.only(left: 15), + height: media.width * 0.5, + width: double.maxFinite, + child: LineChart( + LineChartData( + showingTooltipIndicators: + showingTooltipOnSpots.map((index) { + return ShowingTooltipIndicators([ + LineBarSpot( + tooltipsOnBar, + lineBarsData.indexOf(tooltipsOnBar), + tooltipsOnBar.spots[index], + ), + ]); + }).toList(), + lineTouchData: LineTouchData( + enabled: true, + handleBuiltInTouches: false, + touchCallback: (FlTouchEvent event, + LineTouchResponse? response) { + if (response == null || + response.lineBarSpots == null) { + return; + } + if (event is FlTapUpEvent) { + final spotIndex = + response.lineBarSpots!.first.spotIndex; + showingTooltipOnSpots.clear(); + setState(() { + showingTooltipOnSpots.add(spotIndex); + }); + } + }, + mouseCursorResolver: (FlTouchEvent event, + LineTouchResponse? response) { + if (response == null || + response.lineBarSpots == null) { + return SystemMouseCursors.basic; + } + return SystemMouseCursors.click; + }, + getTouchedSpotIndicator: (LineChartBarData barData, + List spotIndexes) { + return spotIndexes.map((index) { + return TouchedSpotIndicatorData( + FlLine( + color: Colors.transparent, + ), + FlDotData( + show: true, + getDotPainter: + (spot, percent, barData, index) => + FlDotCirclePainter( + radius: 3, + color: Colors.white, + strokeWidth: 3, + strokeColor: TColor.secondaryColor1, + ), + ), + ); + }).toList(); + }, + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: TColor.secondaryColor1, + tooltipRoundedRadius: 20, + getTooltipItems: (List lineBarsSpot) { + return lineBarsSpot.map((lineBarSpot) { + return LineTooltipItem( + "il y a ${lineBarSpot.x.toInt()} minutes", + const TextStyle( + color: Colors.white, + fontSize: 10, + fontWeight: FontWeight.bold, + ), + ); + }).toList(); + }, + ), + ), + lineBarsData: lineBarsData1, + minY: -0.5, + maxY: 110, + titlesData: FlTitlesData( + show: true, + leftTitles: AxisTitles(), + topTitles: AxisTitles(), + bottomTitles: AxisTitles( + sideTitles: bottomTitles, + ), + rightTitles: AxisTitles( + sideTitles: rightTitles, + )), + gridData: FlGridData( + show: true, + drawHorizontalLine: true, + horizontalInterval: 25, + drawVerticalLine: false, + getDrawingHorizontalLine: (value) { + return FlLine( + color: TColor.gray.withOpacity(0.15), + strokeWidth: 2, + ); + }, + ), + borderData: FlBorderData( + show: true, + border: Border.all( + color: Colors.transparent, + ), + ), + ), + )), + SizedBox( + height: media.width * 0.05, + ), + + SizedBox( + height: media.width * 0.1, + ), + ], + ), + ), + ), + ), + ); + } + + void updateChartData(List newData) { + setState(() { + allSpots = newData; + }); + } + + + List showingSections() { + return List.generate( + 2, + (i) { + var color0 = TColor.secondaryColor1; + + switch (i) { + case 0: + return PieChartSectionData( + color: color0, + value: 33, + title: '', + radius: 55, + titlePositionPercentageOffset: 0.55, + badgeWidget: const Text( + "20,1", + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.w700), + )); + case 1: + return PieChartSectionData( + color: Colors.white, + value: 75, + title: '', + radius: 45, + titlePositionPercentageOffset: 0.55, + ); + + default: + throw Error(); + } + }, + ); + } + + LineTouchData get lineTouchData1 => LineTouchData( + handleBuiltInTouches: true, + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.blueGrey.withOpacity(0.8), + ), + ); + + List get lineBarsData1 => [ + lineChartBarData1_1, + lineChartBarData1_2, + ]; + + LineChartBarData get lineChartBarData1_1 => LineChartBarData( + isCurved: true, + gradient: LinearGradient(colors: [ + TColor.primaryColor2.withOpacity(0.5), + TColor.primaryColor1.withOpacity(0.5), + ]), + barWidth: 4, + isStrokeCapRound: true, + dotData: FlDotData(show: false), + belowBarData: BarAreaData(show: false), + spots: const [ + FlSpot(1, 35), + FlSpot(2, 70), + FlSpot(3, 40), + FlSpot(4, 80), + FlSpot(5, 25), + FlSpot(6, 70), + FlSpot(7, 35), + ], + ); + + LineChartBarData get lineChartBarData1_2 => LineChartBarData( + isCurved: true, + gradient: LinearGradient(colors: [ + TColor.secondaryColor2.withOpacity(0.5), + TColor.secondaryColor1.withOpacity(0.5), + ]), + barWidth: 2, + isStrokeCapRound: true, + dotData: FlDotData(show: false), + belowBarData: BarAreaData( + show: false, + ), + spots: const [ + FlSpot(1, 80), + FlSpot(2, 50), + FlSpot(3, 90), + FlSpot(4, 40), + FlSpot(5, 80), + FlSpot(6, 35), + FlSpot(7, 60), + ], + ); + + SideTitles get rightTitles => SideTitles( + getTitlesWidget: rightTitleWidgets, + showTitles: true, + interval: 20, + reservedSize: 40, + ); + + Widget rightTitleWidgets(double value, TitleMeta meta) { + String text; + switch (value.toInt()) { + case 0: + text = '0%'; + break; + case 20: + text = '20%'; + break; + case 40: + text = '40%'; + break; + case 60: + text = '60%'; + break; + case 80: + text = '80%'; + break; + case 100: + text = '100%'; + break; + default: + return Container(); + } + + return Text(text, + style: TextStyle( + color: TColor.gray, + fontSize: 12, + ), + textAlign: TextAlign.center); + } + + SideTitles get bottomTitles => SideTitles( + showTitles: true, + reservedSize: 32, + interval: 1, + getTitlesWidget: bottomTitleWidgets, + ); + + Widget bottomTitleWidgets(double value, TitleMeta meta) { + var style = TextStyle( + color: TColor.gray, + fontSize: 12, + ); + Widget text; + switch (value.toInt()) { + case 1: + text = Text('Dim', style: style); + break; + case 2: + text = Text('Lun', style: style); + break; + case 3: + text = Text('Mar', style: style); + break; + case 4: + text = Text('Mer', style: style); + break; + case 5: + text = Text('Jeu', style: style); + break; + case 6: + text = Text('Ven', style: style); + break; + case 7: + text = Text('Sam', style: style); + break; + default: + text = Text('', style: style); + break; + } + + return SideTitleWidget( + axisSide: meta.axisSide, + space: 10, + child: text, + ); + } +} \ No newline at end of file diff --git a/lib/View/home/notification_view.dart b/lib/View/home/notification_view.dart new file mode 100644 index 0000000..c8e46c5 --- /dev/null +++ b/lib/View/home/notification_view.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; + +import '../../common/colo_extension.dart'; +import '../../common_widget/notification_row.dart'; + +class NotificationView extends StatefulWidget { + const NotificationView({super.key}); + + @override + State createState() => _NotificationViewState(); +} + +class _NotificationViewState extends State { + List notificationArr = [ + {"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "Il y a 3 minutes"}, + {"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "Il y a 7 minutes"}, + {"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "Il y a 5 jours"}, + {"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "29 Mai"}, + {"image": "assets/img/workout1.svg", "title": "Hey, c'est l'heure du sport", "time": "8 Avril"}, + {"image": "assets/img/workout1.svg", "title": "Ne manque pas ton entrainement", "time": "8 Avril"}, + ]; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: TColor.white, + centerTitle: true, + elevation: 0, + leading: InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Container( + margin: const EdgeInsets.all(8), + height: 40, + width: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.lightGray, + borderRadius: BorderRadius.circular(10)), + child: Image.asset( + "assets/img/black_btn.png", + width: 15, + height: 15, + fit: BoxFit.contain, + ), + ), + ), + title: Text( + "Notification", + style: TextStyle( + color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), + ), + actions: [ + InkWell( + onTap: () {}, + child: Container( + margin: const EdgeInsets.all(8), + height: 40, + width: 40, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.lightGray, + borderRadius: BorderRadius.circular(10)), + child: Image.asset( + "assets/img/more_btn.png", + width: 12, + height: 12, + fit: BoxFit.contain, + ), + ), + ) + ], + ), + backgroundColor: TColor.white, + body: ListView.separated( + padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 25), + itemBuilder: ((context, index) { + var nObj = notificationArr[index] as Map? ?? {}; + return NotificationRow(nObj: nObj); + }), separatorBuilder: (context, index){ + return Divider(color: TColor.gray.withOpacity(0.5), height: 1, ); + }, itemCount: notificationArr.length), + ); + } +} \ No newline at end of file diff --git a/lib/View/login/login_view.dart b/lib/View/login/login_view.dart new file mode 100644 index 0000000..17fa1ce --- /dev/null +++ b/lib/View/login/login_view.dart @@ -0,0 +1,201 @@ +import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/common_widget/round_button.dart'; +import 'package:smartfit_app_mobile/common_widget/round_text_field.dart'; +import 'package:flutter/material.dart'; + +class LoginView extends StatefulWidget { + const LoginView({super.key}); + + @override + State createState() => _LoginViewState(); +} + +class _LoginViewState extends State { + bool isCheck = false; + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: TColor.white, + body: SingleChildScrollView( + child: SafeArea( + child: Container( + height: media.height * 0.9, + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "Bienvenue,", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Se connecter", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.05, + ), + SizedBox( + height: media.width * 0.04, + ), + const RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: true, + rigtIcon: TextButton( + onPressed: () {}, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", + width: 20, + height: 20, + fit: BoxFit.contain, + ))), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Mot de passe oublié ?", + style: TextStyle( + color: TColor.gray, + fontSize: 15, + decoration: TextDecoration.underline), + ), + ], + ), + const Spacer(), + RoundButton( + title: "Se connecter", + onPressed: () { + + }), + SizedBox( + height: media.width * 0.04, + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + Text( + " Or ", + style: TextStyle(color: TColor.black, fontSize: 12), + ), + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), + ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/google.png", + width: 20, + height: 20, + ), + ), + ), + SizedBox( + width: media.width * 0.04, + ), + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), + ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/suunto.png", + width: 35, + height: 35, + ), + ), + ) + ], + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Vous n'avez pas toujours pas de compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, + ), + ), + Text( + "Créer un compte", + style: TextStyle( + color: TColor.black, + fontSize: 14, + fontWeight: FontWeight.w700), + ) + ], + ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/View/login/signup_view.dart b/lib/View/login/signup_view.dart new file mode 100644 index 0000000..0efce72 --- /dev/null +++ b/lib/View/login/signup_view.dart @@ -0,0 +1,233 @@ +import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/common_widget/round_button.dart'; +import 'package:smartfit_app_mobile/common_widget/round_text_field.dart'; +import 'package:smartfit_app_mobile/view/home/home_view.dart'; +//import 'package:smartfit_app_mobile/view/login/complete_profile_view.dart'; +import 'package:smartfit_app_mobile/view/login/login_view.dart'; +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/view/main_tab/main_tab_view.dart'; + +class SignUpView extends StatefulWidget { + const SignUpView({super.key}); + + @override + State createState() => _SignUpViewState(); +} + +class _SignUpViewState extends State { + bool isCheck = false; + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: TColor.white, + body: SingleChildScrollView( + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "Bienvenue,", + style: TextStyle(color: TColor.gray, fontSize: 16), + ), + Text( + "Créer un compte", + style: TextStyle( + color: TColor.black, + fontSize: 20, + fontWeight: FontWeight.w700), + ), + SizedBox( + height: media.width * 0.05, + ), + const RoundTextField( + hitText: "Prénom", + icon: "assets/img/user_text.svg", + ), + SizedBox( + height: media.width * 0.04, + ), + const RoundTextField( + hitText: "Nom", + icon: "assets/img/user_text.svg", + ), + SizedBox( + height: media.width * 0.04, + ), + const RoundTextField( + hitText: "Email", + icon: "assets/img/email.svg", + keyboardType: TextInputType.emailAddress, + ), + SizedBox( + height: media.width * 0.04, + ), + RoundTextField( + hitText: "Mot de passe", + icon: "assets/img/lock.svg", + obscureText: true, + rigtIcon: TextButton( + onPressed: () {}, + child: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + "assets/img/show_password.svg", + width: 20, + height: 20, + fit: BoxFit.contain, + ))), + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + IconButton( + onPressed: () { + setState(() { + isCheck = !isCheck; + }); + }, + icon: Icon( + isCheck + ? Icons.check_box_outlined + : Icons.check_box_outline_blank_outlined, + color: TColor.gray, + size: 20, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + "En continuant, vous acceptez notre Politique de\nconfidentialité et nos Conditions d'utilisation.", + style: TextStyle(color: TColor.gray, fontSize: 10), + ), + + ) + ], + ), + SizedBox( + height: media.width * 0.4, + ), + RoundButton(title: "Créer un compte", onPressed: () {}), + SizedBox( + height: media.width * 0.04, + ), + Row( + // crossAxisAlignment: CrossAxisAlignment., + children: [ + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + Text( + " Ou ", + style: TextStyle(color: TColor.black, fontSize: 12), + ), + Expanded( + child: Container( + height: 1, + color: TColor.gray.withOpacity(0.5), + )), + ], + ), + SizedBox( + height: media.width * 0.04, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), + ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/google.png", + width: 20, + height: 20, + ), + ), + ), + + SizedBox( + width: media.width * 0.04, + ), + + GestureDetector( + onTap: () {}, + child: Container( + width: 50, + height: 50, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.white, + border: Border.all( + width: 1, + color: TColor.gray.withOpacity(0.4), + ), + borderRadius: BorderRadius.circular(15), + ), + child: Image.asset( + "assets/img/suunto.png", + width: 35, + height: 35, + ), + ), + ) + ], + ), + SizedBox( + height: media.width * 0.04, + ), + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MainTabView())); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "Vous avez déjà un compte ? ", + style: TextStyle( + color: TColor.black, + fontSize: 14, + ), + ), + Text( + "Se connecter", + style: TextStyle( + color: TColor.black, + fontSize: 14, + fontWeight: FontWeight.w700), + ) + ], + ), + ), + SizedBox( + height: media.width * 0.04, + ), + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/View/main_tab/main_tab_view.dart b/lib/View/main_tab/main_tab_view.dart new file mode 100644 index 0000000..41c2386 --- /dev/null +++ b/lib/View/main_tab/main_tab_view.dart @@ -0,0 +1,121 @@ +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/common_widget/tab_button.dart'; +import 'package:smartfit_app_mobile/view/activity/activity.dart'; +import 'package:smartfit_app_mobile/view/home/blank_view.dart'; +import 'package:smartfit_app_mobile/view/home/home_view.dart'; +import 'package:smartfit_app_mobile/view/main_tab/select_view.dart'; +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/view/map/my_map.dart'; +import 'package:smartfit_app_mobile/view/page_test.dart'; +import 'package:smartfit_app_mobile/view/profile/profile_view.dart'; + + + +class MainTabView extends StatefulWidget { + const MainTabView({super.key}); + + @override + State createState() => _MainTabViewState(); +} + +class _MainTabViewState extends State { + int selectTab = 0; + final PageStorageBucket pageBucket = PageStorageBucket(); + Widget currentTab = const HomeView(); + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: TColor.white, + body: PageStorage(bucket: pageBucket, child: currentTab), + floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, + floatingActionButton: SizedBox( + width: 70, + height: 70, + child: InkWell( + onTap: () { + selectTab = 0; + currentTab = const TestPage(); + if (mounted) { + setState(() {}); + } + }, + child: Container( + width: 65, + height: 65, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: TColor.primaryG, + ), + borderRadius: BorderRadius.circular(35), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 2,) + ]), + child: Icon(Icons.search,color: TColor.white, size: 35, ), + ), + ), + ), + bottomNavigationBar: BottomAppBar( + child: Container( + decoration: BoxDecoration(color: TColor.white, boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2, offset: Offset(0, -2)) + ]), + height: kToolbarHeight, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + TabButton( + icon: "assets/img/Home_tab.svg", + selectIcon: "assets/img/Home_tab_select.svg", + isActive: selectTab == 0, + onTap: () { + selectTab = 0; + currentTab = const HomeView(); + if (mounted) { + setState(() {}); + } + }), + TabButton( + icon: "assets/img/Activity_tab.svg", + selectIcon: "assets/img/Activity_tab_select.svg", + isActive: selectTab == 1, + onTap: () { + selectTab = 1; + currentTab = const Activity(); + if (mounted) { + setState(() {}); + } + }), + + const SizedBox(width: 40,), + TabButton( + icon: "assets/img/Camera_tab.svg", + selectIcon: "assets/img/Camera_tab_select.svg", + isActive: selectTab == 2, + onTap: () { + selectTab = 2; + currentTab = const MyMap(); + if (mounted) { + setState(() {}); + } + }), + TabButton( + icon: "assets/img/Profile_tab.svg", + selectIcon: "assets/img/Profile_tab_select.svg", + isActive: selectTab == 3, + onTap: () { + selectTab = 3; + currentTab = const ProfileView(); + if (mounted) { + setState(() {}); + } + }) + + + ], + ), + )), + ); + } +} \ No newline at end of file diff --git a/lib/View/main_tab/select_view.dart b/lib/View/main_tab/select_view.dart new file mode 100644 index 0000000..fcd5bbc --- /dev/null +++ b/lib/View/main_tab/select_view.dart @@ -0,0 +1,63 @@ +import 'package:smartfit_app_mobile/common_widget/round_button.dart'; +//import 'package:smartfit_app_mobile/view/meal_planner/meal_planner_view.dart'; +//import 'package:smartfit_app_mobile/view/workout_tracker/workout_tracker_view.dart'; +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/view/home/blank_view.dart'; + +//import '../sleep_tracker/sleep_tracker_view.dart'; + +class SelectView extends StatelessWidget { + const SelectView({super.key}); + + @override + Widget build(BuildContext context) { + // var media = MediaQuery.of(context).size; + + return Scaffold( + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RoundButton( + title: "Workout Tracker", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BlankView(), + ), + ); + }), + + const SizedBox(height: 15,), + + RoundButton( + title: "Meal Planner", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BlankView(), + ), + ); + }), + + const SizedBox(height: 15,), + + RoundButton( + title: "Sleep Tracker", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const BlankView(), + ), + ); + }) + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/View/map/my_map.dart b/lib/View/map/my_map.dart new file mode 100644 index 0000000..272fe38 --- /dev/null +++ b/lib/View/map/my_map.dart @@ -0,0 +1,154 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:location/location.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; + +class MyMap extends StatefulWidget { + const MyMap({ Key? key }) : super(key: key); + + @override + State createState() => _MyMapState(); +} + +class _MyMapState extends State { + + Completer _googleMapController = Completer(); + CameraPosition? _cameraPosition; + Location? _location; + LocationData? _currentLocation; + List _polylineCoordinates = []; + Set _polylines = {}; + Set _markers = {}; // Add a set to store markers + + @override + void initState() { + _init(); + super.initState(); + } + + _init() async { + _location = Location(); + _cameraPosition = CameraPosition( + target: LatLng(0, 0), // this is just the example lat and lng for initializing + zoom: 20 + ); + _initLocation(); + } + + //function to listen when we move position + _initLocation() { + + _location?.getLocation().then((location) { + _currentLocation = location; + }); + + _location?.onLocationChanged.listen((newLocation) { + setState(() { + _currentLocation = newLocation; + _polylineCoordinates.add(LatLng( + _currentLocation?.latitude ?? 0, + _currentLocation?.longitude ?? 0, + )); + _updatePolyline(); + + }); + + moveToPosition(LatLng(_currentLocation?.latitude ?? 0, + _currentLocation?.longitude ?? 0)); + }); + } + + _updatePolyline() { + setState(() { + _polylines.clear(); + _polylines.add(Polyline( + polylineId: PolylineId("polyline"), + color: TColor.primaryColor1, + points: _polylineCoordinates, + width: 10, + )); + }); + } + + // Updated _updateMarker to use the custom marker + _updateMarker(LatLng position) async { + final markerId = MarkerId('marker'); + final marker = Marker( + markerId: markerId, + position: position + ); + _markers.clear(); + _markers.add(marker); +} + + + moveToPosition(LatLng latLng) async { + GoogleMapController mapController = await _googleMapController.future; + mapController.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition( + target: latLng, + zoom: 15 + ) + ) + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: _buildBody(), + ); + } + + Widget _buildBody() { + return _getMap(); + } + + Widget _getMarker() { + return Container( + width: 25, + height: 25, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + boxShadow: [ + BoxShadow( + color: Colors.grey, + offset: Offset(0,3), + spreadRadius: 4, + blurRadius: 6 + ) + ] + ), + child: ClipOval(child: Image.asset("assets/img/u1.png")), + ); + } + + Widget _getMap() { + return Stack( + children: [ + GoogleMap( + initialCameraPosition: _cameraPosition!, + mapType: MapType.normal, + onMapCreated: (GoogleMapController controller) { + if (!_googleMapController.isCompleted) { + _googleMapController.complete(controller); + } + }, + polylines: _polylines, + markers: _markers, + ), + Positioned.fill( + child: Align( + alignment: Alignment.center, + child: _getMarker() + ) + ) + ], + ); + } +} diff --git a/lib/View/map/test.dart b/lib/View/map/test.dart new file mode 100644 index 0000000..717dfbb --- /dev/null +++ b/lib/View/map/test.dart @@ -0,0 +1,117 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:location/location.dart'; + +class MyMap extends StatefulWidget { + const MyMap({ Key? key }) : super(key: key); + + @override + State createState() => _MyMapState(); +} + +class _MyMapState extends State { + + Completer _googleMapController = Completer(); + CameraPosition? _cameraPosition; + Location? _location; + LocationData? _currentLocation; + + + + @override + void initState() { + _init(); + super.initState(); + } + + _init() async { + _location = Location(); + _cameraPosition = CameraPosition( + target: LatLng(0, 0), // this is just the example lat and lng for initializing + zoom: 15 + ); + _initLocation(); + } + + //function to listen when we move position + _initLocation() { + //use this to go to current location instead + _location?.getLocation().then((location) { + _currentLocation = location; + }); + _location?.onLocationChanged.listen((newLocation) { + _currentLocation = newLocation; + moveToPosition(LatLng(_currentLocation?.latitude ?? 0, _currentLocation?.longitude ?? 0)); + }); + } + + moveToPosition(LatLng latLng) async { + GoogleMapController mapController = await _googleMapController.future; + mapController.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition( + target: latLng, + zoom: 15 + ) + ) + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: _buildBody(), + ); + } + + Widget _buildBody() { + return _getMap(); + } + + Widget _getMarker() { + return Container( + width: 40, + height: 40, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(100), + boxShadow: [ + BoxShadow( + color: Colors.grey, + offset: Offset(0,3), + spreadRadius: 4, + blurRadius: 6 + ) + ] + ), + child: ClipOval(child: Image.asset("assets/img/u1.png")), + ); + } + + Widget _getMap() { + return Stack( + children: [ + GoogleMap( + initialCameraPosition: _cameraPosition!, + mapType: MapType.normal, + onMapCreated: (GoogleMapController controller) { + // now we need a variable to get the controller of google map + if (!_googleMapController.isCompleted) { + _googleMapController.complete(controller); + } + }, + ), + + Positioned.fill( + child: Align( + alignment: Alignment.center, + child: _getMarker() + ) + ) + ], + ); + } +} \ No newline at end of file diff --git a/lib/View/on_boarding/on_boarding_view.dart b/lib/View/on_boarding/on_boarding_view.dart new file mode 100644 index 0000000..02e6008 --- /dev/null +++ b/lib/View/on_boarding/on_boarding_view.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/common_widget/on_boarding_page.dart'; +import 'package:smartfit_app_mobile/view/login/signup_view.dart'; + +class OnBoardingView extends StatefulWidget { + const OnBoardingView({super.key}); + + @override + State createState() => _OnBoardingViewState(); +} + +class _OnBoardingViewState extends State { + int selectPage = 0; + PageController controller = PageController(); + + @override + void initState() { + + super.initState(); + + controller.addListener(() { + selectPage = controller.page?.round() ?? 0; + + setState(() { + + }); + }); + } + + List pageArr = [ + { + "title": "Atteignez vos objectifs", + "subtitle": + "Ne vous inquiétez pas si vous avez du mal à déterminer vos objectifs. Grâce à l'analyse concrète de vos performances, nous vous aiderons à les atteindre.", + "image": "assets/img/on_1.svg" + }, + { + "title": "Persévérez", + "subtitle": + "Continuez à persévérer pour atteindre vos objectifs. La douleur n'est que temporaire. Si vous abandonnez maintenant, vous souffrirez éternellement.", + "image": "assets/img/on_2.svg" + }, + { + "title": "Laissez-nous piloter, mettez simplement votre Suunto", + "subtitle": + "Détendez-vous, nous prenons les commandes en analysant performances et statistiques pour vous aider à atteindre vos objectifs.", + "image": "assets/img/on_3.svg" + }, + ]; + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: TColor.white, + body: Stack( + alignment: Alignment.bottomRight, + children: [ + PageView.builder( + controller: controller, + itemCount: pageArr.length, + itemBuilder: (context, index) { + var pObj = pageArr[index] as Map? ?? {}; + return OnBoardingPage(pObj: pObj) ; + }), + + SizedBox( + width: 120, + height: 120, + child: Stack( + alignment: Alignment.center, + children: [ + + SizedBox( + width: 70, + height: 70, + child: CircularProgressIndicator( + color: TColor.primaryColor1, + value: (selectPage + 1) / 3 , + strokeWidth: 2, + ), + ), + + Container( + margin: const EdgeInsets.symmetric(horizontal: 30, vertical: 30), + width: 60, + height: 60, + decoration: BoxDecoration(color: TColor.primaryColor1, borderRadius: BorderRadius.circular(35)), + child: IconButton(icon: Icon( Icons.navigate_next, color: TColor.white, ), onPressed: (){ + + if(selectPage < 2) { + selectPage = selectPage + 1; + controller.animateToPage(selectPage, duration: const Duration(milliseconds: 200), curve: Curves.bounceInOut); + setState(() { + + }); + + }else{ + Navigator.push(context, + MaterialPageRoute( + builder: (context) => const SignUpView() + ) + ); + } + + },), + ), + + + ], + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/View/on_boarding/started_view.dart b/lib/View/on_boarding/started_view.dart new file mode 100644 index 0000000..d091d59 --- /dev/null +++ b/lib/View/on_boarding/started_view.dart @@ -0,0 +1,68 @@ +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/view/on_boarding/on_boarding_view.dart'; +import 'package:flutter/material.dart'; +import '../../common_widget/round_button.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class StartedView extends StatefulWidget { + const StartedView({super.key}); + + @override + State createState() => _StartedViewState(); +} + +class _StartedViewState extends State { + bool isChangeColor = true; + + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: TColor.white, + body: Container( + width: media.width, + decoration: BoxDecoration( + gradient: isChangeColor + ? LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + : null, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + height: media.width * 0.90, + ), + SvgPicture.asset("assets/img/logoSM.svg"), + const Spacer(), + SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: RoundButton( + title: "Commencer", + type: isChangeColor + ? RoundButtonType.textGradient + : RoundButtonType.bgGradient, + onPressed: () { + if (isChangeColor) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const OnBoardingView())); + } else { + //Change Color + setState(() { + isChangeColor = true; + }); + } + }, + ), + ), + ) + ], + )), + ); + } +} \ No newline at end of file diff --git a/lib/View/profile/profile_view.dart b/lib/View/profile/profile_view.dart new file mode 100644 index 0000000..ddc0f43 --- /dev/null +++ b/lib/View/profile/profile_view.dart @@ -0,0 +1,354 @@ +import 'package:flutter/material.dart'; + +import '../../common/colo_extension.dart'; +import '../../common_widget/round_button.dart'; +import '../../common_widget/setting_row.dart'; +import '../../common_widget/title_subtitle_cell.dart'; +import 'package:animated_toggle_switch/animated_toggle_switch.dart'; + +class ProfileView extends StatefulWidget { + const ProfileView({super.key}); + + @override + State createState() => _ProfileViewState(); +} + +class _ProfileViewState extends State { + bool positive = false; + + List accountArr = [ + {"image": "assets/img/p_personal.png", "name": "Données personnelles", "tag": "1"}, + + ]; + + List otherArr = [ + {"image": "assets/img/p_contact.png", "name": "Nous contacter", "tag": "5"}, + {"image": "assets/img/p_privacy.png", "name": "Politique de confidentialité", "tag": "6"}, + ]; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: TColor.white, + centerTitle: true, + elevation: 0, + leadingWidth: 0, + title: Text( + "Profile", + style: TextStyle( + color: TColor.black, fontSize: 16, fontWeight: FontWeight.w700), + ), + actions: [ + InkWell( + onTap: () {}, + child: Container( + margin: const EdgeInsets.all(8), + height: 20, + width: 20, + alignment: Alignment.center, + decoration: BoxDecoration( + color: TColor.lightGray, + borderRadius: BorderRadius.circular(10)), + child: Image.asset( + "assets/img/more_btn.png", + width: 15, + height: 15, + fit: BoxFit.contain, + ), + ), + ) + ], + ), + backgroundColor: TColor.white, + body: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(30), + child: Image.asset( + "assets/img/u1.png", + width: 50, + height: 50, + fit: BoxFit.cover, + ), + ), + const SizedBox( + width: 15, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Benjelloun Othmane", + style: TextStyle( + color: TColor.black, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + Text( + "Course à pied", + style: TextStyle( + color: TColor.gray, + fontSize: 12, + ), + ) + ], + ), + ), + SizedBox( + width: 70, + height: 25, + child: RoundButton( + title: "Editer", + type: RoundButtonType.bgGradient, + fontSize: 12, + fontWeight: FontWeight.w400, + onPressed: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => const ActivityTrackerView(), + // ), + // ); + }, + ), + ) + ], + ), + const SizedBox( + height: 15, + ), + const Row( + children: [ + Expanded( + child: TitleSubtitleCell( + title: "??? cm", + subtitle: "Taille", + ), + ), + SizedBox( + width: 15, + ), + Expanded( + child: TitleSubtitleCell( + title: "?? kg", + subtitle: "Poids", + ), + ), + SizedBox( + width: 15, + ), + Expanded( + child: TitleSubtitleCell( + title: "?? ans", + subtitle: "Age", + ), + ), + ], + ), + const SizedBox( + height: 25, + ), + Container( + padding: + const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Compte", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox( + height: 8, + ), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: accountArr.length, + itemBuilder: (context, index) { + var iObj = accountArr[index] as Map? ?? {}; + return SettingRow( + icon: iObj["image"].toString(), + title: iObj["name"].toString(), + onPressed: () {}, + ); + }, + ) + ], + ), + ), + const SizedBox( + height: 25, + ), + Container( + padding: + const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Notification", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox( + height: 8, + ), + SizedBox( + height: 30, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset("assets/img/p_notification.png", + height: 15, width: 15, fit: BoxFit.contain), + const SizedBox( + width: 15, + ), + Expanded( + child: Text( + "Pop-up Notification", + style: TextStyle( + color: TColor.black, + fontSize: 12, + ), + ), + ), + CustomAnimatedToggleSwitch( + current: positive, + values: [false, true], + spacing : 0.0, + indicatorSize: Size.square(25.0), + animationDuration: + const Duration(milliseconds: 200), + animationCurve: Curves.linear, + onChanged: (b) => setState(() => positive = b), + iconBuilder: (context, local, global) { + return const SizedBox(); + }, + cursors: ToggleCursors(defaultCursor: SystemMouseCursors.click), + onTap: (_) => setState(() => positive = !positive), + iconsTappable: false, + wrapperBuilder: (context, global, child) { + return Stack( + alignment: Alignment.center, + children: [ + Positioned( + left: 10.0, + right: 10.0, + + height: 20.0, + child: DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: TColor.secondaryG), + borderRadius: + const BorderRadius.all( + Radius.circular(50.0)), + ), + )), + child, + ], + ); + }, + foregroundIndicatorBuilder: (context, global) { + return SizedBox.fromSize( + size: const Size(5, 5), + child: DecoratedBox( + decoration: BoxDecoration( + color: TColor.white, + borderRadius: const BorderRadius.all( + Radius.circular(50.0)), + boxShadow: const [ + BoxShadow( + color: Colors.black38, + spreadRadius: 0.05, + blurRadius: 1.1, + offset: Offset(0.0, 0.8)) + ], + ), + ), + ); + }, + ), + ]), + ) + ], + ), + ), + const SizedBox( + height: 25, + ), + Container( + padding: + const EdgeInsets.symmetric(vertical: 10, horizontal: 15), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 2) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Autre", + style: TextStyle( + color: TColor.black, + fontSize: 16, + fontWeight: FontWeight.w700, + ), + ), + const SizedBox( + height: 8, + ), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: otherArr.length, + itemBuilder: (context, index) { + var iObj = otherArr[index] as Map? ?? {}; + return SettingRow( + icon: iObj["image"].toString(), + title: iObj["name"].toString(), + onPressed: () {}, + ); + }, + ) + ], + ), + ) + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/common/colo_extension.dart b/lib/common/colo_extension.dart new file mode 100644 index 0000000..c1f31bf --- /dev/null +++ b/lib/common/colo_extension.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +class TColor { + static Color get primaryColor1 => Color(0xffF09932); + static Color get primaryColor2 => Color(0xffFFDCB2); + + static Color get secondaryColor1 => Color(0xff6131AD); + static Color get secondaryColor2 => Color(0xffD4B9FF); + + static List get primaryG => [ primaryColor2, primaryColor1 ]; + static List get secondaryG => [secondaryColor2, secondaryColor1]; + + static Color get black => const Color(0xff1D1617); + static Color get gray => const Color(0xff786F72); + static Color get white => Colors.white; + static Color get lightGray => const Color(0xffF7F8F8); + +} \ No newline at end of file diff --git a/lib/common_widget/dates.dart b/lib/common_widget/dates.dart new file mode 100644 index 0000000..126f864 --- /dev/null +++ b/lib/common_widget/dates.dart @@ -0,0 +1,80 @@ +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:smartfit_app_mobile/common_widget/helpers.dart'; +import 'package:flutter/material.dart'; + +class Dates extends StatelessWidget { + const Dates({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + List dateBoxes = []; + + // DateTime date = DateTime.parse('2021-11-08'); + DateTime date = DateTime.now().subtract(const Duration(days: 3)); + + for (int i = 0; i < 6; i++) { + dateBoxes.add(DateBox(date: date, active: i == 3)); + date = date.add(const Duration(days: 1)); + } + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: dateBoxes, + ), + ); + } +} + +class DateBox extends StatelessWidget { + final bool active; + final DateTime date; + + const DateBox({ + Key? key, + this.active = false, + required this.date, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: 50, + height: 70, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5), + decoration: BoxDecoration( + gradient: active + ? LinearGradient(colors: [ + TColor.primaryColor2, + TColor.primaryColor1, + ], begin: Alignment.topCenter) + : null, + borderRadius: BorderRadius.circular(10), + border: Border.all( + color: const Color(0xffe1e1e1), + ), + ), + child: DefaultTextStyle.merge( + style: active ? const TextStyle(color: Colors.white) : null, + child: Column( + children: [ + Text( + daysOfWeek[date.weekday]!, + style: const TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + Text(date.day.toString().padLeft(2, '0'), + style: const TextStyle( + fontSize: 19, + fontWeight: FontWeight.w500, + )), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/graph.dart b/lib/common_widget/graph.dart new file mode 100644 index 0000000..15a10e3 --- /dev/null +++ b/lib/common_widget/graph.dart @@ -0,0 +1,187 @@ +import 'dart:math'; +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; + +class Graph extends StatelessWidget { + const Graph({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return const Expanded( + child: SizedBox( + width: double.infinity, + child: GraphArea(), + ), + ); + } +} + +class GraphArea extends StatefulWidget { + const GraphArea({Key? key}) : super(key: key); + + @override + _GraphAreaState createState() => _GraphAreaState(); +} + +class _GraphAreaState extends State + with SingleTickerProviderStateMixin { + late AnimationController _animationController; + + List data = [ + DataPoint(day: 1, steps: Random().nextInt(70)), + DataPoint(day: 2, steps: Random().nextInt(70)), + DataPoint(day: 3, steps: Random().nextInt(70)), + DataPoint(day: 4, steps: Random().nextInt(70)), + DataPoint(day: 5, steps: Random().nextInt(70)), + DataPoint(day: 6, steps: Random().nextInt(70)), + DataPoint(day: 7, steps: Random().nextInt(70)), + DataPoint(day: 8, steps: Random().nextInt(70)), + ]; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, duration: const Duration(milliseconds: 2500)); + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + _animationController.forward(from: 0.0); + }, + child: CustomPaint( + painter: GraphPainter(_animationController.view, data: data), + ), + ); + } +} + +class GraphPainter extends CustomPainter { + final List data; + final Animation _size; + final Animation _dotSize; + + GraphPainter(Animation animation, {required this.data}) + : _size = Tween(begin: 0, end: 1).animate( + CurvedAnimation( + parent: animation, + curve: const Interval(0.0, 0.75, + curve: Curves.easeInOutCubicEmphasized), + ), + ), + _dotSize = Tween(begin: 0, end: 1).animate( + CurvedAnimation( + parent: animation, + curve: + const Interval(0.75, 1, curve: Curves.easeInOutCubicEmphasized), + ), + ), + super(repaint: animation); + + @override + void paint(Canvas canvas, Size size) { + var xSpacing = size.width / (data.length - 1); + + var maxSteps = data + .fold(data[0], (p, c) => p.steps > c.steps ? p : c) + .steps; + + var yRatio = size.height / maxSteps; + var curveOffset = xSpacing * 0.3; + + List offsets = []; + + var cx = 0.0; + for (int i = 0; i < data.length; i++) { + var y = size.height - (data[i].steps * yRatio * _size.value); + + offsets.add(Offset(cx, y)); + cx += xSpacing; + } + + Paint linePaint = Paint() + ..color = TColor.primaryColor1 + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + Paint shadowPaint = Paint() + ..color = TColor.primaryColor1 + ..style = PaintingStyle.stroke + ..maskFilter = const ui.MaskFilter.blur(ui.BlurStyle.solid, 0) + ..strokeWidth = 0.0; + + Paint fillPaint = Paint() + ..shader = ui.Gradient.linear( + Offset(size.width / 2, 0), + Offset(size.width / 2, size.height), + [ + TColor.primaryColor1, + Colors.white, + ], + ) + ..color = TColor.primaryColor1 + ..style = PaintingStyle.fill; + + Paint dotOutlinePaint = Paint() + ..color = Colors.white.withAlpha(200) + ..strokeWidth = 8; + + Paint dotCenter = Paint() + ..color = TColor.primaryColor1 + ..strokeWidth = 8; + + Path linePath = Path(); + + Offset cOffset = offsets[0]; + + linePath.moveTo(cOffset.dx, cOffset.dy); + + for (int i = 1; i < offsets.length; i++) { + var x = offsets[i].dx; + var y = offsets[i].dy; + var c1x = cOffset.dx + curveOffset; + var c1y = cOffset.dy; + var c2x = x - curveOffset; + var c2y = y; + + linePath.cubicTo(c1x, c1y, c2x, c2y, x, y); + cOffset = offsets[i]; + } + + Path fillPath = Path.from(linePath); + fillPath.lineTo(size.width, size.height); + fillPath.lineTo(0, size.height); + + canvas.drawPath(fillPath, fillPaint); + canvas.drawPath(linePath, shadowPaint); + canvas.drawPath(linePath, linePaint); + + canvas.drawCircle(offsets[4], 15 * _dotSize.value, dotOutlinePaint); + canvas.drawCircle(offsets[4], 6 * _dotSize.value, dotCenter); + } + + @override + bool shouldRepaint(covariant GraphPainter oldDelegate) { + return data != oldDelegate.data; + } +} + +class DataPoint { + final int day; + final int steps; + + DataPoint({ + required this.day, + required this.steps, + }); +} \ No newline at end of file diff --git a/lib/common_widget/helpers.dart b/lib/common_widget/helpers.dart new file mode 100644 index 0000000..7a40e1f --- /dev/null +++ b/lib/common_widget/helpers.dart @@ -0,0 +1,22 @@ +import 'dart:math'; + +final Map daysOfWeek = { + 1: 'Mon', + 2: 'Tue', + 3: 'Wed', + 4: 'Thu', + 5: 'Fri', + 6: 'Sat', + 7: 'Sun', +}; + +int randBetween(int min, int max) { + return Random().nextInt(max - min) + min; +} + +String formatNumber(int number) { + return number.toString().replaceAllMapped( + RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), + (Match m) => '${m[1]},', + ); +} \ No newline at end of file diff --git a/lib/common_widget/info.dart b/lib/common_widget/info.dart new file mode 100644 index 0000000..e7f6a19 --- /dev/null +++ b/lib/common_widget/info.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +class Info extends StatelessWidget { + const Info({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: const [ + Stats(value: '345', unit: 'kcal', label: 'Calories'), + Stats(value: '3.6', unit: 'km', label: 'Distance'), + Stats(value: '1.5', unit: 'hr', label: 'Hours'), + ], + ); + } +} + +class Stats extends StatelessWidget { + final String value; + final String unit; + final String label; + + const Stats({ + Key? key, + required this.value, + required this.unit, + required this.label, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text.rich( + TextSpan( + text: value, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.w900, + ), + children: [ + const TextSpan(text: ' '), + TextSpan( + text: unit, + style: const TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ]), + ), + const SizedBox(height: 6), + Text( + label, + style: const TextStyle( + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/latest_activity_row.dart b/lib/common_widget/latest_activity_row.dart new file mode 100644 index 0000000..ce31ec4 --- /dev/null +++ b/lib/common_widget/latest_activity_row.dart @@ -0,0 +1,61 @@ +import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:flutter/material.dart'; + +class LatestActivityRow extends StatelessWidget { + final Map wObj; + const LatestActivityRow({super.key, required this.wObj}); + + @override + Widget build(BuildContext context) { + + return Container( + margin: const EdgeInsets.symmetric(vertical: 8), + + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(30), + child: SvgPicture.asset( + wObj["image"].toString(), + width: 50, + height: 50, + fit: BoxFit.cover, + ), + ), + + const SizedBox(width: 15,), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + wObj["title"].toString(), + style: TextStyle( + color: TColor.black, + fontSize: 12, fontWeight: FontWeight.w500), + ), + + Text( + wObj["time"].toString(), + style: TextStyle( + color: TColor.gray, + fontSize: 10,), + ), + + + + ], + )), + IconButton( + onPressed: () {}, + icon: Image.asset( + "assets/img/sub_menu.png", + width: 12, + height: 12, + fit: BoxFit.contain, + )) + ], + )); + } +} \ No newline at end of file diff --git a/lib/common_widget/notification_row.dart b/lib/common_widget/notification_row.dart new file mode 100644 index 0000000..6446572 --- /dev/null +++ b/lib/common_widget/notification_row.dart @@ -0,0 +1,59 @@ + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:flutter/material.dart'; + +class NotificationRow extends StatelessWidget { + final Map nObj; + const NotificationRow({super.key, required this.nObj}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(30), + child: SvgPicture.asset( + nObj["image"].toString(), + width: 40, + height: 40 + ), + ), + const SizedBox( + width: 15, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + nObj["title"].toString(), + style: TextStyle( + color: TColor.black, + fontWeight: FontWeight.w500, + fontSize: 12), + ), + Text( + nObj["time"].toString(), + style: TextStyle( + color: TColor.gray, + fontSize: 10, + ), + ), + ], + )), + IconButton( + onPressed: () {}, + icon: SvgPicture.asset( + "assets/img/sub_menu.svg", + width: 15, + height: 15, + fit: BoxFit.contain, + )) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/on_boarding_page.dart b/lib/common_widget/on_boarding_page.dart new file mode 100644 index 0000000..ff21b3e --- /dev/null +++ b/lib/common_widget/on_boarding_page.dart @@ -0,0 +1,54 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../common/colo_extension.dart'; + +class OnBoardingPage extends StatelessWidget { + final Map pObj; + const OnBoardingPage({super.key, required this.pObj}); + + @override + Widget build(BuildContext context) { + var media = MediaQuery.of(context).size; + return + + SizedBox( + width: media.width, + height: media.height, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SvgPicture.asset( + pObj["image"].toString(), + width: media.width, + ), + SizedBox( + height: media.width * 0.15, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Text( + pObj["title"].toString(), + style: TextStyle( + color: TColor.black, + fontSize: 24, + fontWeight: FontWeight.w700), + ), + ), + SizedBox( + height: media.width * 0.03, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Text( + pObj["subtitle"].toString(), + style: TextStyle(color: TColor.gray, fontSize: 14), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/round_button.dart b/lib/common_widget/round_button.dart new file mode 100644 index 0000000..5eae22a --- /dev/null +++ b/lib/common_widget/round_button.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; + +import '../common/colo_extension.dart'; + +enum RoundButtonType { bgGradient, bgSGradient , textGradient } + +class RoundButton extends StatelessWidget { + final String title; + final RoundButtonType type; + final VoidCallback onPressed; + final double fontSize; + final double elevation; + final FontWeight fontWeight; + + const RoundButton( + {super.key, + required this.title, + this.type = RoundButtonType.bgGradient, + this.fontSize = 16, + this.elevation = 1, + this.fontWeight=FontWeight.w700, + required this.onPressed}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: type == RoundButtonType.bgSGradient ? TColor.secondaryG : TColor.primaryG, + ), + borderRadius: BorderRadius.circular(25), + boxShadow: type == RoundButtonType.bgGradient || type == RoundButtonType.bgSGradient + ? const [ + BoxShadow( + color: Colors.black26, + blurRadius: 0.5, + offset: Offset(0, 0.5)) + ] + : null), + child: MaterialButton( + onPressed: onPressed, + height: 50, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), + textColor: TColor.primaryColor1, + minWidth: double.maxFinite, + elevation: type == RoundButtonType.bgGradient || type == RoundButtonType.bgSGradient ? 0 : elevation, + color: type == RoundButtonType.bgGradient || type == RoundButtonType.bgSGradient + ? Colors.transparent + : TColor.white, + child: type == RoundButtonType.bgGradient || type == RoundButtonType.bgSGradient + ? Text(title, + style: TextStyle( + color: TColor.white, + fontSize: fontSize, + fontWeight: fontWeight)) + : ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader( + Rect.fromLTRB(0, 0, bounds.width, bounds.height)); + }, + child: Text(title, + style: TextStyle( + color: TColor.primaryColor1, + fontSize: fontSize, + fontWeight: fontWeight)), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/round_text_field.dart b/lib/common_widget/round_text_field.dart new file mode 100644 index 0000000..894e20d --- /dev/null +++ b/lib/common_widget/round_text_field.dart @@ -0,0 +1,48 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +import '../common/colo_extension.dart'; + +class RoundTextField extends StatelessWidget { + final TextEditingController? controller; + final TextInputType? keyboardType; + final String hitText; + final String icon; + final Widget? rigtIcon; + final bool obscureText; + final EdgeInsets? margin; + const RoundTextField({super.key, required this.hitText, required this.icon, this.controller, this.margin, this.keyboardType, this.obscureText = false , this.rigtIcon }); + + @override + Widget build(BuildContext context) { + return Container( + margin: margin, + decoration: BoxDecoration( + color: TColor.lightGray, borderRadius: BorderRadius.circular(15)), + child: TextField( + controller: controller, + keyboardType: keyboardType, + obscureText: obscureText, + decoration: InputDecoration( + contentPadding: + const EdgeInsets.symmetric(vertical: 15, horizontal: 15), + enabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + hintText: hitText, + suffixIcon: rigtIcon, + prefixIcon: Container( + alignment: Alignment.center, + width: 20, + height: 20, + child: SvgPicture.asset( + icon, + width: 20, + height: 20, + fit: BoxFit.contain, + )), + hintStyle: TextStyle(color: TColor.gray, fontSize: 12)), + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/setting_row.dart b/lib/common_widget/setting_row.dart new file mode 100644 index 0000000..6a44a6f --- /dev/null +++ b/lib/common_widget/setting_row.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import '../common/colo_extension.dart'; + +class SettingRow extends StatelessWidget { + final String icon; + final String title; + final VoidCallback onPressed; + const SettingRow({super.key, required this.icon, required this.title, required this.onPressed }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onPressed, + child: SizedBox( + height: 30, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset(icon, + height: 15, width: 15, fit: BoxFit.contain), + const SizedBox( + width: 15, + ), + Expanded( + child: Text( + title, + style: TextStyle( + color: TColor.black, + fontSize: 12, + ), + ), + ), + Image.asset("assets/img/p_next.png", + height: 12, width: 12, fit: BoxFit.contain) + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/stats.dart b/lib/common_widget/stats.dart new file mode 100644 index 0000000..f90abb5 --- /dev/null +++ b/lib/common_widget/stats.dart @@ -0,0 +1,197 @@ +import 'package:flutter/material.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; + +class Stats extends StatelessWidget { + const Stats({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Row( + children: [ + Text( + 'Statistiques', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w800, + ), + ), + SizedBox(width: 8), + Icon( + Icons.pie_chart_rounded, + size: 15, + color: TColor.secondaryColor1, + ), + ], + ), + ), + const SizedBox(height: 15), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: const [ + SizedBox(width: 30), + InfoStat( + icon: Icons.timer, + iconColor: Color.fromARGB(255, 255, 255, 255), + iconBackground: Color(0xff6131AD), + time: '+5s', + label: 'Time', + value: '30:34', + ), + SizedBox(width: 15), + InfoStat( + icon: Icons.favorite_outline, + iconColor: Color.fromARGB(255, 255, 255, 255), + iconBackground: Color(0xff6131AD), + time: '+5s', + label: 'Heart Rate', + value: '151bpm', + ), + SizedBox(width: 15), + InfoStat( + icon: Icons.bolt, + iconColor: Color.fromARGB(255, 255, 255, 255), + iconBackground: Color(0xff6131AD), + time: '+5s', + label: 'Energy', + value: '169kcal', + ), + SizedBox(width: 30), + ], + ), + ) + ], + ); + } +} + +class InfoStat extends StatelessWidget { + final IconData icon; + final Color iconColor; + final Color iconBackground; + final String time; + final String label; + final String value; + + const InfoStat({ + Key? key, + required this.icon, + required this.iconColor, + required this.iconBackground, + required this.time, + required this.label, + required this.value, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 110, + width: 110, + padding: const EdgeInsets.all(8), + margin: const EdgeInsets.symmetric(vertical: 5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: const Color(0xffe1e1e1), + ), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + offset: Offset(3, 3), + blurRadius: 3, + ), + ]), + child: Stack( + children: [ + StatIcon( + icon: icon, + iconColor: iconColor, + iconBackground: iconBackground, + ), + Change(time: time), + Align( + alignment: Alignment.bottomLeft, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: const TextStyle(fontSize: 10), + ), + Text( + value, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w800, + ), + ), + ], + ), + ) + ], + ), + ); + } +} + +class Change extends StatelessWidget { + const Change({ + Key? key, + required this.time, + }) : super(key: key); + + final String time; + + @override + Widget build(BuildContext context) { + return Align( + alignment: Alignment.topRight, + child: Container( + padding: const EdgeInsets.symmetric( + vertical: 1, + horizontal: 4, + ), + decoration: BoxDecoration( + color: Colors.green, + borderRadius: BorderRadius.circular(500), + ), + child: Text( + time, + style: const TextStyle(fontSize: 10, color: Colors.white), + ), + ), + ); + } +} + +class StatIcon extends StatelessWidget { + const StatIcon({ + Key? key, + required this.icon, + required this.iconColor, + required this.iconBackground, + }) : super(key: key); + + final IconData icon; + final Color iconColor; + final Color iconBackground; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(5), + decoration: BoxDecoration( + color: iconBackground, + borderRadius: BorderRadius.circular(9), + ), + child: Icon(icon, size: 15, color: iconColor), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/steps.dart b/lib/common_widget/steps.dart new file mode 100644 index 0000000..3fe1e93 --- /dev/null +++ b/lib/common_widget/steps.dart @@ -0,0 +1,33 @@ +import 'package:smartfit_app_mobile/common_widget/helpers.dart'; +import 'package:flutter/material.dart'; + +class Steps extends StatelessWidget { + const Steps({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + String steps = formatNumber(randBetween(3000, 6000)); + return Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: Column( + children: [ + Text( + steps, + style: const TextStyle( + fontSize: 33, + fontWeight: FontWeight.w900, + ), + ), + const Text( + 'Total Steps', + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w500, + height: 2, + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/tab_button.dart b/lib/common_widget/tab_button.dart new file mode 100644 index 0000000..de8939d --- /dev/null +++ b/lib/common_widget/tab_button.dart @@ -0,0 +1,40 @@ +import 'package:flutter_svg/svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:flutter/material.dart'; + +class TabButton extends StatelessWidget { + final String icon; + final String selectIcon; + final VoidCallback onTap; + final bool isActive; + const TabButton( + {super.key, + required this.icon, + required this.selectIcon, + required this.isActive, + required this.onTap}); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Column(mainAxisSize: MainAxisSize.min, children: [ + SvgPicture.asset(isActive ? selectIcon : icon, + width: 28, height: 28, fit: BoxFit.fitWidth), + SizedBox( + height: isActive ? 12: 8, + ), + if(isActive) + Container( + width: 4, + height: 4, + decoration: BoxDecoration( + gradient: LinearGradient( + colors: TColor.secondaryG, + ), + borderRadius: BorderRadius.circular(2)), + ) + ]), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/title_subtitle_cell.dart b/lib/common_widget/title_subtitle_cell.dart new file mode 100644 index 0000000..cc0e0e8 --- /dev/null +++ b/lib/common_widget/title_subtitle_cell.dart @@ -0,0 +1,50 @@ + +import 'package:flutter/material.dart'; + +import '../common/colo_extension.dart'; + +class TitleSubtitleCell extends StatelessWidget { + final String title; + final String subtitle; + const TitleSubtitleCell({super.key, required this.title, required this.subtitle}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 2)]), + child: Column( + children: [ + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader( + Rect.fromLTRB(0, 0, bounds.width, bounds.height)); + }, + child: Text( + title, + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontWeight: FontWeight.w500, + fontSize: 14), + ), + ), + Text( + subtitle, + style: TextStyle( + color: TColor.gray, + fontSize: 12, + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/common_widget/today_target_cell.dart b/lib/common_widget/today_target_cell.dart new file mode 100644 index 0000000..4cd8e86 --- /dev/null +++ b/lib/common_widget/today_target_cell.dart @@ -0,0 +1,67 @@ + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; +import 'package:flutter/material.dart'; + +class TodayTargetCell extends StatelessWidget { + final String icon; + final String value; + final String title; + const TodayTargetCell({super.key, required this.icon, required this.value, required this.title}); + + @override + Widget build(BuildContext context) { + return Container( + height: 70, + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: TColor.white, + borderRadius: BorderRadius.circular(15), + ), + child: Row( + children: [ + SvgPicture.asset( + icon, + width: 40, + height: 40, + ), + const SizedBox( + width: 8, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: (bounds) { + return LinearGradient( + colors: TColor.primaryG, + begin: Alignment.centerLeft, + end: Alignment.centerRight) + .createShader( + Rect.fromLTRB(0, 0, bounds.width, bounds.height)); + }, + child: Text( + value, + style: TextStyle( + color: TColor.white.withOpacity(0.7), + fontWeight: FontWeight.w700, + fontSize: 14), + ), + ), + Text( + title, + style: TextStyle( + color: TColor.black, + fontSize: 12, + ), + ), + ], + )) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 17837dd..8e731f2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:smartfit_app_mobile/Modele/user.dart'; +import 'package:smartfit_app_mobile/View/on_boarding/started_view.dart'; import 'package:smartfit_app_mobile/View/page_test.dart'; +import 'package:smartfit_app_mobile/common/colo_extension.dart'; void main() { runApp(ChangeNotifierProvider( @@ -15,12 +17,28 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Demo', + title: 'SmartFit 3 in 1', + debugShowCheckedModeBanner: false, theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - useMaterial3: true, + // This is the theme of your application. + // + // TRY THIS: Try running your application with "flutter run". You'll see + // the application has a blue toolbar. Then, without quitting the app, + // try changing the seedColor in the colorScheme below to Colors.green + // and then invoke "hot reload" (save your changes or press the "hot + // reload" button in a Flutter-supported IDE, or press "r" if you used + // the command line to start the app). + // + // Notice that the counter didn't reset back to zero; the application + // state is not lost during the reload. To reset the state, use hot + // restart instead. + // + // This works for code too, not just values: Most code changes can be + // tested with just a hot reload. + primaryColor: TColor.primaryColor1, + fontFamily: "Poppins" ), - home: const TestPage(), + home: const StartedView(), ); } } diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index e71a16d..8fe711c 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) simple_animation_progress_bar_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SimpleAnimationProgressBarPlugin"); + simple_animation_progress_bar_plugin_register_with_registrar(simple_animation_progress_bar_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 2e1de87..d00be37 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + simple_animation_progress_bar ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b..4b81f9b 100644 --- a/macos/Flutter/Flutter-Debug.xcconfig +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig index c2efd0b..5caa9d1 100644 --- a/macos/Flutter/Flutter-Release.xcconfig +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Podfile b/macos/Podfile new file mode 100644 index 0000000..c795730 --- /dev/null +++ b/macos/Podfile @@ -0,0 +1,43 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 2396703..0c554e7 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 4D637422A8A48A3DD3870FF2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAAF6B72880031AF91AF1D78 /* Pods_Runner.framework */; }; + 7D1B58A988C2D813F0AD2648 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 224D4A3F225F68632ECDCB3C /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 06F9583AED9802D69AFAD397 /* 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 = ""; }; + 1447CF3F22E5C6E2DD864A7D /* 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 = ""; }; + 224D4A3F225F68632ECDCB3C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; 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 /* smartfit_app_mobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "smartfit_app_mobile.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* smartfit_app_mobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = smartfit_app_mobile.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 = ""; }; @@ -78,6 +83,11 @@ 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + AAAF6B72880031AF91AF1D78 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BB183F8B5EC5D582001EBA19 /* 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 = ""; }; + BB8EEC31748594A92EEC1868 /* 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 = ""; }; + E5AEE884F74A0E9EED0AD62E /* 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 = ""; }; + FE192D1015B74FEF6DB87A25 /* 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 7D1B58A988C2D813F0AD2648 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +103,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4D637422A8A48A3DD3870FF2 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +137,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + 9F6FEA9E182E3B341478D3C6 /* Pods */, ); sourceTree = ""; }; @@ -172,9 +185,25 @@ path = Runner; sourceTree = ""; }; + 9F6FEA9E182E3B341478D3C6 /* Pods */ = { + isa = PBXGroup; + children = ( + 06F9583AED9802D69AFAD397 /* Pods-Runner.debug.xcconfig */, + BB183F8B5EC5D582001EBA19 /* Pods-Runner.release.xcconfig */, + FE192D1015B74FEF6DB87A25 /* Pods-Runner.profile.xcconfig */, + E5AEE884F74A0E9EED0AD62E /* Pods-RunnerTests.debug.xcconfig */, + BB8EEC31748594A92EEC1868 /* Pods-RunnerTests.release.xcconfig */, + 1447CF3F22E5C6E2DD864A7D /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + AAAF6B72880031AF91AF1D78 /* Pods_Runner.framework */, + 224D4A3F225F68632ECDCB3C /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 6B6EE52CAA76343BE300E884 /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 3AC4D89FFF1B08682057CD0D /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + 320422BBE48D36334808249B /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -290,6 +322,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 320422BBE48D36334808249B /* [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; + }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -328,6 +377,50 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 3AC4D89FFF1B08682057CD0D /* [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; + }; + 6B6EE52CAA76343BE300E884 /* [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-RunnerTests-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; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -379,6 +472,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E5AEE884F74A0E9EED0AD62E /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -393,6 +487,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = BB8EEC31748594A92EEC1868 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -407,6 +502,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 1447CF3F22E5C6E2DD864A7D /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; 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.yaml b/pubspec.yaml index b45cf0b..4cb6e21 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,11 +35,21 @@ dependencies: file_picker: ^6.1.1 csv: ^5.1.1 fit_tool: ^1.0.5 - fl_chart: ^0.64.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + flutter_svg: ^2.0.8 + fl_chart: ^0.64.0 + dotted_dashed_line: ^0.0.3 + simple_animation_progress_bar: ^1.6.0 + simple_circular_progress_bar: ^1.0.2 + animated_toggle_switch: ^0.8.0 + flutter_polyline_points: ^2.0.0 + location: ^5.0.3 + google_maps_flutter: ^2.5.0 + flutter_bloc: ^8.1.3 + flutter_form_builder: ^9.1.1 http: ^1.1.0 provider: ^6.0.5 @@ -66,9 +76,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/img/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware @@ -82,16 +91,12 @@ flutter: # list giving the asset and other descriptors for the font. For # example: # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 + fonts: + - family: Poppins + fonts: + - asset: assets/font/Poppins-Regular.ttf + - asset: assets/font/Poppins-Bold.ttf + weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 8b6d468..dddde2c 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { + SimpleAnimationProgressBarPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SimpleAnimationProgressBarPluginCApi")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b93c4c3..36dd032 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + simple_animation_progress_bar ) list(APPEND FLUTTER_FFI_PLUGIN_LIST