diff --git a/.dhiwise/config b/.dhiwise/config new file mode 100644 index 00000000..f825776a --- /dev/null +++ b/.dhiwise/config @@ -0,0 +1,3 @@ +TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjU3ZmYzZmVjMzBjMTkwMDFjZTZiNTM4IiwiX2lkIjoiNjU3ZmYzZmVjMzBjMTkwMDFjZTZiNTM4In0sImNvbXBhbnlJZCI6IjY1N2ZmM2ZlYzMwYzE5MDAxY2U2YjUzYSIsImFwcGxpY2F0aW9uSWQiOiI2NTdmZmI0NGE1ZDdiNDAwMjIzMGEwZWMiLCJpYXQiOjE3MDI4ODYyMTJ9.24JeUo8jgiAwKQkeKhwu49qjWT2CnXAoQrDmduDL0d0 +SEMANTIC_VERSION = 1.0 +VERSION_NUMBER = 3 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6d6c41b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.dart_tool/ +/.idea/ +/build/ +/.vscode/ +*.lock +/.flutter-plugins +/.flutter-plugins-dependencies +/.packages diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 00000000..0a741cb4 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 00000000..ae7a7c7c --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,67 @@ +plugins{ + id 'com.android.application' + id 'kotlin-android' +} +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.eatvioapp.app" + minSdkVersion 21 + targetSdkVersion flutter.targetSdkVersion + multiDexEnabled true + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "androidx.multidex:multidex:2.0.1" +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..fdeb7774 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..8d3a74df --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/eatvioapp/app/MainActivity.kt b/android/app/src/main/kotlin/com/eatvioapp/app/MainActivity.kt new file mode 100644 index 00000000..ebb55c94 --- /dev/null +++ b/android/app/src/main/kotlin/com/eatvioapp/app/MainActivity.kt @@ -0,0 +1,6 @@ +package com.eatvioapp.app + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/kotlin/com/example/base_project/MainActivity.kt b/android/app/src/main/kotlin/com/example/base_project/MainActivity.kt new file mode 100644 index 00000000..dc8981cc --- /dev/null +++ b/android/app/src/main/kotlin/com/example/base_project/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.base_project + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..35c33dfb Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..f63d16f1 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..aa9b6a11 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..634816bb Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..fe26de29 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..a2885751 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + + eatvio_app + + \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..1f83a33f --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..fdeb7774 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/base_project_android.iml b/android/base_project_android.iml new file mode 100644 index 00000000..18999696 --- /dev/null +++ b/android/base_project_android.iml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 00000000..5670189c --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.7.20' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.2.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/flutterarch_android.iml b/android/flutterarch_android.iml new file mode 100644 index 00000000..18999696 --- /dev/null +++ b/android/flutterarch_android.iml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 00000000..94adc3a3 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..6b665338 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 00000000..44e62bcf --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/assets/fonts/MulishBold.ttf b/assets/fonts/MulishBold.ttf new file mode 100644 index 00000000..0c1eed73 Binary files /dev/null and b/assets/fonts/MulishBold.ttf differ diff --git a/assets/fonts/MulishRegular.ttf b/assets/fonts/MulishRegular.ttf new file mode 100644 index 00000000..0971518b Binary files /dev/null and b/assets/fonts/MulishRegular.ttf differ diff --git a/assets/fonts/MulishSemiBold.ttf b/assets/fonts/MulishSemiBold.ttf new file mode 100644 index 00000000..9ac1fc8f Binary files /dev/null and b/assets/fonts/MulishSemiBold.ttf differ diff --git a/assets/fonts/SegoeUISemibold.ttf b/assets/fonts/SegoeUISemibold.ttf new file mode 100644 index 00000000..46b3b993 Binary files /dev/null and b/assets/fonts/SegoeUISemibold.ttf differ diff --git a/assets/images/image_not_found.png b/assets/images/image_not_found.png new file mode 100644 index 00000000..840d828d Binary files /dev/null and b/assets/images/image_not_found.png differ diff --git a/assets/images/img_2456927096976.svg b/assets/images/img_2456927096976.svg new file mode 100644 index 00000000..17ee6769 --- /dev/null +++ b/assets/images/img_2456927096976.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/images/img_arrow_left.svg b/assets/images/img_arrow_left.svg new file mode 100644 index 00000000..686dc1ab --- /dev/null +++ b/assets/images/img_arrow_left.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_favorite.svg b/assets/images/img_favorite.svg new file mode 100644 index 00000000..b6998c1c --- /dev/null +++ b/assets/images/img_favorite.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_logo_eatvio.svg b/assets/images/img_logo_eatvio.svg new file mode 100644 index 00000000..701b5d1d --- /dev/null +++ b/assets/images/img_logo_eatvio.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 00000000..e96ef602 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..f2872cf4 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..ec97fc6f --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +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 new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..36428fd8 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,495 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..a28140cf --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 00000000..70693e4a --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..c43ad6c1 --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "58x58", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "87x87", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "80x80", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "120x120", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "", + "scale" : "3x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "152x152", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "167x167", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ipad", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "ios_icon_set" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..0c151683 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..255d38a4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..0e485357 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..19bdca9a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..5d8314ba Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..91ff526f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..cdd9f74c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..0e485357 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..569dc4d6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..ea97f488 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..ea97f488 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..d90bbe63 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..80a91b16 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..68b7c09b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..79d03f42 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 00000000..08477d7a --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + eatvio_app + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 00000000..308a2a56 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/lib/core/app_export.dart b/lib/core/app_export.dart new file mode 100644 index 00000000..6d115305 --- /dev/null +++ b/lib/core/app_export.dart @@ -0,0 +1,20 @@ +export 'package:connectivity_plus/connectivity_plus.dart'; +export 'package:flutter_bloc/flutter_bloc.dart'; +export 'package:eatvio_app/core/constants/constants.dart'; +export 'package:eatvio_app/core/errors/exceptions.dart'; +export 'package:eatvio_app/core/network/network_info.dart'; +export 'package:eatvio_app/core/utils/image_constant.dart'; +export 'package:eatvio_app/core/utils/logger.dart'; +export 'package:eatvio_app/core/utils/navigator_service.dart'; +export 'package:eatvio_app/core/utils/pref_utils.dart'; +export 'package:eatvio_app/core/utils/size_utils.dart'; +export 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; +export 'package:eatvio_app/localization/app_localization.dart'; +export 'package:eatvio_app/routes/app_routes.dart'; +export 'package:eatvio_app/theme/app_decoration.dart'; +export 'package:eatvio_app/theme/custom_text_style.dart'; +export 'package:eatvio_app/theme/theme_helper.dart'; +export 'package:eatvio_app/widgets/custom_image_view.dart'; +export '../theme/bloc/theme_bloc.dart'; +export '../theme/custom_button_style.dart'; +export 'package:eatvio_app/core/utils/date_time_utils.dart'; diff --git a/lib/core/constants/constants.dart b/lib/core/constants/constants.dart new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/lib/core/constants/constants.dart @@ -0,0 +1 @@ + diff --git a/lib/core/errors/exceptions.dart b/lib/core/errors/exceptions.dart new file mode 100644 index 00000000..d7d4de89 --- /dev/null +++ b/lib/core/errors/exceptions.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/main.dart'; + +class ServerException implements Exception {} + +class CacheException implements Exception {} + +class NetworkException implements Exception {} + +///can be used for throwing [NoInternetException] +class NoInternetException implements Exception { + late String _message; + + NoInternetException([String message = 'NoInternetException Occurred']) { + if (globalMessengerKey.currentState != null) { + globalMessengerKey.currentState! + .showSnackBar(SnackBar(content: Text(message))); + } + this._message = message; + } + + @override + String toString() { + return _message; + } +} diff --git a/lib/core/errors/failures.dart b/lib/core/errors/failures.dart new file mode 100644 index 00000000..a96b786a --- /dev/null +++ b/lib/core/errors/failures.dart @@ -0,0 +1,8 @@ +abstract class Failure {} + +// General failures +class ServerFailure extends Failure {} + +class CacheFailure extends Failure {} + +class NetworkFailure extends Failure {} diff --git a/lib/core/network/network_info.dart b/lib/core/network/network_info.dart new file mode 100644 index 00000000..c92c5215 --- /dev/null +++ b/lib/core/network/network_info.dart @@ -0,0 +1,47 @@ +import 'package:connectivity_plus/connectivity_plus.dart'; + +// For checking internet connectivity +abstract class NetworkInfoI { + Future isConnected(); + + Future get connectivityResult; + + Stream get onConnectivityChanged; +} + +class NetworkInfo implements NetworkInfoI { + Connectivity connectivity; + + static final NetworkInfo _networkInfo = NetworkInfo._internal(Connectivity()); + + factory NetworkInfo() { + return _networkInfo; + } + + NetworkInfo._internal(this.connectivity) { + connectivity = this.connectivity; + } + + ///checks internet is connected or not + ///returns [true] if internet is connected + ///else it will return [false] + @override + Future isConnected() async { + final result = await connectivity.checkConnectivity(); + if (result != ConnectivityResult.none) { + return true; + } + return false; + } + + // to check type of internet connectivity + @override + Future get connectivityResult async { + return connectivity.checkConnectivity(); + } + + //check the type on internet connection on changed of internet connection + @override + Stream get onConnectivityChanged => + connectivity.onConnectivityChanged; +} diff --git a/lib/core/utils/date_time_utils.dart b/lib/core/utils/date_time_utils.dart new file mode 100644 index 00000000..b121089e --- /dev/null +++ b/lib/core/utils/date_time_utils.dart @@ -0,0 +1,17 @@ +import 'package:intl/date_symbol_data_local.dart'; +import 'package:intl/intl.dart'; + +const String dateTimeFormatPattern = 'dd/MM/yyyy'; + +extension DateTimeExtension on DateTime { + /// Return a string representing [date] formatted according to our locale + String format([ + String pattern = dateTimeFormatPattern, + String? locale, + ]) { + if (locale != null && locale.isNotEmpty) { + initializeDateFormatting(locale); + } + return DateFormat(pattern, locale).format(this); + } +} diff --git a/lib/core/utils/image_constant.dart b/lib/core/utils/image_constant.dart new file mode 100644 index 00000000..edafef3c --- /dev/null +++ b/lib/core/utils/image_constant.dart @@ -0,0 +1,16 @@ +class ImageConstant { + // Image folder path + static String imagePath = 'assets/images'; + + // splash_screen images + static String img2456927096976 = '$imagePath/img_2456927096976.svg'; + + // Common images + static String imgArrowLeft = '$imagePath/img_arrow_left.svg'; + + static String imgLogoEatvio = '$imagePath/img_logo_eatvio.svg'; + + static String imgFavorite = '$imagePath/img_favorite.svg'; + + static String imageNotFound = 'assets/images/image_not_found.png'; +} diff --git a/lib/core/utils/logger.dart b/lib/core/utils/logger.dart new file mode 100644 index 00000000..dab50c2a --- /dev/null +++ b/lib/core/utils/logger.dart @@ -0,0 +1,15 @@ +class Logger { + static LogMode _logMode = LogMode.debug; + + static void init(LogMode mode) { + Logger._logMode = mode; + } + + static void log(dynamic data, {StackTrace? stackTrace}) { + if (_logMode == LogMode.debug) { + print("Error: $data$stackTrace"); + } + } +} + +enum LogMode { debug, live } diff --git a/lib/core/utils/navigator_service.dart b/lib/core/utils/navigator_service.dart new file mode 100644 index 00000000..e5ea8350 --- /dev/null +++ b/lib/core/utils/navigator_service.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +class NavigatorService { + static GlobalKey navigatorKey = GlobalKey(); + + static Future pushNamed(String routeName, + {dynamic arguments}) async { + return navigatorKey.currentState + ?.pushNamed(routeName, arguments: arguments); + } + + static void goBack() { + return navigatorKey.currentState?.pop(); + } + + static Future pushNamedAndRemoveUntil(String routeName, + {bool routePredicate = false, dynamic arguments}) async { + return navigatorKey.currentState?.pushNamedAndRemoveUntil( + routeName, (route) => routePredicate, + arguments: arguments); + } + + static Future popAndPushNamed(String routeName, + {dynamic arguments}) async { + return navigatorKey.currentState + ?.popAndPushNamed(routeName, arguments: arguments); + } +} diff --git a/lib/core/utils/pref_utils.dart b/lib/core/utils/pref_utils.dart new file mode 100644 index 00000000..5a7f1b98 --- /dev/null +++ b/lib/core/utils/pref_utils.dart @@ -0,0 +1,38 @@ +//ignore: unused_import +import 'dart:convert'; +import 'dart:ui'; +import 'package:flutter/scheduler.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class PrefUtils { + static SharedPreferences? _sharedPreferences; + + PrefUtils() { + // init(); + SharedPreferences.getInstance().then((value) { + _sharedPreferences = value; + }); + } + + Future init() async { + _sharedPreferences ??= await SharedPreferences.getInstance(); + print('SharedPreference Initialized'); + } + + ///will clear all the data stored in preference + void clearPreferencesData() async { + _sharedPreferences!.clear(); + } + + Future setThemeData(String value) { + return _sharedPreferences!.setString('themeData', value); + } + + String getThemeData() { + try { + return _sharedPreferences!.getString('themeData')!; + } catch (e) { + return 'primary'; + } + } +} diff --git a/lib/core/utils/progress_dialog_utils.dart b/lib/core/utils/progress_dialog_utils.dart new file mode 100644 index 00000000..b111e966 --- /dev/null +++ b/lib/core/utils/progress_dialog_utils.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/core/app_export.dart'; + +class ProgressDialogUtils { + static bool isProgressVisible = false; + + ///common method for showing progress dialog + static void showProgressDialog( + {BuildContext? context, isCancellable = false}) async { + if (!isProgressVisible && + NavigatorService.navigatorKey.currentState?.overlay?.context != null) { + showDialog( + barrierDismissible: isCancellable, + context: NavigatorService.navigatorKey.currentState!.overlay!.context, + builder: (BuildContext context) { + return Center( + child: CircularProgressIndicator.adaptive( + strokeWidth: 4, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), + ), + ); + }); + isProgressVisible = true; + } + } + + ///common method for hiding progress dialog + static void hideProgressDialog() { + if (isProgressVisible) + Navigator.pop( + NavigatorService.navigatorKey.currentState!.overlay!.context); + isProgressVisible = false; + } +} diff --git a/lib/core/utils/size_utils.dart b/lib/core/utils/size_utils.dart new file mode 100644 index 00000000..ddc30061 --- /dev/null +++ b/lib/core/utils/size_utils.dart @@ -0,0 +1,52 @@ +import 'dart:ui' as ui; +import 'package:flutter/material.dart'; + +// This functions are responsible to make UI responsive across all the mobile devices. + +MediaQueryData mediaQueryData = MediaQueryData.fromWindow(ui.window); + +// These are the Viewport values of your Figma Design. +// These are used in the code as a reference to create your UI Responsively. +const num FIGMA_DESIGN_WIDTH = 375; +const num FIGMA_DESIGN_HEIGHT = 812; +const num FIGMA_DESIGN_STATUS_BAR = 0; + +///This extension is used to set padding/margin (for the top and bottom side) & height of the screen or widget according to the Viewport height. +extension ResponsiveExtension on num { + ///This method is used to get device viewport width. + get _width { + return mediaQueryData.size.width; + } + + ///This method is used to get device viewport height. + get _height { + num statusBar = mediaQueryData.viewPadding.top; + num bottomBar = mediaQueryData.viewPadding.bottom; + num screenHeight = mediaQueryData.size.height - statusBar - bottomBar; + return screenHeight; + } + + ///This method is used to set padding/margin (for the left and Right side) & width of the screen or widget according to the Viewport width. + double get h => ((this * _width) / FIGMA_DESIGN_WIDTH); + + ///This method is used to set padding/margin (for the top and bottom side) & height of the screen or widget according to the Viewport height. + double get v => + (this * _height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR); + + ///This method is used to set smallest px in image height and width + double get adaptSize { + var height = v; + var width = h; + return height < width ? height.toDoubleValue() : width.toDoubleValue(); + } + + ///This method is used to set text font size according to Viewport + double get fSize => adaptSize; +} + +extension FormatExtension on double { + /// Return a [double] value with formatted according to provided fractionDigits + double toDoubleValue({int fractionDigits = 2}) { + return double.parse(this.toStringAsFixed(fractionDigits)); + } +} diff --git a/lib/data/apiClient/api_client.dart b/lib/data/apiClient/api_client.dart new file mode 100644 index 00000000..cd1bf912 --- /dev/null +++ b/lib/data/apiClient/api_client.dart @@ -0,0 +1,3 @@ +import 'package:eatvio_app/core/app_export.dart'; + +class ApiClient {} diff --git a/lib/data/models/selectionPopupModel/selection_popup_model.dart b/lib/data/models/selectionPopupModel/selection_popup_model.dart new file mode 100644 index 00000000..e9aa2c89 --- /dev/null +++ b/lib/data/models/selectionPopupModel/selection_popup_model.dart @@ -0,0 +1,15 @@ +///SelectionPopupModel is common model +///used for setting data into dropdowns +class SelectionPopupModel { + int? id; + String title; + dynamic value; + bool isSelected; + + SelectionPopupModel({ + this.id, + required this.title, + this.value, + this.isSelected = false, + }); +} diff --git a/lib/localization/app_localization.dart b/lib/localization/app_localization.dart new file mode 100644 index 00000000..e72734ef --- /dev/null +++ b/lib/localization/app_localization.dart @@ -0,0 +1,43 @@ +import 'en_us/en_us_translations.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/cupertino.dart'; +import '../core/app_export.dart'; + +class AppLocalization { + AppLocalization(this.locale); + + Locale locale; + + static final Map> _localizedValues = {'en': enUs}; + + static AppLocalization of() { + return Localizations.of( + NavigatorService.navigatorKey.currentContext!, AppLocalization)!; + } + + static List languages() => _localizedValues.keys.toList(); + String getString(String text) => + _localizedValues[locale.languageCode]![text] ?? text; +} + +class AppLocalizationDelegate extends LocalizationsDelegate { + const AppLocalizationDelegate(); + + @override + bool isSupported(Locale locale) => + AppLocalization.languages().contains(locale.languageCode); + + //Returning a SynchronousFuture here because an async "load" operation + //cause an async "load" operation + @override + Future load(Locale locale) { + return SynchronousFuture(AppLocalization(locale)); + } + + @override + bool shouldReload(AppLocalizationDelegate old) => false; +} + +extension LocalizationExtension on String { + String get tr => AppLocalization.of().getString(this); +} diff --git a/lib/localization/en_us/en_us_translations.dart b/lib/localization/en_us/en_us_translations.dart new file mode 100644 index 00000000..d9955be5 --- /dev/null +++ b/lib/localization/en_us/en_us_translations.dart @@ -0,0 +1,59 @@ +final Map enUs = { + // date_of_birth Screen + "lbl": "Дата Рождения", "lbl_01_01_2000": "01.01.2000", + + // city_of_living Screen + "lbl4": "Страна", "lbl5": "Россия", "lbl6": "Город", "lbl7": "Москва", + "msg": "Место проживания", + + // body_circumferences Screen + "lbl10": "Обхват бедр", "lbl8": "Обхват груди", "lbl9": "Обхват талии", + "msg2": "Первичные замеры", + + // weight Screen + "lbl11": "Замер Веса", "lbl12": "Ваш вес:", "lbl_70": "70", + + // allergies Screen + "msg3": "Наличие аллергии", + + // medicine_intake Screen + "msg6": "Принимаете ли вы лекарства или бады?", + + // gender Screen + "lbl13": "Ваш пол?", + + // blood_pressure Screen + "lbl14": "Нет", + "msg10": "Есть ли у вас склонность к гипертании?", + "msg7": "Ваше артериальное давление?", + "msg8": "Средние показатели давления:", + "msg9": "Есть ли у вас склонность к гипо?", + + // favorite_sports Screen + "msg11": "Ваши спортивные увлечения?", + + // favorite_foods Screen + "lbl15": "Люблю продукты:", + "msg12": "Ваши любимые/нелюбимые продукты питания?", + "msg13": "Нелюбимые продукты:", + + // schedule Screen + "lbl16": "Ваш режим дня?", + "msg14": + "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:", + + // additional_information Screen + "msg15": "Дополнительная информация:", + "msg16": "Введите любую дополнительную информацию на своё усмотрение:", + + // language_select Screen + "lbl_english": "English", "msg17": "Предпочетаемый язык общения?", + + // Common String + "lbl2": "Продолжить", "lbl3": "Пропустить", "lbl_60": "60", "lbl_90": "90", + "msg4": "Заполните информацию:", "msg5": "Введите информацию...", + +// Network Error String + "msg_network_err": "Network Error", + "msg_something_went_wrong": "Something Went Wrong!", +}; diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 00000000..e56d855b --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'core/app_export.dart'; + +var globalMessengerKey = GlobalKey(); +void main() { + WidgetsFlutterBinding.ensureInitialized(); + Future.wait([ + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + ]), + PrefUtils().init() + ]).then((value) { + runApp(MyApp()); + }); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => ThemeBloc( + ThemeState( + themeType: PrefUtils().getThemeData(), + ), + ), + child: BlocBuilder( + builder: (context, state) { + return MaterialApp( + theme: theme, + title: 'eatvio_app', + navigatorKey: NavigatorService.navigatorKey, + debugShowCheckedModeBanner: false, + localizationsDelegates: [ + AppLocalizationDelegate(), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [ + Locale( + 'en', + '', + ), + ], + initialRoute: AppRoutes.initialRoute, + routes: AppRoutes.routes, + ); + }, + ), + ); + } +} diff --git a/lib/presentation/additional_information_screen/additional_information_screen.dart b/lib/presentation/additional_information_screen/additional_information_screen.dart new file mode 100644 index 00000000..4f1b71e3 --- /dev/null +++ b/lib/presentation/additional_information_screen/additional_information_screen.dart @@ -0,0 +1,122 @@ +import 'bloc/additional_information_bloc.dart'; +import 'models/additional_information_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class AdditionalInformationScreen extends StatelessWidget { + const AdditionalInformationScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => AdditionalInformationBloc( + AdditionalInformationState( + additionalInformationModelObj: AdditionalInformationModel())) + ..add(AdditionalInformationInitialEvent()), + child: AdditionalInformationScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + _buildProgressIndicator(context), + SizedBox(height: 20.v), + SizedBox( + width: 192.h, + child: Text("msg15".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: theme.textTheme.headlineSmall)), + SizedBox(height: 73.v), + _buildNinetyThree(context), + Spacer(), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 31.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildProgressIndicator(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), + decoration: AppDecoration.outlinePrimary + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Container( + height: 8.v, + width: 332.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular(4.h), + border: + Border.all(color: theme.colorScheme.primary, width: 1.h)))); + } + + /// Section Widget + Widget _buildNinetyThree(BuildContext context) { + return SizedBox( + height: 257.v, + width: 343.h, + child: Stack(alignment: Alignment.center, children: [ + Align( + alignment: Alignment.topLeft, + child: Padding( + padding: EdgeInsets.only(left: 10.h, top: 69.v), + child: Text("msg5".tr, style: theme.textTheme.bodyLarge))), + Align( + alignment: Alignment.center, + child: Column(mainAxisSize: MainAxisSize.min, children: [ + Container( + width: 294.h, + margin: EdgeInsets.only(left: 24.h, right: 23.h), + child: Text("msg16".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: CustomTextStyles.titleMediumSegoeUI)), + SizedBox(height: 10.v), + BlocSelector( + selector: (state) => state.editTextController, + builder: (context, editTextController) { + return CustomTextFormField( + controller: editTextController, + textInputAction: TextInputAction.done); + }) + ])) + ])); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/additional_information_screen/bloc/additional_information_bloc.dart b/lib/presentation/additional_information_screen/bloc/additional_information_bloc.dart new file mode 100644 index 00000000..e2b62253 --- /dev/null +++ b/lib/presentation/additional_information_screen/bloc/additional_information_bloc.dart @@ -0,0 +1,22 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/additional_information_screen/models/additional_information_model.dart'; +part 'additional_information_event.dart'; +part 'additional_information_state.dart'; + +/// A bloc that manages the state of a AdditionalInformation according to the event that is dispatched to it. +class AdditionalInformationBloc + extends Bloc { + AdditionalInformationBloc(AdditionalInformationState initialState) + : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + AdditionalInformationInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith(editTextController: TextEditingController())); + } +} diff --git a/lib/presentation/additional_information_screen/bloc/additional_information_event.dart b/lib/presentation/additional_information_screen/bloc/additional_information_event.dart new file mode 100644 index 00000000..71494f83 --- /dev/null +++ b/lib/presentation/additional_information_screen/bloc/additional_information_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'additional_information_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///AdditionalInformation widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class AdditionalInformationEvent extends Equatable {} + +/// Event that is dispatched when the AdditionalInformation widget is first created. +class AdditionalInformationInitialEvent extends AdditionalInformationEvent { + @override + List get props => []; +} diff --git a/lib/presentation/additional_information_screen/bloc/additional_information_state.dart b/lib/presentation/additional_information_screen/bloc/additional_information_state.dart new file mode 100644 index 00000000..08dd10c4 --- /dev/null +++ b/lib/presentation/additional_information_screen/bloc/additional_information_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'additional_information_bloc.dart'; + +/// Represents the state of AdditionalInformation in the application. +class AdditionalInformationState extends Equatable { + AdditionalInformationState({ + this.editTextController, + this.additionalInformationModelObj, + }); + + TextEditingController? editTextController; + + AdditionalInformationModel? additionalInformationModelObj; + + @override + List get props => [ + editTextController, + additionalInformationModelObj, + ]; + AdditionalInformationState copyWith({ + TextEditingController? editTextController, + AdditionalInformationModel? additionalInformationModelObj, + }) { + return AdditionalInformationState( + editTextController: editTextController ?? this.editTextController, + additionalInformationModelObj: + additionalInformationModelObj ?? this.additionalInformationModelObj, + ); + } +} diff --git a/lib/presentation/additional_information_screen/models/additional_information_model.dart b/lib/presentation/additional_information_screen/models/additional_information_model.dart new file mode 100644 index 00000000..bc31be45 --- /dev/null +++ b/lib/presentation/additional_information_screen/models/additional_information_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [additional_information_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class AdditionalInformationModel extends Equatable { + AdditionalInformationModel() {} + + AdditionalInformationModel copyWith() { + return AdditionalInformationModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/allergies_screen/allergies_screen.dart b/lib/presentation/allergies_screen/allergies_screen.dart new file mode 100644 index 00000000..bb1f4d5e --- /dev/null +++ b/lib/presentation/allergies_screen/allergies_screen.dart @@ -0,0 +1,95 @@ +import 'bloc/allergies_bloc.dart'; +import 'models/allergies_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class AllergiesScreen extends StatelessWidget { + const AllergiesScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel())) + ..add(AllergiesInitialEvent()), + child: AllergiesScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.41, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 22.v), + Text("msg3".tr, style: CustomTextStyles.headlineSmallMulish), + Spacer(flex: 36), + _buildNinetyThree(context), + Spacer(flex: 63), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 31.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildNinetyThree(BuildContext context) { + return Column(children: [ + Text("msg4".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.enterInformationController, + builder: (context, enterInformationController) { + return CustomTextFormField( + controller: enterInformationController, + hintText: "msg5".tr, + textInputAction: TextInputAction.done, + maxLines: 8); + }) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/allergies_screen/bloc/allergies_bloc.dart b/lib/presentation/allergies_screen/bloc/allergies_bloc.dart new file mode 100644 index 00000000..d529d958 --- /dev/null +++ b/lib/presentation/allergies_screen/bloc/allergies_bloc.dart @@ -0,0 +1,20 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/allergies_screen/models/allergies_model.dart'; +part 'allergies_event.dart'; +part 'allergies_state.dart'; + +/// A bloc that manages the state of a Allergies according to the event that is dispatched to it. +class AllergiesBloc extends Bloc { + AllergiesBloc(AllergiesState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + AllergiesInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith(enterInformationController: TextEditingController())); + } +} diff --git a/lib/presentation/allergies_screen/bloc/allergies_event.dart b/lib/presentation/allergies_screen/bloc/allergies_event.dart new file mode 100644 index 00000000..8892cc35 --- /dev/null +++ b/lib/presentation/allergies_screen/bloc/allergies_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'allergies_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Allergies widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class AllergiesEvent extends Equatable {} + +/// Event that is dispatched when the Allergies widget is first created. +class AllergiesInitialEvent extends AllergiesEvent { + @override + List get props => []; +} diff --git a/lib/presentation/allergies_screen/bloc/allergies_state.dart b/lib/presentation/allergies_screen/bloc/allergies_state.dart new file mode 100644 index 00000000..a63c52d8 --- /dev/null +++ b/lib/presentation/allergies_screen/bloc/allergies_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'allergies_bloc.dart'; + +/// Represents the state of Allergies in the application. +class AllergiesState extends Equatable { + AllergiesState({ + this.enterInformationController, + this.allergiesModelObj, + }); + + TextEditingController? enterInformationController; + + AllergiesModel? allergiesModelObj; + + @override + List get props => [ + enterInformationController, + allergiesModelObj, + ]; + AllergiesState copyWith({ + TextEditingController? enterInformationController, + AllergiesModel? allergiesModelObj, + }) { + return AllergiesState( + enterInformationController: + enterInformationController ?? this.enterInformationController, + allergiesModelObj: allergiesModelObj ?? this.allergiesModelObj, + ); + } +} diff --git a/lib/presentation/allergies_screen/models/allergies_model.dart b/lib/presentation/allergies_screen/models/allergies_model.dart new file mode 100644 index 00000000..64649efe --- /dev/null +++ b/lib/presentation/allergies_screen/models/allergies_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [allergies_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class AllergiesModel extends Equatable { + AllergiesModel() {} + + AllergiesModel copyWith() { + return AllergiesModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/app_navigation_screen/app_navigation_screen.dart b/lib/presentation/app_navigation_screen/app_navigation_screen.dart new file mode 100644 index 00000000..a04ad84a --- /dev/null +++ b/lib/presentation/app_navigation_screen/app_navigation_screen.dart @@ -0,0 +1,246 @@ +import 'bloc/app_navigation_bloc.dart'; +import 'models/app_navigation_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class AppNavigationScreen extends StatelessWidget { + const AppNavigationScreen({Key? key}) + : super( + key: key, + ); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => AppNavigationBloc(AppNavigationState( + appNavigationModelObj: AppNavigationModel(), + )) + ..add(AppNavigationInitialEvent()), + child: AppNavigationScreen(), + ); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + + return BlocBuilder( + builder: (context, state) { + return SafeArea( + child: Scaffold( + backgroundColor: Color(0XFFFFFFFF), + body: SizedBox( + width: double.maxFinite, + child: Column( + children: [ + _buildAppNavigation(context), + Expanded( + child: SingleChildScrollView( + child: Container( + decoration: BoxDecoration( + color: Color(0XFFFFFFFF), + ), + child: Column( + children: [ + _buildScreenTitle( + context, + screenTitle: "date_of_birth".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.dateOfBirthScreen), + ), + _buildScreenTitle( + context, + screenTitle: "city_of_living".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.cityOfLivingScreen), + ), + _buildScreenTitle( + context, + screenTitle: "body_circumferences".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.bodyCircumferencesScreen), + ), + _buildScreenTitle( + context, + screenTitle: "weight".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.weightScreen), + ), + _buildScreenTitle( + context, + screenTitle: "allergies".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.allergiesScreen), + ), + _buildScreenTitle( + context, + screenTitle: "medicine_intake".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.medicineIntakeScreen), + ), + _buildScreenTitle( + context, + screenTitle: "splash_screen".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.splashScreen), + ), + _buildScreenTitle( + context, + screenTitle: "gender".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.genderScreen), + ), + _buildScreenTitle( + context, + screenTitle: "blood_pressure".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.bloodPressureScreen), + ), + _buildScreenTitle( + context, + screenTitle: "favorite_sports".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.favoriteSportsScreen), + ), + _buildScreenTitle( + context, + screenTitle: "favorite_foods".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.favoriteFoodsScreen), + ), + _buildScreenTitle( + context, + screenTitle: "schedule".tr, + onTapScreenTitle: () => + onTapScreenTitle(AppRoutes.scheduleScreen), + ), + _buildScreenTitle( + context, + screenTitle: "additional_information".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.additionalInformationScreen), + ), + _buildScreenTitle( + context, + screenTitle: "language_select".tr, + onTapScreenTitle: () => onTapScreenTitle( + AppRoutes.languageSelectScreen), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ); + }, + ); + } + + /// Section Widget + Widget _buildAppNavigation(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: Color(0XFFFFFFFF), + ), + child: Column( + children: [ + SizedBox(height: 10.v), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20.h), + child: Text( + "App Navigation".tr, + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0XFF000000), + fontSize: 20.fSize, + fontFamily: 'Roboto', + fontWeight: FontWeight.w400, + ), + ), + ), + ), + SizedBox(height: 10.v), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 20.h), + child: Text( + "Check your app's UI from the below demo screens of your app." + .tr, + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0XFF888888), + fontSize: 16.fSize, + fontFamily: 'Roboto', + fontWeight: FontWeight.w400, + ), + ), + ), + ), + SizedBox(height: 5.v), + Divider( + height: 1.v, + thickness: 1.v, + color: Color(0XFF000000), + ), + ], + ), + ); + } + + /// Common widget + Widget _buildScreenTitle( + BuildContext context, { + required String screenTitle, + Function? onTapScreenTitle, + }) { + return GestureDetector( + onTap: () { + onTapScreenTitle!.call(); + }, + child: Container( + decoration: BoxDecoration( + color: Color(0XFFFFFFFF), + ), + child: Column( + children: [ + SizedBox(height: 10.v), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20.h), + child: Text( + screenTitle, + textAlign: TextAlign.center, + style: TextStyle( + color: Color(0XFF000000), + fontSize: 20.fSize, + fontFamily: 'Roboto', + fontWeight: FontWeight.w400, + ), + ), + ), + ), + SizedBox(height: 10.v), + SizedBox(height: 5.v), + Divider( + height: 1.v, + thickness: 1.v, + color: Color(0XFF888888), + ), + ], + ), + ), + ); + } + + /// Common click event + void onTapScreenTitle(String routeName) { + NavigatorService.pushNamed(routeName); + } +} diff --git a/lib/presentation/app_navigation_screen/bloc/app_navigation_bloc.dart b/lib/presentation/app_navigation_screen/bloc/app_navigation_bloc.dart new file mode 100644 index 00000000..3ece4d2b --- /dev/null +++ b/lib/presentation/app_navigation_screen/bloc/app_navigation_bloc.dart @@ -0,0 +1,18 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/app_navigation_screen/models/app_navigation_model.dart'; +part 'app_navigation_event.dart'; +part 'app_navigation_state.dart'; + +/// A bloc that manages the state of a AppNavigation according to the event that is dispatched to it. +class AppNavigationBloc extends Bloc { + AppNavigationBloc(AppNavigationState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + AppNavigationInitialEvent event, + Emitter emit, + ) async {} +} diff --git a/lib/presentation/app_navigation_screen/bloc/app_navigation_event.dart b/lib/presentation/app_navigation_screen/bloc/app_navigation_event.dart new file mode 100644 index 00000000..649738e6 --- /dev/null +++ b/lib/presentation/app_navigation_screen/bloc/app_navigation_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'app_navigation_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///AppNavigation widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class AppNavigationEvent extends Equatable {} + +/// Event that is dispatched when the AppNavigation widget is first created. +class AppNavigationInitialEvent extends AppNavigationEvent { + @override + List get props => []; +} diff --git a/lib/presentation/app_navigation_screen/bloc/app_navigation_state.dart b/lib/presentation/app_navigation_screen/bloc/app_navigation_state.dart new file mode 100644 index 00000000..2ee33461 --- /dev/null +++ b/lib/presentation/app_navigation_screen/bloc/app_navigation_state.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +part of 'app_navigation_bloc.dart'; + +/// Represents the state of AppNavigation in the application. +class AppNavigationState extends Equatable { + AppNavigationState({this.appNavigationModelObj}); + + AppNavigationModel? appNavigationModelObj; + + @override + List get props => [ + appNavigationModelObj, + ]; + AppNavigationState copyWith({AppNavigationModel? appNavigationModelObj}) { + return AppNavigationState( + appNavigationModelObj: + appNavigationModelObj ?? this.appNavigationModelObj, + ); + } +} diff --git a/lib/presentation/app_navigation_screen/models/app_navigation_model.dart b/lib/presentation/app_navigation_screen/models/app_navigation_model.dart new file mode 100644 index 00000000..405bdc8a --- /dev/null +++ b/lib/presentation/app_navigation_screen/models/app_navigation_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [app_navigation_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class AppNavigationModel extends Equatable { + AppNavigationModel() {} + + AppNavigationModel copyWith() { + return AppNavigationModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart new file mode 100644 index 00000000..139d43dd --- /dev/null +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart @@ -0,0 +1,41 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/blood_pressure_screen/models/blood_pressure_model.dart'; +part 'blood_pressure_event.dart'; +part 'blood_pressure_state.dart'; + +/// A bloc that manages the state of a BloodPressure according to the event that is dispatched to it. +class BloodPressureBloc extends Bloc { + BloodPressureBloc(BloodPressureState initialState) : super(initialState) { + on(_onInitialize); + on(_changeDropDown); + } + + _changeDropDown( + ChangeDropDownEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedDropDownValue: event.value)); + } + + List fillDropdownItemList() { + return [ + SelectionPopupModel(id: 1, title: "Item One", isSelected: true), + SelectionPopupModel(id: 2, title: "Item Two"), + SelectionPopupModel(id: 3, title: "Item Three") + ]; + } + + _onInitialize( + BloodPressureInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + valueController: TextEditingController(), + valueController1: TextEditingController())); + emit(state.copyWith( + bloodPressureModelObj: state.bloodPressureModelObj + ?.copyWith(dropdownItemList: fillDropdownItemList()))); + } +} diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart new file mode 100644 index 00000000..98e86810 --- /dev/null +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'blood_pressure_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///BloodPressure widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class BloodPressureEvent extends Equatable {} + +/// Event that is dispatched when the BloodPressure widget is first created. +class BloodPressureInitialEvent extends BloodPressureEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends BloodPressureEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart new file mode 100644 index 00000000..e43ee812 --- /dev/null +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart @@ -0,0 +1,44 @@ +// ignore_for_file: must_be_immutable + +part of 'blood_pressure_bloc.dart'; + +/// Represents the state of BloodPressure in the application. +class BloodPressureState extends Equatable { + BloodPressureState({ + this.valueController, + this.valueController1, + this.selectedDropDownValue, + this.bloodPressureModelObj, + }); + + TextEditingController? valueController; + + TextEditingController? valueController1; + + SelectionPopupModel? selectedDropDownValue; + + BloodPressureModel? bloodPressureModelObj; + + @override + List get props => [ + valueController, + valueController1, + selectedDropDownValue, + bloodPressureModelObj, + ]; + BloodPressureState copyWith({ + TextEditingController? valueController, + TextEditingController? valueController1, + SelectionPopupModel? selectedDropDownValue, + BloodPressureModel? bloodPressureModelObj, + }) { + return BloodPressureState( + valueController: valueController ?? this.valueController, + valueController1: valueController1 ?? this.valueController1, + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + bloodPressureModelObj: + bloodPressureModelObj ?? this.bloodPressureModelObj, + ); + } +} diff --git a/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart new file mode 100644 index 00000000..5dcd2740 --- /dev/null +++ b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart @@ -0,0 +1,152 @@ +import 'bloc/blood_pressure_bloc.dart'; +import 'models/blood_pressure_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class BloodPressureScreen extends StatelessWidget { + const BloodPressureScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => BloodPressureBloc( + BloodPressureState(bloodPressureModelObj: BloodPressureModel())) + ..add(BloodPressureInitialEvent()), + child: BloodPressureScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Padding( + padding: EdgeInsets.symmetric(horizontal: 4.h), + child: Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.63, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400))))), + SizedBox(height: 21.v), + SizedBox( + width: 224.h, + child: Text("msg7".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: theme.textTheme.headlineSmall)), + SizedBox(height: 77.v), + _buildThirtyThree(context), + SizedBox(height: 22.v), + Text("msg9".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + Padding( + padding: EdgeInsets.symmetric(horizontal: 4.h), + child: BlocSelector( + selector: (state) => state.valueController1, + builder: (context, valueController1) { + return CustomTextFormField( + controller: valueController1, + hintText: "lbl_60".tr, + textInputAction: TextInputAction.done); + })), + SizedBox(height: 22.v), + Text("msg10".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + Padding( + padding: EdgeInsets.symmetric(horizontal: 4.h), + child: BlocSelector( + selector: (state) => state.bloodPressureModelObj, + builder: (context, bloodPressureModelObj) { + return CustomDropDown( + icon: Container( + margin: EdgeInsets.fromLTRB( + 30.h, 11.v, 13.h, 11.v), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(1.h)), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize)), + hintText: "lbl14".tr, + items: + bloodPressureModelObj?.dropdownItemList ?? + [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }); + })), + Spacer(), + CustomOutlinedButton( + text: "lbl2".tr.toUpperCase(), + margin: EdgeInsets.symmetric(horizontal: 4.h)), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildThirtyThree(BuildContext context) { + return Container( + margin: EdgeInsets.only(right: 1.h), + padding: EdgeInsets.symmetric(horizontal: 3.h), + child: Column(children: [ + Text("msg8".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.valueController, + builder: (context, valueController) { + return CustomTextFormField( + controller: valueController, hintText: "lbl_90".tr); + }) + ])); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart b/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart new file mode 100644 index 00000000..1e6c2fa3 --- /dev/null +++ b/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; + +/// This class defines the variables used in the [blood_pressure_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class BloodPressureModel extends Equatable { + BloodPressureModel({this.dropdownItemList = const []}) {} + + List dropdownItemList; + + BloodPressureModel copyWith({List? dropdownItemList}) { + return BloodPressureModel( + dropdownItemList: dropdownItemList ?? this.dropdownItemList, + ); + } + + @override + List get props => [dropdownItemList]; +} diff --git a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart new file mode 100644 index 00000000..5b626c60 --- /dev/null +++ b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart @@ -0,0 +1,25 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/body_circumferences_screen/models/body_circumferences_model.dart'; +part 'body_circumferences_event.dart'; +part 'body_circumferences_state.dart'; + +/// A bloc that manages the state of a BodyCircumferences according to the event that is dispatched to it. +class BodyCircumferencesBloc + extends Bloc { + BodyCircumferencesBloc(BodyCircumferencesState initialState) + : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + BodyCircumferencesInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + valueController: TextEditingController(), + valueController1: TextEditingController(), + valueController2: TextEditingController())); + } +} diff --git a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_event.dart b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_event.dart new file mode 100644 index 00000000..d164270e --- /dev/null +++ b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'body_circumferences_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///BodyCircumferences widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class BodyCircumferencesEvent extends Equatable {} + +/// Event that is dispatched when the BodyCircumferences widget is first created. +class BodyCircumferencesInitialEvent extends BodyCircumferencesEvent { + @override + List get props => []; +} diff --git a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart new file mode 100644 index 00000000..9c952fb0 --- /dev/null +++ b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart @@ -0,0 +1,43 @@ +// ignore_for_file: must_be_immutable + +part of 'body_circumferences_bloc.dart'; + +/// Represents the state of BodyCircumferences in the application. +class BodyCircumferencesState extends Equatable { + BodyCircumferencesState({ + this.valueController, + this.valueController1, + this.valueController2, + this.bodyCircumferencesModelObj, + }); + + TextEditingController? valueController; + + TextEditingController? valueController1; + + TextEditingController? valueController2; + + BodyCircumferencesModel? bodyCircumferencesModelObj; + + @override + List get props => [ + valueController, + valueController1, + valueController2, + bodyCircumferencesModelObj, + ]; + BodyCircumferencesState copyWith({ + TextEditingController? valueController, + TextEditingController? valueController1, + TextEditingController? valueController2, + BodyCircumferencesModel? bodyCircumferencesModelObj, + }) { + return BodyCircumferencesState( + valueController: valueController ?? this.valueController, + valueController1: valueController1 ?? this.valueController1, + valueController2: valueController2 ?? this.valueController2, + bodyCircumferencesModelObj: + bodyCircumferencesModelObj ?? this.bodyCircumferencesModelObj, + ); + } +} diff --git a/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart new file mode 100644 index 00000000..9d4d775b --- /dev/null +++ b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart @@ -0,0 +1,116 @@ +import 'bloc/body_circumferences_bloc.dart'; +import 'models/body_circumferences_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class BodyCircumferencesScreen extends StatelessWidget { + const BodyCircumferencesScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => BodyCircumferencesBloc(BodyCircumferencesState( + bodyCircumferencesModelObj: BodyCircumferencesModel())) + ..add(BodyCircumferencesInitialEvent()), + child: BodyCircumferencesScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.29, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 39.v), + Text("msg2".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 93.v), + _buildTwentySeven(context), + SizedBox(height: 19.v), + Text("lbl9".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 5.v), + BlocSelector( + selector: (state) => state.valueController1, + builder: (context, valueController1) { + return CustomTextFormField( + controller: valueController1, + hintText: "lbl_60".tr); + }), + SizedBox(height: 21.v), + Text("lbl10".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.valueController2, + builder: (context, valueController2) { + return CustomTextFormField( + controller: valueController2, + hintText: "lbl_90".tr, + textInputAction: TextInputAction.done); + }), + Spacer(), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildTwentySeven(BuildContext context) { + return Column(children: [ + Text("lbl8".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.valueController, + builder: (context, valueController) { + return CustomTextFormField( + controller: valueController, hintText: "lbl_90".tr); + }) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart b/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart new file mode 100644 index 00000000..3d6dd7c9 --- /dev/null +++ b/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [body_circumferences_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class BodyCircumferencesModel extends Equatable { + BodyCircumferencesModel() {} + + BodyCircumferencesModel copyWith() { + return BodyCircumferencesModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart b/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart new file mode 100644 index 00000000..75ebb7de --- /dev/null +++ b/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart @@ -0,0 +1,55 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/city_of_living_screen/models/city_of_living_model.dart'; +part 'city_of_living_event.dart'; +part 'city_of_living_state.dart'; + +/// A bloc that manages the state of a CityOfLiving according to the event that is dispatched to it. +class CityOfLivingBloc extends Bloc { + CityOfLivingBloc(CityOfLivingState initialState) : super(initialState) { + on(_onInitialize); + on(_changeDropDown); + on(_changeDropDown1); + } + + _onInitialize( + CityOfLivingInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + cityOfLivingModelObj: state.cityOfLivingModelObj?.copyWith( + dropdownItemList: fillDropdownItemList(), + dropdownItemList1: fillDropdownItemList1()))); + } + + _changeDropDown( + ChangeDropDownEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedDropDownValue: event.value)); + } + + _changeDropDown1( + ChangeDropDown1Event event, + Emitter emit, + ) { + emit(state.copyWith(selectedDropDownValue1: event.value)); + } + + List fillDropdownItemList() { + return [ + SelectionPopupModel(id: 1, title: "Item One", isSelected: true), + SelectionPopupModel(id: 2, title: "Item Two"), + SelectionPopupModel(id: 3, title: "Item Three") + ]; + } + + List fillDropdownItemList1() { + return [ + SelectionPopupModel(id: 1, title: "Item One", isSelected: true), + SelectionPopupModel(id: 2, title: "Item Two"), + SelectionPopupModel(id: 3, title: "Item Three") + ]; + } +} diff --git a/lib/presentation/city_of_living_screen/bloc/city_of_living_event.dart b/lib/presentation/city_of_living_screen/bloc/city_of_living_event.dart new file mode 100644 index 00000000..c12d13e3 --- /dev/null +++ b/lib/presentation/city_of_living_screen/bloc/city_of_living_event.dart @@ -0,0 +1,40 @@ +// ignore_for_file: must_be_immutable + +part of 'city_of_living_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///CityOfLiving widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class CityOfLivingEvent extends Equatable {} + +/// Event that is dispatched when the CityOfLiving widget is first created. +class CityOfLivingInitialEvent extends CityOfLivingEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends CityOfLivingEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} + +///event for dropdown selection +class ChangeDropDown1Event extends CityOfLivingEvent { + ChangeDropDown1Event({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/city_of_living_screen/bloc/city_of_living_state.dart b/lib/presentation/city_of_living_screen/bloc/city_of_living_state.dart new file mode 100644 index 00000000..b7967ccf --- /dev/null +++ b/lib/presentation/city_of_living_screen/bloc/city_of_living_state.dart @@ -0,0 +1,38 @@ +// ignore_for_file: must_be_immutable + +part of 'city_of_living_bloc.dart'; + +/// Represents the state of CityOfLiving in the application. +class CityOfLivingState extends Equatable { + CityOfLivingState({ + this.selectedDropDownValue, + this.selectedDropDownValue1, + this.cityOfLivingModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + SelectionPopupModel? selectedDropDownValue1; + + CityOfLivingModel? cityOfLivingModelObj; + + @override + List get props => [ + selectedDropDownValue, + selectedDropDownValue1, + cityOfLivingModelObj, + ]; + CityOfLivingState copyWith({ + SelectionPopupModel? selectedDropDownValue, + SelectionPopupModel? selectedDropDownValue1, + CityOfLivingModel? cityOfLivingModelObj, + }) { + return CityOfLivingState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + selectedDropDownValue1: + selectedDropDownValue1 ?? this.selectedDropDownValue1, + cityOfLivingModelObj: cityOfLivingModelObj ?? this.cityOfLivingModelObj, + ); + } +} diff --git a/lib/presentation/city_of_living_screen/city_of_living_screen.dart b/lib/presentation/city_of_living_screen/city_of_living_screen.dart new file mode 100644 index 00000000..6b37c010 --- /dev/null +++ b/lib/presentation/city_of_living_screen/city_of_living_screen.dart @@ -0,0 +1,126 @@ +import 'bloc/city_of_living_bloc.dart'; +import 'models/city_of_living_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class CityOfLivingScreen extends StatelessWidget { + const CityOfLivingScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => CityOfLivingBloc( + CityOfLivingState(cityOfLivingModelObj: CityOfLivingModel())) + ..add(CityOfLivingInitialEvent()), + child: CityOfLivingScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.23, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 39.v), + Text("msg".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 34), + Text("lbl4".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.cityOfLivingModelObj, + builder: (context, cityOfLivingModelObj) { + return CustomDropDown( + icon: Container( + margin: + EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1.h)), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize)), + hintText: "lbl5".tr, + items: cityOfLivingModelObj?.dropdownItemList ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }); + }), + SizedBox(height: 22.v), + Text("lbl6".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.cityOfLivingModelObj, + builder: (context, cityOfLivingModelObj) { + return CustomDropDown( + icon: Container( + margin: + EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1.h)), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize)), + hintText: "lbl7".tr, + items: + cityOfLivingModelObj?.dropdownItemList1 ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDown1Event(value: value)); + }); + }), + Spacer(flex: 65), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/city_of_living_screen/models/city_of_living_model.dart b/lib/presentation/city_of_living_screen/models/city_of_living_model.dart new file mode 100644 index 00000000..a20b013c --- /dev/null +++ b/lib/presentation/city_of_living_screen/models/city_of_living_model.dart @@ -0,0 +1,30 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; + +/// This class defines the variables used in the [city_of_living_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class CityOfLivingModel extends Equatable { + CityOfLivingModel({ + this.dropdownItemList = const [], + this.dropdownItemList1 = const [], + }) {} + + List dropdownItemList; + + List dropdownItemList1; + + CityOfLivingModel copyWith({ + List? dropdownItemList, + List? dropdownItemList1, + }) { + return CityOfLivingModel( + dropdownItemList: dropdownItemList ?? this.dropdownItemList, + dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1, + ); + } + + @override + List get props => [dropdownItemList, dropdownItemList1]; +} diff --git a/lib/presentation/date_of_birth_screen/bloc/date_of_birth_bloc.dart b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_bloc.dart new file mode 100644 index 00000000..71ae39b8 --- /dev/null +++ b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_bloc.dart @@ -0,0 +1,18 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/date_of_birth_screen/models/date_of_birth_model.dart'; +part 'date_of_birth_event.dart'; +part 'date_of_birth_state.dart'; + +/// A bloc that manages the state of a DateOfBirth according to the event that is dispatched to it. +class DateOfBirthBloc extends Bloc { + DateOfBirthBloc(DateOfBirthState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + DateOfBirthInitialEvent event, + Emitter emit, + ) async {} +} diff --git a/lib/presentation/date_of_birth_screen/bloc/date_of_birth_event.dart b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_event.dart new file mode 100644 index 00000000..0d6938b5 --- /dev/null +++ b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'date_of_birth_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///DateOfBirth widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class DateOfBirthEvent extends Equatable {} + +/// Event that is dispatched when the DateOfBirth widget is first created. +class DateOfBirthInitialEvent extends DateOfBirthEvent { + @override + List get props => []; +} diff --git a/lib/presentation/date_of_birth_screen/bloc/date_of_birth_state.dart b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_state.dart new file mode 100644 index 00000000..e54b82c6 --- /dev/null +++ b/lib/presentation/date_of_birth_screen/bloc/date_of_birth_state.dart @@ -0,0 +1,20 @@ +// ignore_for_file: must_be_immutable + +part of 'date_of_birth_bloc.dart'; + +/// Represents the state of DateOfBirth in the application. +class DateOfBirthState extends Equatable { + DateOfBirthState({this.dateOfBirthModelObj}); + + DateOfBirthModel? dateOfBirthModelObj; + + @override + List get props => [ + dateOfBirthModelObj, + ]; + DateOfBirthState copyWith({DateOfBirthModel? dateOfBirthModelObj}) { + return DateOfBirthState( + dateOfBirthModelObj: dateOfBirthModelObj ?? this.dateOfBirthModelObj, + ); + } +} diff --git a/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart new file mode 100644 index 00000000..3e109d6a --- /dev/null +++ b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart @@ -0,0 +1,114 @@ +import 'bloc/date_of_birth_bloc.dart'; +import 'models/date_of_birth_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class DateOfBirthScreen extends StatelessWidget { + const DateOfBirthScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => DateOfBirthBloc( + DateOfBirthState(dateOfBirthModelObj: DateOfBirthModel())) + ..add(DateOfBirthInitialEvent()), + child: DateOfBirthScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return BlocBuilder( + builder: (context, state) { + return SafeArea( + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: + EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + _buildProgressIndicator(context), + SizedBox(height: 38.v), + Text("lbl".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 39), + _buildDateInput(context), + Spacer(flex: 60), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 8.h), + child: Text("lbl3".tr, + style: theme.textTheme.bodyLarge))) + ])))); + }); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildProgressIndicator(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), + decoration: AppDecoration.outlinePrimary + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Container( + height: 8.v, + width: 60.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular(4.h), + border: + Border.all(color: theme.colorScheme.primary, width: 1.h)))); + } + + /// Section Widget + Widget _buildDateInput(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 1.v), + decoration: AppDecoration.outlineBlueA + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize, + radius: BorderRadius.circular(1.h)), + SizedBox(height: 6.v), + Align( + alignment: Alignment.center, + child: Text("lbl_01_01_2000".tr, + style: theme.textTheme.titleMedium)), + SizedBox(height: 4.v) + ])); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart b/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart new file mode 100644 index 00000000..3cc83943 --- /dev/null +++ b/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [date_of_birth_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class DateOfBirthModel extends Equatable { + DateOfBirthModel() {} + + DateOfBirthModel copyWith() { + return DateOfBirthModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart new file mode 100644 index 00000000..95c740fe --- /dev/null +++ b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart @@ -0,0 +1,22 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/favorite_foods_screen/models/favorite_foods_model.dart'; +part 'favorite_foods_event.dart'; +part 'favorite_foods_state.dart'; + +/// A bloc that manages the state of a FavoriteFoods according to the event that is dispatched to it. +class FavoriteFoodsBloc extends Bloc { + FavoriteFoodsBloc(FavoriteFoodsState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + FavoriteFoodsInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + enterinformationController: TextEditingController(), + enterinformationController1: TextEditingController())); + } +} diff --git a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_event.dart b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_event.dart new file mode 100644 index 00000000..f930b8e0 --- /dev/null +++ b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'favorite_foods_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///FavoriteFoods widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class FavoriteFoodsEvent extends Equatable {} + +/// Event that is dispatched when the FavoriteFoods widget is first created. +class FavoriteFoodsInitialEvent extends FavoriteFoodsEvent { + @override + List get props => []; +} diff --git a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart new file mode 100644 index 00000000..fd14b209 --- /dev/null +++ b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart @@ -0,0 +1,39 @@ +// ignore_for_file: must_be_immutable + +part of 'favorite_foods_bloc.dart'; + +/// Represents the state of FavoriteFoods in the application. +class FavoriteFoodsState extends Equatable { + FavoriteFoodsState({ + this.enterinformationController, + this.enterinformationController1, + this.favoriteFoodsModelObj, + }); + + TextEditingController? enterinformationController; + + TextEditingController? enterinformationController1; + + FavoriteFoodsModel? favoriteFoodsModelObj; + + @override + List get props => [ + enterinformationController, + enterinformationController1, + favoriteFoodsModelObj, + ]; + FavoriteFoodsState copyWith({ + TextEditingController? enterinformationController, + TextEditingController? enterinformationController1, + FavoriteFoodsModel? favoriteFoodsModelObj, + }) { + return FavoriteFoodsState( + enterinformationController: + enterinformationController ?? this.enterinformationController, + enterinformationController1: + enterinformationController1 ?? this.enterinformationController1, + favoriteFoodsModelObj: + favoriteFoodsModelObj ?? this.favoriteFoodsModelObj, + ); + } +} diff --git a/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart new file mode 100644 index 00000000..c5f5e27a --- /dev/null +++ b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart @@ -0,0 +1,125 @@ +import 'bloc/favorite_foods_bloc.dart'; +import 'models/favorite_foods_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class FavoriteFoodsScreen extends StatelessWidget { + const FavoriteFoodsScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => FavoriteFoodsBloc( + FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel())) + ..add(FavoriteFoodsInitialEvent()), + child: FavoriteFoodsScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + _buildProgressIndicator(context), + SizedBox(height: 19.v), + Container( + width: 327.h, + margin: EdgeInsets.only(left: 8.h, right: 7.h), + child: Text("msg12".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: theme.textTheme.headlineSmall)), + SizedBox(height: 23.v), + _buildNinetyThree(context), + SizedBox(height: 22.v), + _buildNinetyThree1(context), + SizedBox(height: 27.v), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 31.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildProgressIndicator(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), + decoration: AppDecoration.outlinePrimary + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Container( + height: 8.v, + width: 279.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular(4.h), + border: + Border.all(color: theme.colorScheme.primary, width: 1.h)))); + } + + /// Section Widget + Widget _buildNinetyThree(BuildContext context) { + return Column(children: [ + Text("lbl15".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.enterinformationController, + builder: (context, enterinformationController) { + return CustomTextFormField( + controller: enterinformationController, + hintText: "msg5".tr, + maxLines: 8); + }) + ]); + } + + /// Section Widget + Widget _buildNinetyThree1(BuildContext context) { + return Column(children: [ + Text("msg13".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.enterinformationController1, + builder: (context, enterinformationController1) { + return CustomTextFormField( + controller: enterinformationController1, + hintText: "msg5".tr, + textInputAction: TextInputAction.done, + maxLines: 8); + }) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart b/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart new file mode 100644 index 00000000..3df7820b --- /dev/null +++ b/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [favorite_foods_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class FavoriteFoodsModel extends Equatable { + FavoriteFoodsModel() {} + + FavoriteFoodsModel copyWith() { + return FavoriteFoodsModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/favorite_sports_screen/bloc/favorite_sports_bloc.dart b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_bloc.dart new file mode 100644 index 00000000..9a7c8925 --- /dev/null +++ b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_bloc.dart @@ -0,0 +1,23 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/favorite_sports_screen/models/favorite_sports_model.dart'; +part 'favorite_sports_event.dart'; +part 'favorite_sports_state.dart'; + +/// A bloc that manages the state of a FavoriteSports according to the event that is dispatched to it. +class FavoriteSportsBloc + extends Bloc { + FavoriteSportsBloc(FavoriteSportsState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + FavoriteSportsInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + enterinformationController: TextEditingController(), + )); + } +} diff --git a/lib/presentation/favorite_sports_screen/bloc/favorite_sports_event.dart b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_event.dart new file mode 100644 index 00000000..ae9a018f --- /dev/null +++ b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'favorite_sports_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///FavoriteSports widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class FavoriteSportsEvent extends Equatable {} + +/// Event that is dispatched when the FavoriteSports widget is first created. +class FavoriteSportsInitialEvent extends FavoriteSportsEvent { + @override + List get props => []; +} diff --git a/lib/presentation/favorite_sports_screen/bloc/favorite_sports_state.dart b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_state.dart new file mode 100644 index 00000000..c44cb2ad --- /dev/null +++ b/lib/presentation/favorite_sports_screen/bloc/favorite_sports_state.dart @@ -0,0 +1,32 @@ +// ignore_for_file: must_be_immutable + +part of 'favorite_sports_bloc.dart'; + +/// Represents the state of FavoriteSports in the application. +class FavoriteSportsState extends Equatable { + FavoriteSportsState({ + this.enterinformationController, + this.favoriteSportsModelObj, + }); + + TextEditingController? enterinformationController; + + FavoriteSportsModel? favoriteSportsModelObj; + + @override + List get props => [ + enterinformationController, + favoriteSportsModelObj, + ]; + FavoriteSportsState copyWith({ + TextEditingController? enterinformationController, + FavoriteSportsModel? favoriteSportsModelObj, + }) { + return FavoriteSportsState( + enterinformationController: + enterinformationController ?? this.enterinformationController, + favoriteSportsModelObj: + favoriteSportsModelObj ?? this.favoriteSportsModelObj, + ); + } +} diff --git a/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart new file mode 100644 index 00000000..adcde32f --- /dev/null +++ b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart @@ -0,0 +1,127 @@ +import 'bloc/favorite_sports_bloc.dart'; +import 'models/favorite_sports_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class FavoriteSportsScreen extends StatelessWidget { + const FavoriteSportsScreen({Key? key}) + : super( + key: key, + ); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => FavoriteSportsBloc(FavoriteSportsState( + favoriteSportsModelObj: FavoriteSportsModel(), + )) + ..add(FavoriteSportsInitialEvent()), + child: FavoriteSportsScreen(), + ); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric( + horizontal: 16.h, + vertical: 5.v, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CustomImageView( + imagePath: ImageConstant.imgLogoEatvio, + height: 50.adaptSize, + width: 50.adaptSize, + ), + SizedBox(height: 20.v), + _buildProgressIndicatorSection(context), + SizedBox(height: 38.v), + Text( + "msg11".tr, + style: theme.textTheme.headlineSmall, + ), + Spacer( + flex: 32, + ), + _buildNinetyThreeSection(context), + Spacer( + flex: 67, + ), + CustomOutlinedButton( + text: "lbl2".tr.toUpperCase(), + ), + SizedBox(height: 17.v), + Text( + "lbl3".tr, + style: theme.textTheme.bodyLarge, + ), + SizedBox(height: 4.v), + ], + ), + ), + ), + ); + } + + /// Section Widget + Widget _buildProgressIndicatorSection(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric( + horizontal: 4.h, + vertical: 3.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.circleBorder8, + ), + child: Container( + height: 8.v, + width: 259.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular( + 4.h, + ), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, + ), + ), + ), + ); + } + + /// Section Widget + Widget _buildNinetyThreeSection(BuildContext context) { + return Column( + children: [ + Text( + "msg4".tr, + style: CustomTextStyles.titleMediumSegoeUI, + ), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.enterinformationController, + builder: (context, enterinformationController) { + return CustomTextFormField( + controller: enterinformationController, + hintText: "msg5".tr, + textInputAction: TextInputAction.done, + maxLines: 8, + ); + }, + ), + ], + ); + } +} diff --git a/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart b/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart new file mode 100644 index 00000000..aa5c41b0 --- /dev/null +++ b/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [favorite_sports_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class FavoriteSportsModel extends Equatable { + FavoriteSportsModel() {} + + FavoriteSportsModel copyWith() { + return FavoriteSportsModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/gender_screen/bloc/gender_bloc.dart b/lib/presentation/gender_screen/bloc/gender_bloc.dart new file mode 100644 index 00000000..2d2b2618 --- /dev/null +++ b/lib/presentation/gender_screen/bloc/gender_bloc.dart @@ -0,0 +1,18 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/gender_screen/models/gender_model.dart'; +part 'gender_event.dart'; +part 'gender_state.dart'; + +/// A bloc that manages the state of a Gender according to the event that is dispatched to it. +class GenderBloc extends Bloc { + GenderBloc(GenderState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + GenderInitialEvent event, + Emitter emit, + ) async {} +} diff --git a/lib/presentation/gender_screen/bloc/gender_event.dart b/lib/presentation/gender_screen/bloc/gender_event.dart new file mode 100644 index 00000000..3660a87c --- /dev/null +++ b/lib/presentation/gender_screen/bloc/gender_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'gender_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Gender widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class GenderEvent extends Equatable {} + +/// Event that is dispatched when the Gender widget is first created. +class GenderInitialEvent extends GenderEvent { + @override + List get props => []; +} diff --git a/lib/presentation/gender_screen/bloc/gender_state.dart b/lib/presentation/gender_screen/bloc/gender_state.dart new file mode 100644 index 00000000..16109442 --- /dev/null +++ b/lib/presentation/gender_screen/bloc/gender_state.dart @@ -0,0 +1,20 @@ +// ignore_for_file: must_be_immutable + +part of 'gender_bloc.dart'; + +/// Represents the state of Gender in the application. +class GenderState extends Equatable { + GenderState({this.genderModelObj}); + + GenderModel? genderModelObj; + + @override + List get props => [ + genderModelObj, + ]; + GenderState copyWith({GenderModel? genderModelObj}) { + return GenderState( + genderModelObj: genderModelObj ?? this.genderModelObj, + ); + } +} diff --git a/lib/presentation/gender_screen/gender_screen.dart b/lib/presentation/gender_screen/gender_screen.dart new file mode 100644 index 00000000..cc60c175 --- /dev/null +++ b/lib/presentation/gender_screen/gender_screen.dart @@ -0,0 +1,84 @@ +import 'bloc/gender_bloc.dart'; +import 'models/gender_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class GenderScreen extends StatelessWidget { + const GenderScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + GenderBloc(GenderState(genderModelObj: GenderModel())) + ..add(GenderInitialEvent()), + child: GenderScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return BlocBuilder(builder: (context, state) { + return SafeArea( + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: + EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + _buildProgressIndicator(context), + SizedBox(height: 36.v), + Text("lbl13".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 33), + Text(""), + SizedBox(height: 20.v), + Text(""), + Spacer(flex: 66), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + }); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildProgressIndicator(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), + decoration: AppDecoration.outlinePrimary + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Container( + height: 8.v, + width: 40.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular(4.h), + border: + Border.all(color: theme.colorScheme.primary, width: 1.h)))); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/gender_screen/models/gender_model.dart b/lib/presentation/gender_screen/models/gender_model.dart new file mode 100644 index 00000000..1ba38218 --- /dev/null +++ b/lib/presentation/gender_screen/models/gender_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [gender_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class GenderModel extends Equatable { + GenderModel() {} + + GenderModel copyWith() { + return GenderModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/language_select_screen/bloc/language_select_bloc.dart b/lib/presentation/language_select_screen/bloc/language_select_bloc.dart new file mode 100644 index 00000000..2c3918c4 --- /dev/null +++ b/lib/presentation/language_select_screen/bloc/language_select_bloc.dart @@ -0,0 +1,52 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/language_select_screen/models/language_select_model.dart'; +part 'language_select_event.dart'; +part 'language_select_state.dart'; + +/// A bloc that manages the state of a LanguageSelect according to the event that is dispatched to it. +class LanguageSelectBloc + extends Bloc { + LanguageSelectBloc(LanguageSelectState initialState) : super(initialState) { + on(_onInitialize); + on(_changeDropDown); + } + + _onInitialize( + LanguageSelectInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + languageSelectModelObj: state.languageSelectModelObj?.copyWith( + dropdownItemList: fillDropdownItemList(), + ))); + } + + _changeDropDown( + ChangeDropDownEvent event, + Emitter emit, + ) { + emit(state.copyWith( + selectedDropDownValue: event.value, + )); + } + + List fillDropdownItemList() { + return [ + SelectionPopupModel( + id: 1, + title: "Item One", + isSelected: true, + ), + SelectionPopupModel( + id: 2, + title: "Item Two", + ), + SelectionPopupModel( + id: 3, + title: "Item Three", + ) + ]; + } +} diff --git a/lib/presentation/language_select_screen/bloc/language_select_event.dart b/lib/presentation/language_select_screen/bloc/language_select_event.dart new file mode 100644 index 00000000..5c39a950 --- /dev/null +++ b/lib/presentation/language_select_screen/bloc/language_select_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'language_select_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///LanguageSelect widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class LanguageSelectEvent extends Equatable {} + +/// Event that is dispatched when the LanguageSelect widget is first created. +class LanguageSelectInitialEvent extends LanguageSelectEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends LanguageSelectEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/language_select_screen/bloc/language_select_state.dart b/lib/presentation/language_select_screen/bloc/language_select_state.dart new file mode 100644 index 00000000..602a4adc --- /dev/null +++ b/lib/presentation/language_select_screen/bloc/language_select_state.dart @@ -0,0 +1,32 @@ +// ignore_for_file: must_be_immutable + +part of 'language_select_bloc.dart'; + +/// Represents the state of LanguageSelect in the application. +class LanguageSelectState extends Equatable { + LanguageSelectState({ + this.selectedDropDownValue, + this.languageSelectModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + LanguageSelectModel? languageSelectModelObj; + + @override + List get props => [ + selectedDropDownValue, + languageSelectModelObj, + ]; + LanguageSelectState copyWith({ + SelectionPopupModel? selectedDropDownValue, + LanguageSelectModel? languageSelectModelObj, + }) { + return LanguageSelectState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + languageSelectModelObj: + languageSelectModelObj ?? this.languageSelectModelObj, + ); + } +} diff --git a/lib/presentation/language_select_screen/language_select_screen.dart b/lib/presentation/language_select_screen/language_select_screen.dart new file mode 100644 index 00000000..677fbfcb --- /dev/null +++ b/lib/presentation/language_select_screen/language_select_screen.dart @@ -0,0 +1,142 @@ +import 'bloc/language_select_bloc.dart'; +import 'models/language_select_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class LanguageSelectScreen extends StatelessWidget { + const LanguageSelectScreen({Key? key}) + : super( + key: key, + ); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => LanguageSelectBloc(LanguageSelectState( + languageSelectModelObj: LanguageSelectModel(), + )) + ..add(LanguageSelectInitialEvent()), + child: LanguageSelectScreen(), + ); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + + return SafeArea( + child: Scaffold( + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric( + horizontal: 16.h, + vertical: 5.v, + ), + child: Column( + children: [ + CustomImageView( + imagePath: ImageConstant.imgLogoEatvio, + height: 50.adaptSize, + width: 50.adaptSize, + ), + SizedBox(height: 20.v), + _buildProgressIndicatorSection(context), + SizedBox(height: 20.v), + Container( + width: 262.h, + margin: EdgeInsets.only( + left: 41.h, + right: 39.h, + ), + child: Text( + "msg17".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: theme.textTheme.headlineSmall, + ), + ), + Spacer( + flex: 36, + ), + BlocSelector( + selector: (state) => state.languageSelectModelObj, + builder: (context, languageSelectModelObj) { + return CustomDropDown( + icon: Container( + margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular( + 1.h, + ), + ), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize, + ), + ), + hintText: "lbl_english".tr, + items: languageSelectModelObj?.dropdownItemList ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }, + ); + }, + ), + Spacer( + flex: 63, + ), + ], + ), + ), + bottomNavigationBar: _buildContinueButtonSection(context), + ), + ); + } + + /// Section Widget + Widget _buildProgressIndicatorSection(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric( + horizontal: 4.h, + vertical: 3.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.circleBorder8, + ), + child: Container( + height: 8.v, + width: 20.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular( + 4.h, + ), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, + ), + ), + ), + ); + } + + /// Section Widget + Widget _buildContinueButtonSection(BuildContext context) { + return CustomOutlinedButton( + text: "lbl2".tr.toUpperCase(), + margin: EdgeInsets.only( + left: 16.h, + right: 16.h, + bottom: 50.v, + ), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + ); + } +} diff --git a/lib/presentation/language_select_screen/models/language_select_model.dart b/lib/presentation/language_select_screen/models/language_select_model.dart new file mode 100644 index 00000000..0b9cb205 --- /dev/null +++ b/lib/presentation/language_select_screen/models/language_select_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; + +/// This class defines the variables used in the [language_select_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class LanguageSelectModel extends Equatable { + LanguageSelectModel({this.dropdownItemList = const []}) {} + + List dropdownItemList; + + LanguageSelectModel copyWith({List? dropdownItemList}) { + return LanguageSelectModel( + dropdownItemList: dropdownItemList ?? this.dropdownItemList, + ); + } + + @override + List get props => [dropdownItemList]; +} diff --git a/lib/presentation/medicine_intake_screen/bloc/medicine_intake_bloc.dart b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_bloc.dart new file mode 100644 index 00000000..190c1c0d --- /dev/null +++ b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_bloc.dart @@ -0,0 +1,21 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/medicine_intake_screen/models/medicine_intake_model.dart'; +part 'medicine_intake_event.dart'; +part 'medicine_intake_state.dart'; + +/// A bloc that manages the state of a MedicineIntake according to the event that is dispatched to it. +class MedicineIntakeBloc + extends Bloc { + MedicineIntakeBloc(MedicineIntakeState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + MedicineIntakeInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith(enterInformationController: TextEditingController())); + } +} diff --git a/lib/presentation/medicine_intake_screen/bloc/medicine_intake_event.dart b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_event.dart new file mode 100644 index 00000000..0300b286 --- /dev/null +++ b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'medicine_intake_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///MedicineIntake widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class MedicineIntakeEvent extends Equatable {} + +/// Event that is dispatched when the MedicineIntake widget is first created. +class MedicineIntakeInitialEvent extends MedicineIntakeEvent { + @override + List get props => []; +} diff --git a/lib/presentation/medicine_intake_screen/bloc/medicine_intake_state.dart b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_state.dart new file mode 100644 index 00000000..8d7958f6 --- /dev/null +++ b/lib/presentation/medicine_intake_screen/bloc/medicine_intake_state.dart @@ -0,0 +1,32 @@ +// ignore_for_file: must_be_immutable + +part of 'medicine_intake_bloc.dart'; + +/// Represents the state of MedicineIntake in the application. +class MedicineIntakeState extends Equatable { + MedicineIntakeState({ + this.enterInformationController, + this.medicineIntakeModelObj, + }); + + TextEditingController? enterInformationController; + + MedicineIntakeModel? medicineIntakeModelObj; + + @override + List get props => [ + enterInformationController, + medicineIntakeModelObj, + ]; + MedicineIntakeState copyWith({ + TextEditingController? enterInformationController, + MedicineIntakeModel? medicineIntakeModelObj, + }) { + return MedicineIntakeState( + enterInformationController: + enterInformationController ?? this.enterInformationController, + medicineIntakeModelObj: + medicineIntakeModelObj ?? this.medicineIntakeModelObj, + ); + } +} diff --git a/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart new file mode 100644 index 00000000..56da2766 --- /dev/null +++ b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart @@ -0,0 +1,103 @@ +import 'bloc/medicine_intake_bloc.dart'; +import 'models/medicine_intake_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class MedicineIntakeScreen extends StatelessWidget { + const MedicineIntakeScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => MedicineIntakeBloc( + MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel())) + ..add(MedicineIntakeInitialEvent()), + child: MedicineIntakeScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.47, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 20.v), + Container( + width: 271.h, + margin: EdgeInsets.only(left: 35.h, right: 36.h), + child: Text("msg6".tr, + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: CustomTextStyles.headlineSmallMulish)), + SizedBox(height: 86.v), + _buildNinetyThree(context), + Spacer(), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 31.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildNinetyThree(BuildContext context) { + return Column(children: [ + Text("msg4".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.enterInformationController, + builder: (context, enterInformationController) { + return CustomTextFormField( + controller: enterInformationController, + hintText: "msg5".tr, + textInputAction: TextInputAction.done, + maxLines: 8); + }) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart b/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart new file mode 100644 index 00000000..29323f2d --- /dev/null +++ b/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [medicine_intake_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class MedicineIntakeModel extends Equatable { + MedicineIntakeModel() {} + + MedicineIntakeModel copyWith() { + return MedicineIntakeModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/schedule_screen/bloc/schedule_bloc.dart b/lib/presentation/schedule_screen/bloc/schedule_bloc.dart new file mode 100644 index 00000000..6dedad4a --- /dev/null +++ b/lib/presentation/schedule_screen/bloc/schedule_bloc.dart @@ -0,0 +1,20 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/schedule_screen/models/schedule_model.dart'; +part 'schedule_event.dart'; +part 'schedule_state.dart'; + +/// A bloc that manages the state of a Schedule according to the event that is dispatched to it. +class ScheduleBloc extends Bloc { + ScheduleBloc(ScheduleState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + ScheduleInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith(inputPlaceholderController: TextEditingController())); + } +} diff --git a/lib/presentation/schedule_screen/bloc/schedule_event.dart b/lib/presentation/schedule_screen/bloc/schedule_event.dart new file mode 100644 index 00000000..711e4eaf --- /dev/null +++ b/lib/presentation/schedule_screen/bloc/schedule_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'schedule_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Schedule widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class ScheduleEvent extends Equatable {} + +/// Event that is dispatched when the Schedule widget is first created. +class ScheduleInitialEvent extends ScheduleEvent { + @override + List get props => []; +} diff --git a/lib/presentation/schedule_screen/bloc/schedule_state.dart b/lib/presentation/schedule_screen/bloc/schedule_state.dart new file mode 100644 index 00000000..4c345db8 --- /dev/null +++ b/lib/presentation/schedule_screen/bloc/schedule_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'schedule_bloc.dart'; + +/// Represents the state of Schedule in the application. +class ScheduleState extends Equatable { + ScheduleState({ + this.inputPlaceholderController, + this.scheduleModelObj, + }); + + TextEditingController? inputPlaceholderController; + + ScheduleModel? scheduleModelObj; + + @override + List get props => [ + inputPlaceholderController, + scheduleModelObj, + ]; + ScheduleState copyWith({ + TextEditingController? inputPlaceholderController, + ScheduleModel? scheduleModelObj, + }) { + return ScheduleState( + inputPlaceholderController: + inputPlaceholderController ?? this.inputPlaceholderController, + scheduleModelObj: scheduleModelObj ?? this.scheduleModelObj, + ); + } +} diff --git a/lib/presentation/schedule_screen/models/schedule_model.dart b/lib/presentation/schedule_screen/models/schedule_model.dart new file mode 100644 index 00000000..6eb1022f --- /dev/null +++ b/lib/presentation/schedule_screen/models/schedule_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [schedule_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class ScheduleModel extends Equatable { + ScheduleModel() {} + + ScheduleModel copyWith() { + return ScheduleModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/schedule_screen/schedule_screen.dart b/lib/presentation/schedule_screen/schedule_screen.dart new file mode 100644 index 00000000..b9e49d0d --- /dev/null +++ b/lib/presentation/schedule_screen/schedule_screen.dart @@ -0,0 +1,105 @@ +import 'bloc/schedule_bloc.dart'; +import 'models/schedule_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class ScheduleScreen extends StatelessWidget { + const ScheduleScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + ScheduleBloc(ScheduleState(scheduleModelObj: ScheduleModel())) + ..add(ScheduleInitialEvent()), + child: ScheduleScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + _buildProgressIndicator(context), + SizedBox(height: 38.v), + Text("lbl16".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 67.v), + _buildNinetyThree(context), + Spacer(), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 31.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildProgressIndicator(BuildContext context) { + return Container( + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), + decoration: AppDecoration.outlinePrimary + .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), + child: Container( + height: 8.v, + width: 297.h, + decoration: BoxDecoration( + color: appTheme.blueA400, + borderRadius: BorderRadius.circular(4.h), + border: + Border.all(color: theme.colorScheme.primary, width: 1.h)))); + } + + /// Section Widget + Widget _buildNinetyThree(BuildContext context) { + return Column(children: [ + Container( + width: 324.h, + margin: EdgeInsets.symmetric(horizontal: 9.h), + child: Text("msg14".tr, + maxLines: 3, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: CustomTextStyles.titleMediumSegoeUI)), + SizedBox(height: 12.v), + BlocSelector( + selector: (state) => state.inputPlaceholderController, + builder: (context, inputPlaceholderController) { + return CustomTextFormField( + controller: inputPlaceholderController, + hintText: "msg5".tr, + textInputAction: TextInputAction.done, + maxLines: 8); + }) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/splash_screen/bloc/splash_bloc.dart b/lib/presentation/splash_screen/bloc/splash_bloc.dart new file mode 100644 index 00000000..dc601ef7 --- /dev/null +++ b/lib/presentation/splash_screen/bloc/splash_bloc.dart @@ -0,0 +1,24 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/splash_screen/models/splash_model.dart'; +part 'splash_event.dart'; +part 'splash_state.dart'; + +/// A bloc that manages the state of a Splash according to the event that is dispatched to it. +class SplashBloc extends Bloc { + SplashBloc(SplashState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + SplashInitialEvent event, + Emitter emit, + ) async { + Future.delayed(const Duration(milliseconds: 3000), () { + NavigatorService.popAndPushNamed( + AppRoutes.languageSelectScreen, + ); + }); + } +} diff --git a/lib/presentation/splash_screen/bloc/splash_event.dart b/lib/presentation/splash_screen/bloc/splash_event.dart new file mode 100644 index 00000000..a78a25bb --- /dev/null +++ b/lib/presentation/splash_screen/bloc/splash_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'splash_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Splash widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class SplashEvent extends Equatable {} + +/// Event that is dispatched when the Splash widget is first created. +class SplashInitialEvent extends SplashEvent { + @override + List get props => []; +} diff --git a/lib/presentation/splash_screen/bloc/splash_state.dart b/lib/presentation/splash_screen/bloc/splash_state.dart new file mode 100644 index 00000000..e47ce03e --- /dev/null +++ b/lib/presentation/splash_screen/bloc/splash_state.dart @@ -0,0 +1,20 @@ +// ignore_for_file: must_be_immutable + +part of 'splash_bloc.dart'; + +/// Represents the state of Splash in the application. +class SplashState extends Equatable { + SplashState({this.splashModelObj}); + + SplashModel? splashModelObj; + + @override + List get props => [ + splashModelObj, + ]; + SplashState copyWith({SplashModel? splashModelObj}) { + return SplashState( + splashModelObj: splashModelObj ?? this.splashModelObj, + ); + } +} diff --git a/lib/presentation/splash_screen/models/splash_model.dart b/lib/presentation/splash_screen/models/splash_model.dart new file mode 100644 index 00000000..a2d44d6c --- /dev/null +++ b/lib/presentation/splash_screen/models/splash_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [splash_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class SplashModel extends Equatable { + SplashModel() {} + + SplashModel copyWith() { + return SplashModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/splash_screen/splash_screen.dart b/lib/presentation/splash_screen/splash_screen.dart new file mode 100644 index 00000000..501586fd --- /dev/null +++ b/lib/presentation/splash_screen/splash_screen.dart @@ -0,0 +1,36 @@ +import 'bloc/splash_bloc.dart'; +import 'models/splash_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class SplashScreen extends StatelessWidget { + const SplashScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + SplashBloc(SplashState(splashModelObj: SplashModel())) + ..add(SplashInitialEvent()), + child: SplashScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return BlocBuilder(builder: (context, state) { + return SafeArea( + child: Scaffold( + body: SizedBox( + width: double.maxFinite, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 16.v), + CustomImageView( + imagePath: ImageConstant.img2456927096976, + height: 137.adaptSize, + width: 137.adaptSize) + ])))); + }); + } +} diff --git a/lib/presentation/weight_screen/bloc/weight_bloc.dart b/lib/presentation/weight_screen/bloc/weight_bloc.dart new file mode 100644 index 00000000..70440b67 --- /dev/null +++ b/lib/presentation/weight_screen/bloc/weight_bloc.dart @@ -0,0 +1,38 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/weight_screen/models/weight_model.dart'; +part 'weight_event.dart'; +part 'weight_state.dart'; + +/// A bloc that manages the state of a Weight according to the event that is dispatched to it. +class WeightBloc extends Bloc { + WeightBloc(WeightState initialState) : super(initialState) { + on(_onInitialize); + on(_changeDropDown); + } + + _onInitialize( + WeightInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + weightModelObj: state.weightModelObj + ?.copyWith(dropdownItemList: fillDropdownItemList()))); + } + + _changeDropDown( + ChangeDropDownEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedDropDownValue: event.value)); + } + + List fillDropdownItemList() { + return [ + SelectionPopupModel(id: 1, title: "Item One", isSelected: true), + SelectionPopupModel(id: 2, title: "Item Two"), + SelectionPopupModel(id: 3, title: "Item Three") + ]; + } +} diff --git a/lib/presentation/weight_screen/bloc/weight_event.dart b/lib/presentation/weight_screen/bloc/weight_event.dart new file mode 100644 index 00000000..93b69d22 --- /dev/null +++ b/lib/presentation/weight_screen/bloc/weight_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'weight_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Weight widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class WeightEvent extends Equatable {} + +/// Event that is dispatched when the Weight widget is first created. +class WeightInitialEvent extends WeightEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends WeightEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/weight_screen/bloc/weight_state.dart b/lib/presentation/weight_screen/bloc/weight_state.dart new file mode 100644 index 00000000..06b9c2cf --- /dev/null +++ b/lib/presentation/weight_screen/bloc/weight_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'weight_bloc.dart'; + +/// Represents the state of Weight in the application. +class WeightState extends Equatable { + WeightState({ + this.selectedDropDownValue, + this.weightModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + WeightModel? weightModelObj; + + @override + List get props => [ + selectedDropDownValue, + weightModelObj, + ]; + WeightState copyWith({ + SelectionPopupModel? selectedDropDownValue, + WeightModel? weightModelObj, + }) { + return WeightState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + weightModelObj: weightModelObj ?? this.weightModelObj, + ); + } +} diff --git a/lib/presentation/weight_screen/models/weight_model.dart b/lib/presentation/weight_screen/models/weight_model.dart new file mode 100644 index 00000000..1ebdb828 --- /dev/null +++ b/lib/presentation/weight_screen/models/weight_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; + +/// This class defines the variables used in the [weight_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class WeightModel extends Equatable { + WeightModel({this.dropdownItemList = const []}) {} + + List dropdownItemList; + + WeightModel copyWith({List? dropdownItemList}) { + return WeightModel( + dropdownItemList: dropdownItemList ?? this.dropdownItemList, + ); + } + + @override + List get props => [dropdownItemList]; +} diff --git a/lib/presentation/weight_screen/weight_screen.dart b/lib/presentation/weight_screen/weight_screen.dart new file mode 100644 index 00000000..bb3358ba --- /dev/null +++ b/lib/presentation/weight_screen/weight_screen.dart @@ -0,0 +1,112 @@ +import 'bloc/weight_bloc.dart'; +import 'models/weight_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:flutter/material.dart'; + +class WeightScreen extends StatelessWidget { + const WeightScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + WeightBloc(WeightState(weightModelObj: WeightModel())) + ..add(WeightInitialEvent()), + child: WeightScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column(children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, width: 1.h)), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.35, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 39.v), + _buildTwentySix(context), + Spacer(), + CustomOutlinedButton(text: "lbl2".tr.toUpperCase()), + SizedBox(height: 17.v), + Text("lbl3".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// Section Widget + PreferredSizeWidget _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () { + onTapArrowLeft(context); + }), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + /// Section Widget + Widget _buildTwentySixWidget(BuildContext context) { + return Column(children: [ + Text("lbl12".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 4.v), + BlocSelector( + selector: (state) => state.weightModelObj, + builder: (context, weightModelObj) { + return CustomDropDown( + icon: Container( + margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), + decoration: + BoxDecoration(borderRadius: BorderRadius.circular(1.h)), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize)), + hintText: "lbl_70".tr, + items: weightModelObj?.dropdownItemList ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }); + }) + ]); + } + + /// Section Widget + Widget _buildTwentySix(BuildContext context) { + return Column(children: [ + Text("lbl11".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 174.v), + _buildTwentySixWidget(context) + ]); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart new file mode 100644 index 00000000..d0a33cda --- /dev/null +++ b/lib/routes/app_routes.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/presentation/date_of_birth_screen/date_of_birth_screen.dart'; +import 'package:eatvio_app/presentation/city_of_living_screen/city_of_living_screen.dart'; +import 'package:eatvio_app/presentation/body_circumferences_screen/body_circumferences_screen.dart'; +import 'package:eatvio_app/presentation/weight_screen/weight_screen.dart'; +import 'package:eatvio_app/presentation/allergies_screen/allergies_screen.dart'; +import 'package:eatvio_app/presentation/medicine_intake_screen/medicine_intake_screen.dart'; +import 'package:eatvio_app/presentation/splash_screen/splash_screen.dart'; +import 'package:eatvio_app/presentation/gender_screen/gender_screen.dart'; +import 'package:eatvio_app/presentation/blood_pressure_screen/blood_pressure_screen.dart'; +import 'package:eatvio_app/presentation/favorite_sports_screen/favorite_sports_screen.dart'; +import 'package:eatvio_app/presentation/favorite_foods_screen/favorite_foods_screen.dart'; +import 'package:eatvio_app/presentation/schedule_screen/schedule_screen.dart'; +import 'package:eatvio_app/presentation/additional_information_screen/additional_information_screen.dart'; +import 'package:eatvio_app/presentation/language_select_screen/language_select_screen.dart'; +import 'package:eatvio_app/presentation/app_navigation_screen/app_navigation_screen.dart'; + +class AppRoutes { + static const String dateOfBirthScreen = '/date_of_birth_screen'; + + static const String cityOfLivingScreen = '/city_of_living_screen'; + + static const String bodyCircumferencesScreen = '/body_circumferences_screen'; + + static const String weightScreen = '/weight_screen'; + + static const String allergiesScreen = '/allergies_screen'; + + static const String medicineIntakeScreen = '/medicine_intake_screen'; + + static const String splashScreen = '/splash_screen'; + + static const String genderScreen = '/gender_screen'; + + static const String bloodPressureScreen = '/blood_pressure_screen'; + + static const String favoriteSportsScreen = '/favorite_sports_screen'; + + static const String favoriteFoodsScreen = '/favorite_foods_screen'; + + static const String scheduleScreen = '/schedule_screen'; + + static const String additionalInformationScreen = + '/additional_information_screen'; + + static const String languageSelectScreen = '/language_select_screen'; + + static const String appNavigationScreen = '/app_navigation_screen'; + + static const String initialRoute = '/initialRoute'; + + static Map get routes => { + dateOfBirthScreen: DateOfBirthScreen.builder, + cityOfLivingScreen: CityOfLivingScreen.builder, + bodyCircumferencesScreen: BodyCircumferencesScreen.builder, + weightScreen: WeightScreen.builder, + allergiesScreen: AllergiesScreen.builder, + medicineIntakeScreen: MedicineIntakeScreen.builder, + splashScreen: SplashScreen.builder, + genderScreen: GenderScreen.builder, + bloodPressureScreen: BloodPressureScreen.builder, + favoriteSportsScreen: FavoriteSportsScreen.builder, + favoriteFoodsScreen: FavoriteFoodsScreen.builder, + scheduleScreen: ScheduleScreen.builder, + additionalInformationScreen: AdditionalInformationScreen.builder, + languageSelectScreen: LanguageSelectScreen.builder, + appNavigationScreen: AppNavigationScreen.builder, + initialRoute: SplashScreen.builder + }; +} diff --git a/lib/theme/app_decoration.dart b/lib/theme/app_decoration.dart new file mode 100644 index 00000000..027026b8 --- /dev/null +++ b/lib/theme/app_decoration.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/core/app_export.dart'; + +class AppDecoration { + // Fill decorations + static BoxDecoration get fillOnPrimary => BoxDecoration( + color: theme.colorScheme.onPrimary, + ); + + // Outline decorations + static BoxDecoration get outlineBlueA => BoxDecoration( + color: theme.colorScheme.onPrimary, + border: Border.all( + color: appTheme.blueA400, + width: 1.h, + ), + ); + static BoxDecoration get outlinePrimary => BoxDecoration( + color: theme.colorScheme.onPrimary, + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, + ), + ); +} + +class BorderRadiusStyle { + // Circle borders + static BorderRadius get circleBorder8 => BorderRadius.circular( + 8.h, + ); + + // Rounded borders + static BorderRadius get roundedBorder1 => BorderRadius.circular( + 1.h, + ); +} + +// Comment/Uncomment the below code based on your Flutter SDK version. + +// For Flutter SDK Version 3.7.2 or greater. + +double get strokeAlignInside => BorderSide.strokeAlignInside; + +double get strokeAlignCenter => BorderSide.strokeAlignCenter; + +double get strokeAlignOutside => BorderSide.strokeAlignOutside; + +// For Flutter SDK Version 3.7.1 or less. + +// StrokeAlign get strokeAlignInside => StrokeAlign.inside; +// +// StrokeAlign get strokeAlignCenter => StrokeAlign.center; +// +// StrokeAlign get strokeAlignOutside => StrokeAlign.outside; diff --git a/lib/theme/bloc/theme_bloc.dart b/lib/theme/bloc/theme_bloc.dart new file mode 100644 index 00000000..60f947d2 --- /dev/null +++ b/lib/theme/bloc/theme_bloc.dart @@ -0,0 +1,18 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '../../core/app_export.dart'; +part 'theme_event.dart'; +part 'theme_state.dart'; + +class ThemeBloc extends Bloc { + ThemeBloc(ThemeState initialState) : super(initialState) { + on(_changeTheme); + } + + _changeTheme( + ThemeChangeEvent event, + Emitter emit, + ) async { + emit(state.copyWith(themeType: event.themeType)); + } +} diff --git a/lib/theme/bloc/theme_event.dart b/lib/theme/bloc/theme_event.dart new file mode 100644 index 00000000..700cbdec --- /dev/null +++ b/lib/theme/bloc/theme_event.dart @@ -0,0 +1,15 @@ +part of 'theme_bloc.dart'; + +@immutable +abstract class ThemeEvent extends Equatable {} + +class ThemeChangeEvent extends ThemeEvent { + ThemeChangeEvent({required this.themeType}) : super() { + PrefUtils().setThemeData(themeType); + } + + final String themeType; + + @override + List get props => []; +} diff --git a/lib/theme/bloc/theme_state.dart b/lib/theme/bloc/theme_state.dart new file mode 100644 index 00000000..2f93fff1 --- /dev/null +++ b/lib/theme/bloc/theme_state.dart @@ -0,0 +1,14 @@ +part of 'theme_bloc.dart'; + +@immutable +class ThemeState extends Equatable { + ThemeState({required this.themeType}); + + final String themeType; + + @override + List get props => [themeType]; + ThemeState copyWith({String? themeType}) { + return ThemeState(themeType: themeType ?? this.themeType); + } +} diff --git a/lib/theme/custom_button_style.dart b/lib/theme/custom_button_style.dart new file mode 100644 index 00000000..ed9839fe --- /dev/null +++ b/lib/theme/custom_button_style.dart @@ -0,0 +1,23 @@ +import 'dart:ui'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +/// A class that offers pre-defined button styles for customizing button appearance. +class CustomButtonStyles { + // Outline button style + static ButtonStyle get outlinePrimaryTL15 => OutlinedButton.styleFrom( + backgroundColor: appTheme.blueA400, + side: BorderSide( + color: theme.colorScheme.primary, + width: 1, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.h), + ), + ); + // text button style + static ButtonStyle get none => ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.transparent), + elevation: MaterialStateProperty.all(0), + ); +} diff --git a/lib/theme/custom_text_style.dart b/lib/theme/custom_text_style.dart new file mode 100644 index 00000000..a807d9d3 --- /dev/null +++ b/lib/theme/custom_text_style.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import '../core/app_export.dart'; + +/// A collection of pre-defined text styles for customizing text appearance, +/// categorized by different font families and weights. +/// Additionally, this class includes extensions on [TextStyle] to easily apply specific font families to text. + +class CustomTextStyles { + // Headline style + static get headlineSmallMulish => theme.textTheme.headlineSmall!.mulish; + // Title text style + static get titleMediumSegoeUI => + theme.textTheme.titleMedium!.segoeUI.copyWith( + fontWeight: FontWeight.w600, + ); +} + +extension on TextStyle { + TextStyle get mulish { + return copyWith( + fontFamily: 'Mulish', + ); + } + + TextStyle get segoeUI { + return copyWith( + fontFamily: 'Segoe UI', + ); + } +} diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart new file mode 100644 index 00000000..db1b9984 --- /dev/null +++ b/lib/theme/theme_helper.dart @@ -0,0 +1,128 @@ +import 'dart:ui'; +import 'package:flutter/material.dart'; +import '../../core/app_export.dart'; + +/// Helper class for managing themes and colors. +class ThemeHelper { + // The current app theme + var _appTheme = PrefUtils().getThemeData(); + +// A map of custom color themes supported by the app + Map _supportedCustomColor = { + 'primary': PrimaryColors() + }; + +// A map of color schemes supported by the app + Map _supportedColorScheme = { + 'primary': ColorSchemes.primaryColorScheme + }; + + /// Returns the primary colors for the current theme. + PrimaryColors _getThemeColors() { + //throw exception to notify given theme is not found or not generated by the generator + if (!_supportedCustomColor.containsKey(_appTheme)) { + throw Exception( + "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner"); + } + //return theme from map + + return _supportedCustomColor[_appTheme] ?? PrimaryColors(); + } + + /// Returns the current theme data. + ThemeData _getThemeData() { + //throw exception to notify given theme is not found or not generated by the generator + if (!_supportedColorScheme.containsKey(_appTheme)) { + throw Exception( + "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner"); + } + //return theme from map + + var colorScheme = + _supportedColorScheme[_appTheme] ?? ColorSchemes.primaryColorScheme; + return ThemeData( + visualDensity: VisualDensity.standard, + colorScheme: colorScheme, + textTheme: TextThemes.textTheme(colorScheme), + scaffoldBackgroundColor: colorScheme.onPrimary, + outlinedButtonTheme: OutlinedButtonThemeData( + style: OutlinedButton.styleFrom( + backgroundColor: Colors.transparent, + side: BorderSide( + color: colorScheme.primary, + width: 1.h, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15.h), + ), + visualDensity: const VisualDensity( + vertical: -4, + horizontal: -4, + ), + padding: EdgeInsets.zero, + ), + ), + ); + } + + /// Returns the primary colors for the current theme. + PrimaryColors themeColor() => _getThemeColors(); + + /// Returns the current theme data. + ThemeData themeData() => _getThemeData(); +} + +/// Class containing the supported text theme styles. +class TextThemes { + static TextTheme textTheme(ColorScheme colorScheme) => TextTheme( + bodyLarge: TextStyle( + color: appTheme.blueGray400, + fontSize: 18.fSize, + fontFamily: 'Mulish', + fontWeight: FontWeight.w400, + ), + headlineSmall: TextStyle( + color: colorScheme.primary, + fontSize: 24.fSize, + fontFamily: 'Segoe UI', + fontWeight: FontWeight.w600, + ), + titleMedium: TextStyle( + color: colorScheme.primary, + fontSize: 18.fSize, + fontFamily: 'Mulish', + fontWeight: FontWeight.w700, + ), + titleSmall: TextStyle( + color: colorScheme.onPrimary, + fontSize: 15.fSize, + fontFamily: 'Mulish', + fontWeight: FontWeight.w700, + ), + ); +} + +/// Class containing the supported color schemes. +class ColorSchemes { + static final primaryColorScheme = ColorScheme.light( + // Primary colors + primary: Color(0XFF323F4B), + + // On colors(text colors) + onPrimary: Color(0XFFFFFFFF), + onPrimaryContainer: Color(0XFF0B3F56), + ); +} + +/// Class containing custom colors for a primary theme. +class PrimaryColors { + // Blue + Color get blue400 => Color(0XFF43A6F2); + Color get blueA400 => Color(0XFF2F80ED); + + // BlueGray + Color get blueGray400 => Color(0XFF7B8794); +} + +PrimaryColors get appTheme => ThemeHelper().themeColor(); +ThemeData get theme => ThemeHelper().themeData(); diff --git a/lib/widgets/app_bar/appbar_leading_image.dart b/lib/widgets/app_bar/appbar_leading_image.dart new file mode 100644 index 00000000..5c9ff8e4 --- /dev/null +++ b/lib/widgets/app_bar/appbar_leading_image.dart @@ -0,0 +1,38 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +// ignore: must_be_immutable +class AppbarLeadingImage extends StatelessWidget { + AppbarLeadingImage({ + Key? key, + this.imagePath, + this.margin, + this.onTap, + }) : super( + key: key, + ); + + String? imagePath; + + EdgeInsetsGeometry? margin; + + Function? onTap; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + onTap!.call(); + }, + child: Padding( + padding: margin ?? EdgeInsets.zero, + child: CustomImageView( + imagePath: imagePath, + height: 26.v, + width: 13.h, + fit: BoxFit.contain, + ), + ), + ); + } +} diff --git a/lib/widgets/app_bar/appbar_title_image.dart b/lib/widgets/app_bar/appbar_title_image.dart new file mode 100644 index 00000000..1787d591 --- /dev/null +++ b/lib/widgets/app_bar/appbar_title_image.dart @@ -0,0 +1,38 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +// ignore: must_be_immutable +class AppbarTitleImage extends StatelessWidget { + AppbarTitleImage({ + Key? key, + this.imagePath, + this.margin, + this.onTap, + }) : super( + key: key, + ); + + String? imagePath; + + EdgeInsetsGeometry? margin; + + Function? onTap; + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + onTap!.call(); + }, + child: Padding( + padding: margin ?? EdgeInsets.zero, + child: CustomImageView( + imagePath: imagePath, + height: 26.v, + width: 13.h, + fit: BoxFit.contain, + ), + ), + ); + } +} diff --git a/lib/widgets/app_bar/custom_app_bar.dart b/lib/widgets/app_bar/custom_app_bar.dart new file mode 100644 index 00000000..7ffe17b3 --- /dev/null +++ b/lib/widgets/app_bar/custom_app_bar.dart @@ -0,0 +1,51 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +// ignore: must_be_immutable +class CustomAppBar extends StatelessWidget implements PreferredSizeWidget { + CustomAppBar({ + Key? key, + this.height, + this.leadingWidth, + this.leading, + this.title, + this.centerTitle, + this.actions, + }) : super( + key: key, + ); + + final double? height; + + final double? leadingWidth; + + final Widget? leading; + + final Widget? title; + + final bool? centerTitle; + + final List? actions; + + @override + Widget build(BuildContext context) { + return AppBar( + elevation: 0, + toolbarHeight: height ?? 56.v, + automaticallyImplyLeading: false, + backgroundColor: Colors.transparent, + leadingWidth: leadingWidth ?? 0, + leading: leading, + title: title, + titleSpacing: 0, + centerTitle: centerTitle ?? false, + actions: actions, + ); + } + + @override + Size get preferredSize => Size( + mediaQueryData.size.width, + height ?? 56.v, + ); +} diff --git a/lib/widgets/base_button.dart b/lib/widgets/base_button.dart new file mode 100644 index 00000000..51da7f6c --- /dev/null +++ b/lib/widgets/base_button.dart @@ -0,0 +1,42 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class BaseButton extends StatelessWidget { + BaseButton({ + Key? key, + required this.text, + this.onPressed, + this.buttonStyle, + this.buttonTextStyle, + this.isDisabled, + this.height, + this.width, + this.margin, + this.alignment, + }) : super( + key: key, + ); + + final String text; + + final VoidCallback? onPressed; + + final ButtonStyle? buttonStyle; + + final TextStyle? buttonTextStyle; + + final bool? isDisabled; + + final double? height; + + final double? width; + + final EdgeInsets? margin; + + final Alignment? alignment; + + @override + Widget build(BuildContext context) { + return const SizedBox.shrink(); + } +} diff --git a/lib/widgets/custom_drop_down.dart b/lib/widgets/custom_drop_down.dart new file mode 100644 index 00000000..dd5afc7d --- /dev/null +++ b/lib/widgets/custom_drop_down.dart @@ -0,0 +1,143 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class CustomDropDown extends StatelessWidget { + CustomDropDown({ + Key? key, + this.alignment, + this.width, + this.focusNode, + this.icon, + this.autofocus = true, + this.textStyle, + this.items, + this.hintText, + this.hintStyle, + this.prefix, + this.prefixConstraints, + this.suffix, + this.suffixConstraints, + this.contentPadding, + this.borderDecoration, + this.fillColor, + this.filled = true, + this.validator, + this.onChanged, + }) : super( + key: key, + ); + + final Alignment? alignment; + + final double? width; + + final FocusNode? focusNode; + + final Widget? icon; + + final bool? autofocus; + + final TextStyle? textStyle; + + final List? items; + + final String? hintText; + + final TextStyle? hintStyle; + + final Widget? prefix; + + final BoxConstraints? prefixConstraints; + + final Widget? suffix; + + final BoxConstraints? suffixConstraints; + + final EdgeInsets? contentPadding; + + final InputBorder? borderDecoration; + + final Color? fillColor; + + final bool? filled; + + final FormFieldValidator? validator; + + final Function(SelectionPopupModel)? onChanged; + + @override + Widget build(BuildContext context) { + return alignment != null + ? Align( + alignment: alignment ?? Alignment.center, + child: dropDownWidget, + ) + : dropDownWidget; + } + + Widget get dropDownWidget => SizedBox( + width: width ?? double.maxFinite, + child: DropdownButtonFormField( + focusNode: focusNode ?? FocusNode(), + icon: icon, + autofocus: autofocus!, + style: textStyle ?? theme.textTheme.titleMedium, + items: items?.map((SelectionPopupModel item) { + return DropdownMenuItem( + value: item, + child: Text( + item.title, + overflow: TextOverflow.ellipsis, + style: hintStyle ?? theme.textTheme.titleMedium, + ), + ); + }).toList(), + decoration: decoration, + validator: validator, + onChanged: (value) { + onChanged!(value!); + }, + ), + ); + InputDecoration get decoration => InputDecoration( + hintText: hintText ?? "", + hintStyle: hintStyle ?? theme.textTheme.titleMedium, + prefixIcon: prefix, + prefixIconConstraints: prefixConstraints, + suffixIcon: suffix, + suffixIconConstraints: suffixConstraints, + isDense: true, + contentPadding: contentPadding ?? + EdgeInsets.only( + left: 6.h, + top: 6.v, + bottom: 6.v, + ), + fillColor: fillColor ?? theme.colorScheme.onPrimary, + filled: filled, + border: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + enabledBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + focusedBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + ); +} diff --git a/lib/widgets/custom_image_view.dart b/lib/widgets/custom_image_view.dart new file mode 100644 index 00000000..5bed7a28 --- /dev/null +++ b/lib/widgets/custom_image_view.dart @@ -0,0 +1,161 @@ +// ignore_for_file: must_be_immutable + +import 'dart:io'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +class CustomImageView extends StatelessWidget { + ///[imagePath] is required parameter for showing image + String? imagePath; + + double? height; + double? width; + Color? color; + BoxFit? fit; + final String placeHolder; + Alignment? alignment; + VoidCallback? onTap; + EdgeInsetsGeometry? margin; + BorderRadius? radius; + BoxBorder? border; + + ///a [CustomImageView] it can be used for showing any type of images + /// it will shows the placeholder image if image is not found on network image + CustomImageView({ + this.imagePath, + this.height, + this.width, + this.color, + this.fit, + this.alignment, + this.onTap, + this.radius, + this.margin, + this.border, + this.placeHolder = 'assets/images/image_not_found.png', + }); + + @override + Widget build(BuildContext context) { + return alignment != null + ? Align( + alignment: alignment!, + child: _buildWidget(), + ) + : _buildWidget(); + } + + Widget _buildWidget() { + return Padding( + padding: margin ?? EdgeInsets.zero, + child: InkWell( + onTap: onTap, + child: _buildCircleImage(), + ), + ); + } + + ///build the image with border radius + _buildCircleImage() { + if (radius != null) { + return ClipRRect( + borderRadius: radius ?? BorderRadius.zero, + child: _buildImageWithBorder(), + ); + } else { + return _buildImageWithBorder(); + } + } + + ///build the image with border and border radius style + _buildImageWithBorder() { + if (border != null) { + return Container( + decoration: BoxDecoration( + border: border, + borderRadius: radius, + ), + child: _buildImageView(), + ); + } else { + return _buildImageView(); + } + } + + Widget _buildImageView() { + if (imagePath != null) { + switch (imagePath!.imageType) { + case ImageType.svg: + return Container( + height: height, + width: width, + child: SvgPicture.asset( + imagePath!, + height: height, + width: width, + fit: fit ?? BoxFit.contain, + color: color, + ), + ); + case ImageType.file: + return Image.file( + File(imagePath!), + height: height, + width: width, + fit: fit ?? BoxFit.cover, + color: color, + ); + case ImageType.network: + return CachedNetworkImage( + height: height, + width: width, + fit: fit, + imageUrl: imagePath!, + color: color, + placeholder: (context, url) => Container( + height: 30, + width: 30, + child: LinearProgressIndicator( + color: Colors.grey.shade200, + backgroundColor: Colors.grey.shade100, + ), + ), + errorWidget: (context, url, error) => Image.asset( + placeHolder, + height: height, + width: width, + fit: fit ?? BoxFit.cover, + ), + ); + case ImageType.png: + default: + return Image.asset( + imagePath!, + height: height, + width: width, + fit: fit ?? BoxFit.cover, + color: color, + ); + } + } + return SizedBox(); + } +} + +extension ImageTypeExtension on String { + ImageType get imageType { + if (this.startsWith('http') || this.startsWith('https')) { + return ImageType.network; + } else if (this.endsWith('.svg')) { + return ImageType.svg; + } else if (this.startsWith('file://')) { + return ImageType.file; + } else { + return ImageType.png; + } + } +} + +enum ImageType { svg, png, network, file, unknown } diff --git a/lib/widgets/custom_outlined_button.dart b/lib/widgets/custom_outlined_button.dart new file mode 100644 index 00000000..d498755c --- /dev/null +++ b/lib/widgets/custom_outlined_button.dart @@ -0,0 +1,73 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/base_button.dart'; +import 'package:flutter/material.dart'; + +class CustomOutlinedButton extends BaseButton { + CustomOutlinedButton({ + Key? key, + this.decoration, + this.leftIcon, + this.rightIcon, + this.label, + VoidCallback? onPressed, + ButtonStyle? buttonStyle, + TextStyle? buttonTextStyle, + bool? isDisabled, + Alignment? alignment, + double? height, + double? width, + EdgeInsets? margin, + required String text, + }) : super( + text: text, + onPressed: onPressed, + buttonStyle: buttonStyle, + isDisabled: isDisabled, + buttonTextStyle: buttonTextStyle, + height: height, + alignment: alignment, + width: width, + margin: margin, + ); + + final BoxDecoration? decoration; + + final Widget? leftIcon; + + final Widget? rightIcon; + + final Widget? label; + + @override + Widget build(BuildContext context) { + return alignment != null + ? Align( + alignment: alignment ?? Alignment.center, + child: buildOutlinedButtonWidget, + ) + : buildOutlinedButtonWidget; + } + + Widget get buildOutlinedButtonWidget => Container( + height: this.height ?? 30.v, + width: this.width ?? double.maxFinite, + margin: margin, + decoration: decoration, + child: OutlinedButton( + style: buttonStyle, + onPressed: isDisabled ?? false ? null : onPressed ?? () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + leftIcon ?? const SizedBox.shrink(), + Text( + text, + style: buttonTextStyle ?? theme.textTheme.titleSmall, + ), + rightIcon ?? const SizedBox.shrink(), + ], + ), + ), + ); +} diff --git a/lib/widgets/custom_text_form_field.dart b/lib/widgets/custom_text_form_field.dart new file mode 100644 index 00000000..fed08e3f --- /dev/null +++ b/lib/widgets/custom_text_form_field.dart @@ -0,0 +1,135 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class CustomTextFormField extends StatelessWidget { + CustomTextFormField({ + Key? key, + this.alignment, + this.width, + this.controller, + this.focusNode, + this.autofocus = true, + this.textStyle, + this.obscureText = false, + this.textInputAction = TextInputAction.next, + this.textInputType = TextInputType.text, + this.maxLines, + this.hintText, + this.hintStyle, + this.prefix, + this.prefixConstraints, + this.suffix, + this.suffixConstraints, + this.contentPadding, + this.borderDecoration, + this.fillColor, + this.filled = true, + this.validator, + }) : super( + key: key, + ); + + final Alignment? alignment; + + final double? width; + + final TextEditingController? controller; + + final FocusNode? focusNode; + + final bool? autofocus; + + final TextStyle? textStyle; + + final bool? obscureText; + + final TextInputAction? textInputAction; + + final TextInputType? textInputType; + + final int? maxLines; + + final String? hintText; + + final TextStyle? hintStyle; + + final Widget? prefix; + + final BoxConstraints? prefixConstraints; + + final Widget? suffix; + + final BoxConstraints? suffixConstraints; + + final EdgeInsets? contentPadding; + + final InputBorder? borderDecoration; + + final Color? fillColor; + + final bool? filled; + + final FormFieldValidator? validator; + + @override + Widget build(BuildContext context) { + return alignment != null + ? Align( + alignment: alignment ?? Alignment.center, + child: textFormFieldWidget, + ) + : textFormFieldWidget; + } + + Widget get textFormFieldWidget => SizedBox( + width: width ?? double.maxFinite, + child: TextFormField( + controller: controller, + focusNode: focusNode ?? FocusNode(), + autofocus: autofocus!, + style: textStyle ?? theme.textTheme.titleMedium, + obscureText: obscureText!, + textInputAction: textInputAction, + keyboardType: textInputType, + maxLines: maxLines ?? 1, + decoration: decoration, + validator: validator, + ), + ); + InputDecoration get decoration => InputDecoration( + hintText: hintText ?? "", + hintStyle: hintStyle ?? theme.textTheme.bodyLarge, + prefixIcon: prefix, + prefixIconConstraints: prefixConstraints, + suffixIcon: suffix, + suffixIconConstraints: suffixConstraints, + isDense: true, + contentPadding: contentPadding ?? EdgeInsets.all(6.h), + fillColor: fillColor ?? theme.colorScheme.onPrimary, + filled: filled, + border: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + enabledBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + focusedBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide( + color: appTheme.blueA400, + width: 1, + ), + ), + ); +} diff --git a/logs/errors.log b/logs/errors.log new file mode 100644 index 00000000..e69de29b diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000..3b441985 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,37 @@ +name: eatvio_app +description: A new Flutter project. +version: 1.0.0+1 +environment: + sdk: '>=2.12.0 <3.0.0' +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + flutter_bloc: ^8.0.0 + connectivity_plus: ^2.3.6 + shared_preferences: ^2.0.15 + cached_network_image: ^3.2.1 + flutter_svg: ^1.1.6 + equatable: ^2.0.0 +dev_dependencies: + flutter_test: + sdk: flutter +flutter: + uses-material-design: true + assets: + - assets/ + - assets/images/ + fonts: + - family: Segoe UI + fonts: + - asset: assets/fonts/SegoeUISemibold.ttf + weight: 600 + - family: Mulish + fonts: + - asset: assets/fonts/MulishBold.ttf + weight: 700 + - asset: assets/fonts/MulishRegular.ttf + weight: 400 + - asset: assets/fonts/MulishSemiBold.ttf + weight: 600 diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 00000000..e93dc93b --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:eatvio_app/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}