Compare commits

..

No commits in common. 'aamir_dev' and 'main' have entirely different histories.

2
.gitignore vendored

@ -44,5 +44,3 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
pubspec.lock

@ -22,17 +22,13 @@ if (flutterVersionName == null) {
}
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace = "com.cloud.solutions.mowater.ksa.customer"
compileSdkVersion 34
compileSdkVersion 33
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -47,12 +43,11 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.cloud.solutions.mowater.ksa.customer"
minSdkVersion 23
targetSdkVersion 33
applicationId "com.example.car_customer_app"
minSdkVersion 20
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {
@ -70,9 +65,4 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation platform('com.google.firebase:firebase-bom:33.1.2')
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
// implementation 'com.google.firebase:firebase-analytics'
}

@ -1,48 +0,0 @@
{
"project_info": {
"project_number": "294636898500",
"project_id": "mowater-2c81a",
"storage_bucket": "mowater-2c81a.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:294636898500:android:f2f4ae08e5641216b0e191",
"android_client_info": {
"package_name": "com.cloud.solutions.mowater.ksa.customer"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyD1WNNGrbBiCNvCrI31d3DV5AOgToq-Lus"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:294636898500:android:e93b7e5d1cc15ae6b0e191",
"android_client_info": {
"package_name": "com.cloud.solutions.mowater.ksa.provider"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyD1WNNGrbBiCNvCrI31d3DV5AOgToq-Lus"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloud.solutions.mowater.ksa.customer">
package="com.example.car_customer_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

@ -1,75 +1,40 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloud.solutions.mowater.ksa.customer">
package="com.example.car_customer_app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<queries>
<!-- If your app checks for SMS support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
</intent>
</queries>
<application
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="Customer"
android:requestLegacyExternalStorage="true">
<application
android:label="car_customer_app"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" />
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data

@ -1,4 +1,4 @@
package com.cloud.solutions.mowater.ksa.customer
package com.example.car_customer_app
import io.flutter.embedding.android.FlutterActivity

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloud.solutions.mowater.ksa.customer">
package="com.example.car_customer_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

@ -1,36 +1,21 @@
buildscript {
ext.kotlin_version = '1.8.0'
ext.kotlin_version = '1.6.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.7.0'
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.4.2'
}
}
allprojects {
repositories {
google()
mavenCentral()
}
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android {
if (namespace == null) {
namespace project.group
}
}
}
}
}
}
rootProject.buildDir = '../build'
@ -39,6 +24,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
task clean(type: Delete) {
delete rootProject.buildDir
}

@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx4608m
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

@ -1,7 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

@ -1,26 +1,11 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
include ':app'
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.7.0' apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}
include ":app"
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"

@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
<string>9.0</string>
</dict>
</plist>

@ -3,18 +3,17 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
290601682C7B52F80089E959 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 290601672C7B52F80089E959 /* GoogleService-Info.plist */; };
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 */; };
C4EA21C9F0B74349BB44CD80 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D08A35B63A606B490249EC8 /* Pods_Runner.framework */; };
F385BE1E015F5F197DDC457E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CA04DE821BC910C56C29F5B /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -33,15 +32,12 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
290601672C7B52F80089E959 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
3643750A79F4A25346F39B6F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4B7282768BFBEABE15B9F907 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
4D08A35B63A606B490249EC8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4F0574D3DCBBF0F35A33896D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7827FD9C7107464B177EB9D2 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
907B1BD03AA41E852160AA58 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -49,6 +45,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9CA04DE821BC910C56C29F5B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C74C73D850C4D4FC94940060 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -56,7 +54,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C4EA21C9F0B74349BB44CD80 /* Pods_Runner.framework in Frameworks */,
F385BE1E015F5F197DDC457E /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -66,13 +64,22 @@
83F33F395D7AA87F2A896F35 /* Pods */ = {
isa = PBXGroup;
children = (
4B7282768BFBEABE15B9F907 /* Pods-Runner.debug.xcconfig */,
907B1BD03AA41E852160AA58 /* Pods-Runner.release.xcconfig */,
7827FD9C7107464B177EB9D2 /* Pods-Runner.profile.xcconfig */,
4F0574D3DCBBF0F35A33896D /* Pods-Runner.debug.xcconfig */,
C74C73D850C4D4FC94940060 /* Pods-Runner.release.xcconfig */,
3643750A79F4A25346F39B6F /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
96061B8FD0BBF121A96FFCF3 /* Frameworks */ = {
isa = PBXGroup;
children = (
9CA04DE821BC910C56C29F5B /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@ -91,7 +98,7 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
83F33F395D7AA87F2A896F35 /* Pods */,
CD36CFCFD74735932B803147 /* Frameworks */,
96061B8FD0BBF121A96FFCF3 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -106,7 +113,6 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
290601672C7B52F80089E959 /* GoogleService-Info.plist */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@ -119,14 +125,6 @@
path = Runner;
sourceTree = "<group>";
};
CD36CFCFD74735932B803147 /* Frameworks */ = {
isa = PBXGroup;
children = (
4D08A35B63A606B490249EC8 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -134,15 +132,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
44145330272A105A07B117E5 /* [CP] Check Pods Manifest.lock */,
F3B998BE4409F6FFB76727BB /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9CE978214E2117A90C4BD482 /* [CP] Embed Pods Frameworks */,
ECB30C14A75A6A44362620A8 /* [CP] Copy Pods Resources */,
9A2045E27F192C87BCD2FA50 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -159,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1510;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@ -193,7 +190,6 @@
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
290601682C7B52F80089E959 /* GoogleService-Info.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
@ -204,12 +200,10 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@ -218,31 +212,8 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
44145330272A105A07B117E5 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -255,7 +226,7 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
9CE978214E2117A90C4BD482 /* [CP] Embed Pods Frameworks */ = {
9A2045E27F192C87BCD2FA50 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -272,21 +243,26 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
ECB30C14A75A6A44362620A8 /* [CP] Copy Pods Resources */ = {
F3B998BE4409F6FFB76727BB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -364,7 +340,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -380,15 +356,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloud.solutions.mowater.ksa.customer.ios;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@ -443,7 +414,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -492,12 +463,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@ -510,15 +480,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloud.solutions.mowater.ksa.customer.ios;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@ -534,15 +499,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloud.solutions.mowater.ksa.customer.ios;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

@ -1,27 +1,12 @@
import UIKit
import Flutter
import GoogleMaps
import Firebase
import flutter_local_notifications
@main
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
// This is required to make any communication available in the action isolate.
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant.register(with: registry)
}
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
}
GMSServices.provideAPIKey("AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyAQoUIOm-5FtUqUngK0zvkkF2fafRxsm_I</string>
<key>GCM_SENDER_ID</key>
<string>294636898500</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloud.solutions.mowater.ksa.customer.ios</string>
<key>PROJECT_ID</key>
<string>mowater-2c81a</string>
<key>STORAGE_BUCKET</key>
<string>mowater-2c81a.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:294636898500:ios:b47422d0ef4ca385b0e191</string>
</dict>
</plist>

@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
@ -24,33 +22,22 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Used to access media images for car parts</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This App requires access to your location to pick the location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This App requires access to your location to pick the location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This App requires access to your location to pick the location.</string>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

@ -1,8 +1,8 @@
import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/dependencies.dart';
class CustomerDependencies {
static void addDependencies() {
AppDependencies.addDependencies();
}
}

@ -1,37 +1,23 @@
import 'package:car_customer_app/views/branches/branch_detail_view.dart';
import 'package:car_customer_app/views/branches/favourite_list_view.dart';
import 'package:car_customer_app/views/branches/provider_profile_view.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/appointments/appointment_detail_view.dart';
import 'package:mc_common_app/views/appointments/book_appointment_schedules_view.dart';
import 'package:mc_common_app/views/appointments/book_appointment_services_view.dart';
import 'package:mc_common_app/views/appointments/book_appointments_item_view.dart';
import 'package:mc_common_app/views/appointments/review_appointment_view.dart';
import 'package:car_customer_app/views/dashboard/dashboard_view.dart';
import 'package:car_customer_app/views/appointments/appointment_detail_view.dart';
import 'package:car_customer_app/views/appointments/book_appointment_services_view.dart';
import 'package:car_customer_app/views/appointments/pick_items_view.dart';
import 'package:car_customer_app/views/dashboard/dashboard_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/views/branches/branches_filter_view.dart';
import 'package:mc_common_app/views/appointments/appointments_filter_view.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart';
class CustomerAppRoutes {
static final Map<String, WidgetBuilder> routes = {
AppRoutes.dashboard: (context) => DashboardView(dashboardRouteEnum: (ModalRoute.of(context)!.settings.arguments ?? DashboardRouteEnum.none) as DashboardRouteEnum),
AppRoutes.dashboard: (context) => DashboardPage(),
AppRoutes.bookProviderAppView: (context) => BookProviderAppView(),
AppRoutes.appointmentDetailView: (context) => AppointmentDetailView(appointmentListModel: ModalRoute.of(context)!.settings.arguments as AppointmentListModel),
AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => CreateAdView(),
AppRoutes.bookAppointmenServicesView: (context) => BookAppointmentServicesView(),
AppRoutes.bookAppointmenSchedulesView: (context) => BookAppointmentSchedulesView(
screenArgumentsForAppointmentDetailPage: ModalRoute.of(context)!.settings.arguments as ScreenArgumentsForAppointmentDetailPage,
),
AppRoutes.bookAppointmentsItemView: (context) => BookAppointmentsItemView(),
AppRoutes.reviewAppointmentView: (context) => ReviewAppointment(),
AppRoutes.branchDetailView: (context) => BranchDetailView(branchDetailModel: ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
AppRoutes.branchSearchFilterPage: (context) => BranchesFilterView(),
AppRoutes.appoinmentSearchFilterPage: (context) => AppointmentsFilterView(),
AppRoutes.providerProfileView: (context) => ProviderProfileView(providerId: ModalRoute.of(context)!.settings.arguments as int),
AppRoutes.favoriteListView: (context) => FavoriteListView(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(),
};
}
//314187

@ -1,27 +1,14 @@
import 'dart:io';
import 'package:car_customer_app/config/customer_dependencies.dart';
import 'package:car_customer_app/config/customer_routes.dart';
import 'package:flutter/services.dart';
import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/request_repo.dart';
import 'package:mc_common_app/repositories/setting_options_repo.dart';
import 'package:mc_common_app/services/firebase_service.dart';
import 'package:mc_common_app/utils/location/Location.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/general_models/post_params_model.dart';
import 'package:mc_common_app/models/post_params_model.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart';
@ -33,100 +20,56 @@ import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/view_models/setting_options_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:sizer/sizer.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:firebase_core/firebase_core.dart';
final navigatorKey = GlobalKey<NavigatorState>();
//test commit
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
if (Platform.isAndroid) {
await Firebase.initializeApp(
options: const FirebaseOptions(
apiKey: 'AIzaSyD1WNNGrbBiCNvCrI31d3DV5AOgToq-Lus',
appId: '1:294636898500:android:e93b7e5d1cc15ae6b0e191',
messagingSenderId: '294636898500',
projectId: 'mowater-2c81a',
));
} else {
await Firebase.initializeApp();
}
CustomerDependencies.addDependencies();
injector.get<FirebaseMessagingService>().initializeNotifications().whenComplete(() {
injector.get<Location>().handleLocationPermission();
});
await EasyLocalization.ensureInitialized();
CustomerAppRoutes.routes.addAll(AppRoutes.routes);
initializeDateFormatting().then(
(_) => runApp(
MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(
create: (_) => BaseVM(),
),
ChangeNotifierProvider<DashboardVmCustomer>(
create: (_) => DashboardVmCustomer(
commonServices: injector.get<CommonAppServices>(),
userRepo: injector.get<UserRepo>(),
),
),
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(
userRepo: injector.get<UserRepo>(),
commanServices: injector.get<CommonAppServices>(),
),
),
ChangeNotifierProvider<AdVM>(
create: (_) => AdVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
adsRepo: injector.get<AdsRepo>(),
),
),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
appointmentRepo: injector.get<AppointmentRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
branchRepo: injector.get<BranchRepo>(),
),
runApp(
MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(create: (_) => BaseVM()),
ChangeNotifierProvider<DashboardVM>(
create: (_) => DashboardVM(
commonServices: injector.get<CommonAppServices>(),
userRepo: injector.get<UserRepo>(),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(
paymentService: injector.get<PaymentService>(),
paymentRepo: injector.get<PaymentsRepo>(),
),
),
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()),
),
ChangeNotifierProvider<AdVM>(
create: (_) => AdVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
adsRepo: injector.get<AdsRepo>(),
),
ChangeNotifierProvider<ChatVM>(
create: (_) => ChatVM(
chatRepo: injector.get<ChatRepo>(),
requestRepo: injector.get<RequestRepo>(),
commonServices: injector.get<CommonAppServices>(),
)),
ChangeNotifierProvider<RequestsVM>(
create: (_) => RequestsVM(
requestRepo: injector.get<RequestRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<ProvidersVM>(
create: (_) => ProvidersVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
ChangeNotifierProvider<SettingOptionsVM>(
create: (_) => SettingOptionsVM(
settingOptionsRepo: injector.get<SettingOptionsRepo>(),
),
),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
],
child: MyApp(),
).setupLocale(),
),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(paymentService: injector.get<PaymentService>(), paymentRepo: injector.get<PaymentsRepo>()),
),
],
child: const MyApp(),
).setupLocale(),
);
}
@ -141,10 +84,6 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return Sizer(
builder: (context, orientation, deviceType) {
injector.get<AppState>().setAppType(AppType.customer);
@ -153,10 +92,10 @@ class MyApp extends StatelessWidget {
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
),
);
return MaterialApp(
navigatorKey: navigatorKey,
theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
theme: AppTheme.getTheme(
isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar",
),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
@ -168,10 +107,3 @@ class MyApp extends StatelessWidget {
);
}
}
//Latitude: 24.708741, Longitude: 46.6657643,
//Longitude=24.708741&Latitude=46.6657643
//update I/flutter ( 5035): "latitude": "37.421998",
// I/flutter ( 5035): "longitude": "-122.0839",

@ -0,0 +1,102 @@
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_category_model.dart';
import 'package:mc_common_app/models/provider_service_model.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
class AppointmentsVM extends ChangeNotifier {
final CommonRepo commonRepo;
final CommonAppServices commonServices;
AppointmentsVM({required this.commonServices, required this.commonRepo});
bool isFetchingLists = false;
List<AppointmentListModel> myAppointments = [];
List<FilterListModel> appointmentsFilterOptions = [];
bool isFetchingServices = false;
List<ProviderCategoryModel> providerCategories = [];
bool isHomeTapped = false;
void updateIsHomeTapped(bool value) {
isHomeTapped = value;
notifyListeners();
}
String pickedHomeLocation = "";
void updatePickedHomeLocation(String value) {
pickedHomeLocation = value;
notifyListeners();
}
SelectionModel providerCategoryId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateProviderCategoryId(SelectionModel id) async {
providerCategoryId = id;
await getProviderServices(id.selectedId);
notifyListeners();
}
List<ProviderServiceModel> providerServices = [];
SelectionModel providerServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
void updateProviderServiceId(SelectionModel id) async {
providerServiceId = id;
notifyListeners();
}
void getProviderCategories() async {
notifyListeners();
providerCategories = await commonRepo.getProviderServiceCategories();
notifyListeners();
}
getProviderServices(int categoryId) async {
providerServiceId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: "");
isHomeTapped = false;
pickedHomeLocation = "";
if (categoryId != -1) {
isFetchingServices = true;
notifyListeners();
providerServices = await commonRepo.getProviderServices(categoryId: categoryId);
isFetchingServices = false;
notifyListeners();
}
}
populateAppointmentsFilterList() {
appointmentsFilterOptions.clear();
appointmentsFilterOptions = [
FilterListModel(title: "All Appointments", isSelected: true, id: -1),
FilterListModel(title: "Booked", isSelected: false, id: 1),
FilterListModel(title: "Confirmed", isSelected: false, id: 2),
FilterListModel(title: "Arrived", isSelected: false, id: 3),
FilterListModel(title: "Cancelled", isSelected: false, id: 4),
];
notifyListeners();
}
applyFilterOnAppointmentsVM({required int index}) {
if (appointmentsFilterOptions.isEmpty) return;
for (var value in appointmentsFilterOptions) {
value.isSelected = false;
}
appointmentsFilterOptions[index].isSelected = true;
notifyListeners();
}
Future<void> getMyAppointments() async {
isFetchingLists = true;
myAppointments = await commonRepo.getMyAppointments();
isFetchingLists = false;
notifyListeners();
}
}

@ -0,0 +1,55 @@
import 'dart:io';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/user/image_response.dart';
import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:easy_localization/easy_localization.dart';
class DashboardVM extends BaseVM {
final CommonAppServices commonServices;
final UserRepo userRepo;
DashboardVM({required this.commonServices, required this.userRepo});
String pickedImage = "";
int selectedNavbarBarIndex = 2;
void onNavbarTapped(int index) {
selectedNavbarBarIndex = index;
notifyListeners();
}
void pickImageFromPhone(BuildContext context, int sourceFlag) async {
final File? pickedImageFile = await commonServices.pickImageFromPhone(sourceFlag);
if (pickedImageFile == null) {
return;
}
int sizeInBytes = pickedImageFile.lengthSync();
if (sizeInBytes > 1000) {
Utils.showToast(LocaleKeys.fileLarger.tr());
return;
} else {
String image64 = Utils.convertFileToBase64(pickedImageFile);
Utils.showLoading(context);
ImageResponse response = await userRepo.updateUserImage(image64);
Utils.hideLoading(context);
Navigator.pop(context);
if (response.messageStatus == 1) {
Utils.showToast(LocaleKeys.imageUploaded.tr());
AppState().getUser.data!.userInfo!.userImageUrl = response.data;
} else {
Utils.showToast(response.message ?? "");
}
}
}
Future<ImageResponse> updateUserImage(String image) async {
return await userRepo.updateUserImage(image);
}
}

@ -0,0 +1,35 @@
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
class ProvidersVM extends ChangeNotifier {
final CommonRepo commonRepo;
final CommonAppServices commonServices;
ProvidersVM({required this.commonServices, required this.commonRepo});
List<FilterListModel> providersFilterOptions = [];
populateProvidersFilterList() {
providersFilterOptions.clear();
providersFilterOptions = [
FilterListModel(title: "All Providers", isSelected: true, id: -1),
FilterListModel(title: "Maintenance", isSelected: false, id: 0),
FilterListModel(title: "Oil Service", isSelected: false, id: 1),
FilterListModel(title: "Accessories", isSelected: false, id: 2),
FilterListModel(title: "Tire Service", isSelected: false, id: 3),
FilterListModel(title: "Dent and Paint", isSelected: false, id: 4),
];
notifyListeners();
}
applyFilterOnProviders({required int index}) {
if (providersFilterOptions.isEmpty) return;
for (var value in providersFilterOptions) {
value.isSelected = false;
}
providersFilterOptions[index].isSelected = true;
notifyListeners();
}
}

@ -0,0 +1,128 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/card_button_with_icon.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class AppointmentDetailView extends StatelessWidget {
AppointmentListModel appointmentListModel;
AppointmentDetailView({Key? key, required this.appointmentListModel}) : super(key: key);
final List<String> servicesList = [
"Mechanic",
"Electrician",
" Car Denting",
"Oil Change",
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Appointment",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
),
body: Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Stack(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
appointmentListModel.providerName!.toText(fontSize: 18, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyAssets.miniClockDark.buildSvg(
height: 10,
width: 10,
fit: BoxFit.fill,
),
10.width,
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}".toText(fontSize: 12, isBold: true, color: MyColors.lightTextColor),
],
),
13.height,
Row(
children: [
MyAssets.maintenanceIcon.buildSvg(
height: 10,
width: 10,
fit: BoxFit.fill,
),
10.width,
"Maintenance".toText(fontSize: 18, isBold: true),
],
),
Column(
children: servicesList
.map((e) => e
.toText(
textAlign: TextAlign.start,
fontSize: 13,
isBold: true,
color: MyColors.lightTextColor,
)
.paddingOnly(bottom: 5))
.toList(),
).paddingOnly(left: 15),
15.height,
Row(
children: [
CardButtonWithIcon(
title: "Reschedule Appointment",
onCardTapped: () {},
icon: MyAssets.scheduleAppointmentIcon.buildSvg(),
),
10.width,
CardButtonWithIcon(
title: "Pay for Appointment",
onCardTapped: () {},
icon: MyAssets.creditCardIcon.buildSvg(),
),
],
),
15.height,
],
).toWhiteContainer(width: double.infinity, allPading: 12),
Align(
alignment: Alignment.bottomCenter,
child: Row(
children: [
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Cancel",
onPressed: () {},
backgroundColor: MyColors.redColor,
),
),
if (appointmentListModel.appointmentStatusID == 1) ...[
12.width,
Expanded(
child: ShowFillButton(
maxHeight: 55,
title: "Confirm",
onPressed: () {},
backgroundColor: MyColors.greenColor,
),
),
],
],
),
),
],
),
),
);
}
}

@ -0,0 +1,325 @@
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/views/advertisement/custom_add_button.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
class BookAppointmentServicesView extends StatelessWidget {
const BookAppointmentServicesView({Key? key}) : super(key: key);
void openTheAddServiceBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
AppointmentsVM appointmentsVM = context.watch<AppointmentsVM>();
return SizedBox(
height: MediaQuery.of(context).size.height * 0.85,
child: Column(
children: [
Container(
margin: const EdgeInsets.all(8),
height: 8,
width: 60,
decoration: const BoxDecoration(color: MyColors.lightTextColor, borderRadius: BorderRadius.all(Radius.circular(20))),
),
12.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Select Category".toText(fontSize: 24, isBold: true),
],
),
30.height,
Expanded(
child: ListView(
children: [
Builder(
builder: (context) {
List<DropValue> serviceCategories = [];
for (var element in appointmentsVM.providerCategories) {
if (!element.isSelected!) {
serviceCategories.add(DropValue(element.id?.toInt() ?? 0, element.categoryName ?? "", ""));
}
}
return DropdownField(
(DropValue value) => appointmentsVM.updateProviderCategoryId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: serviceCategories,
hint: "Select Category",
dropdownValue: appointmentsVM.providerCategoryId.selectedId != -1
? DropValue(appointmentsVM.providerCategoryId.selectedId, appointmentsVM.providerCategoryId.selectedOption, "")
: null,
);
},
),
if (appointmentsVM.isFetchingServices) ...[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [const CircularProgressIndicator().paddingAll(10)],
),
] else if (appointmentsVM.providerServices.isNotEmpty) ...[
8.height,
Builder(
builder: (context) {
List<DropValue> serviceCategories = [];
for (var element in appointmentsVM.providerServices) {
if (!element.isSelected!) {
serviceCategories.add(DropValue(element.id?.toInt() ?? 0, element.id.toString(), ""));
}
}
return DropdownField(
(DropValue value) => appointmentsVM.updateProviderServiceId(SelectionModel(selectedId: value.id, selectedOption: value.value, itemPrice: value.subValue)),
list: serviceCategories,
hint: "Select Services",
dropdownValue: appointmentsVM.providerServiceId.selectedId != -1
? DropValue(appointmentsVM.providerServiceId.selectedId, appointmentsVM.providerServiceId.selectedOption, "")
: null,
);
},
),
],
if (appointmentsVM.providerServiceId.selectedId != -1 && !appointmentsVM.isFetchingServices) ...[
16.height,
Row(
children: [
"Select Service Location".toText(
fontSize: 16,
isBold: true,
color: MyColors.black,
),
],
),
8.height,
Row(
children: [
Expanded(
child: ShowFillButton(
isFilled: appointmentsVM.isHomeTapped,
maxHeight: 48,
title: "Home",
txtColor: appointmentsVM.isHomeTapped ? MyColors.white : MyColors.darkTextColor,
onPressed: () => appointmentsVM.updateIsHomeTapped(true),
),
),
12.width,
Expanded(
child: ShowFillButton(
isFilled: !appointmentsVM.isHomeTapped,
txtColor: !appointmentsVM.isHomeTapped ? MyColors.white : MyColors.darkTextColor,
maxHeight: 48,
title: "Workshop",
onPressed: () => appointmentsVM.updateIsHomeTapped(false),
),
),
],
),
if (appointmentsVM.isHomeTapped) ...[
8.height,
TxtField(
hint: 'Pick Home Location',
value: appointmentsVM.pickedHomeLocation,
isNeedClickAll: true,
postfixData: Icons.location_on,
postFixDataColor: MyColors.darkTextColor,
onTap: () {
//TODO: open the place picked to pick the location and save it in provider.
appointmentsVM.updatePickedHomeLocation("PM58+F97, Al Olaya, Riyadh 12333");
},
),
14.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Icon(
Icons.warning,
color: MyColors.adPendingStatusColor,
size: 19,
).paddingOnly(bottom: 2),
3.width,
"Some services are not available on home location.".toText(
color: MyColors.adPendingStatusColor,
fontSize: 12,
isItalic: true,
),
],
),
]
],
],
),
),
SizedBox(
width: double.infinity,
child: Column(
children: [
if (appointmentsVM.isHomeTapped && !appointmentsVM.isFetchingServices) ...[
const Divider(thickness: 1, height: 1),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
// TODO: This Price will be decided according to the service selected
150.toString().toText(fontSize: 30, isBold: true),
"SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5),
],
),
"These charges are additional to the actual service charges. For heavy items the charges may vary.".toText(fontSize: 12, color: MyColors.lightTextColor),
22.height,
],
SizedBox(
width: double.infinity,
child: ShowFillButton(
maxHeight: 55,
title: "Next",
onPressed: () {},
),
),
],
),
).paddingOnly(bottom: 20)
],
)).horPaddingMain();
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Book Appointment",
isRemoveBackButton: false,
isDrawerEnabled: false,
actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)],
onBackButtonTapped: () => Navigator.pop(context),
),
body: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
21.height,
CustomAddButton(
onTap: () => {openTheAddServiceBottomSheet(context)},
text: "Add Services",
icon: Container(
height: 24,
width: 24,
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: const Icon(Icons.add, color: MyColors.white),
),
),
// 20.height,
// ListView.builder(
// physics: const NeverScrollableScrollPhysics(),
// shrinkWrap: true,
// itemCount: adVM.specialServiceCards.length,
// itemBuilder: (BuildContext context, int index) {
// SpecialServiceCard specialServicesCard = adVM.specialServiceCards[index];
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Column(
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Expanded(
// child: specialServicesCard.serviceSelectedId!.selectedOption.toText(fontSize: 16, isBold: true),
// ),
// Align(
// alignment: Alignment.topRight,
// child: MyAssets.closeWithOrangeBg.buildSvg(
// fit: BoxFit.fill,
// height: 30,
// width: 30,
// ),
// ).onPress(() => adVM.removeSpecialServiceCard(index))
// ],
// ),
// Builder(builder: (context) {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// if (specialServicesCard.serviceSelectedId!.selectedId != 1 && specialServicesCard.serviceSelectedId!.selectedId != 3) ...[
// // Row(
// // crossAxisAlignment: CrossAxisAlignment.start,
// // children: [
// // "Duration: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
// // (specialServicesCard.duration ?? "").toText(fontSize: 12, isBold: true).expand(),
// // ],
// // ),
// 8.height,
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// "Description: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
// (specialServicesCard.description ?? "").toText(fontSize: 12, isBold: true).expand(),
// ],
// ),
// ],
// if (specialServicesCard.serviceSelectedId!.selectedId == 1 || specialServicesCard.serviceSelectedId!.selectedId == 3) ...[
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Icon(
// weight: 2,
// Icons.location_on_outlined,
// color: MyColors.primaryColor,
// size: 17,
// ),
// "${specialServicesCard.duration} km".toText(fontSize: 10, color: MyColors.primaryColor),
// ],
// ),
// 8.height,
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// "Branch Address: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
// (specialServicesCard.address ?? "").toText(fontSize: 12, isBold: true).expand(),
// ],
// ),
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// "Appointment Time: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
// "${specialServicesCard.serviceDate} - ${specialServicesCard.serviceTime}".toText(fontSize: 12, isBold: true).expand(),
// ],
// ),
// ],
// 6.height,
// Row(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// (specialServicesCard.serviceSelectedId!.itemPrice).toText(fontSize: 20, isBold: true),
// 2.width,
// "SAR".toText(color: MyColors.lightTextColor, fontSize: 14),
// ],
// ),
// ],
// );
// }),
// 3.height,
// const Divider(thickness: 1.5)
// ],
// ),
// 10.height,
// ],
// );
// },
// ),
],
);
},
).horPaddingMain());
}
}

@ -0,0 +1,168 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class BookProviderAppView extends StatefulWidget {
const BookProviderAppView({Key? key}) : super(key: key);
@override
State<BookProviderAppView> createState() => _BookProviderAppViewState();
}
class _BookProviderAppViewState extends State<BookProviderAppView> {
bool isReview = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Appointment",
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false,
isDrawerEnabled: false,
),
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: ListView(
children: [
ProviderDetailsCard(
onCardTapped: () {},
providerImageUrl: MyAssets.bnCar,
providerLocation: "3km",
providerName: "Al Ahmed Maintenance",
providerRatings: "4.9",
),
12.height,
isReview ? ReviewAppointmentSection() : ServicesSelectionSection(),
10.height,
],
),
),
10.height,
Padding(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: ShowFillButton(
title: "Book Appointment",
maxWidth: double.infinity,
onPressed: () {
isReview = !isReview;
setState(() {});
},
),
),
],
),
),
);
}
}
class ServicesSelectionSection extends StatelessWidget {
const ServicesSelectionSection({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
List<DropValue> dropList = [
DropValue(0, "Maintenance", ""),
DropValue(1, "Car Wash", ""),
DropValue(2, "Monthly Checkup", ""),
DropValue(3, "Friendly Visit", ""),
DropValue(4, "Muftaa", ""),
];
return Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Select services you want".toText(fontSize: 18, isBold: true),
8.height,
DropdownField(
(DropValue value) {},
list: dropList,
hint: "Select service type",
),
8.height,
DropdownField(
(DropValue value) {},
list: dropList,
hint: "Select service type",
),
8.height,
DropdownField(
(DropValue value) {},
list: dropList,
hint: "Select service type",
),
22.height,
"Select date and time".toText(fontSize: 18, isBold: true),
8.height,
DropdownField(
(DropValue value) {},
list: dropList,
hint: "Select service type",
),
22.height,
"Available slots".toText(fontSize: 15, isBold: true),
8.height,
BuildTimeSlots(onPressed: (index) {}, timeSlots: []),
22.height,
"Total Amount".toText(fontSize: 18, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"3000".toText(fontSize: 20, isBold: true),
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
10.height,
],
).toWhiteContainer(width: double.infinity, allPading: 12),
);
}
}
class ReviewAppointmentSection extends StatelessWidget {
const ReviewAppointmentSection({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Review Appointment".toText(fontSize: 18, isBold: true),
15.height,
"Services".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"Car Engine Check".toText(fontSize: 18, isBold: true),
13.height,
"Date and Time".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"2 Feb, 2023 at 09:00am".toText(fontSize: 18, isBold: true),
13.height,
"Total Amount".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"3000".toText(fontSize: 20, isBold: true),
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor),
],
),
100.height,
],
).toWhiteContainer(width: double.infinity, allPading: 12),
);
}
}

@ -0,0 +1,199 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomerAppointmentSliderWidget extends StatelessWidget {
final List<AppointmentListModel> myUpComingAppointments;
const CustomerAppointmentSliderWidget({Key? key, required this.myUpComingAppointments}) : super(key: key);
@override
Widget build(BuildContext context) {
if (myUpComingAppointments.isEmpty) {
return InkWell(
child: Container(
height: 86,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 24,
width: 24,
decoration: BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor),
child: Icon(
Icons.add,
color: MyColors.white,
),
),
SizedBox(width: 10),
"Add New Appointment".toText(
fontSize: 15,
isBold: true,
color: MyColors.lightTextColor,
),
],
),
),
).toWhiteContainer(width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 21, vertical: 10));
}
return CarouselSlider.builder(
options: CarouselOptions(
height: 140,
viewportFraction: 1.0,
enlargeCenterPage: false,
enableInfiniteScroll: false,
),
itemCount: myUpComingAppointments.length,
itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => BuildAppointmentContainerForCustomer(
isForHome: true,
appointmentListModel: myUpComingAppointments[itemIndex],
onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: myUpComingAppointments[itemIndex]),
),
);
}
}
class BuildAppointmentContainerForCustomer extends StatelessWidget {
final bool? isForHome;
final AppointmentListModel? appointmentListModel;
final Function() onTapped;
const BuildAppointmentContainerForCustomer({Key? key, this.isForHome = false, required this.onTapped, required this.appointmentListModel}) : super(key: key);
Widget showServices(String title, String icon, {bool isMoreText = false}) {
return Row(
children: [
if (icon != "") ...[
SvgPicture.asset(icon),
8.width,
],
Flexible(
child: title.toText(
fontSize: 12,
isBold: true,
color: isMoreText ? MyColors.primaryColor : MyColors.black,
),
),
],
);
}
List<Widget> buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) {
if (appointmentListModel.serviceAppointmentItems == null || appointmentListModel.serviceAppointmentItems!.isEmpty) {
return [SizedBox()];
}
if (appointmentListModel.serviceAppointmentItems!.length == 1) {
return [
showServices(
appointmentListModel.serviceAppointmentItems![0].serviceItemName!,
MyAssets.modificationsIcon,
)
];
}
List<Widget> servicesList = List.generate(
2,
(index) => showServices(
appointmentListModel.serviceAppointmentItems![index].serviceItemName!,
MyAssets.modificationsIcon,
),
);
if (appointmentListModel.serviceAppointmentItems!.length > 1) {
servicesList.add(
showServices(
"+ ${appointmentListModel.serviceAppointmentItems!.length - 1} More",
"",
isMoreText: true,
),
);
}
return servicesList;
}
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
isForHome != null && isForHome!
? Image.asset(
MyAssets.bnCar,
width: 56,
height: 56,
fit: BoxFit.fill,
).toCircle(borderRadius: 100)
: Image.asset(
MyAssets.bnCar,
width: 80,
height: 85,
fit: BoxFit.cover,
),
8.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(appointmentListModel!.providerName ?? "").toText(color: MyColors.black, isBold: true, fontSize: 16),
Row(
children: [
MyAssets.miniClock.buildSvg(height: 12),
2.width,
"${appointmentListModel!.duration ?? ""} ${appointmentListModel!.appointmentDate!.toFormattedDateWithoutTime()}".toText(
color: MyColors.lightTextColor,
fontSize: 12,
),
],
),
9.height,
isForHome != null && isForHome!
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"Appointment Details".toText(
color: MyColors.primaryColor,
isUnderLine: true,
isBold: true,
fontSize: 14,
),
const Icon(Icons.arrow_forward),
],
)
: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Column(
children: buildServicesFromAppointment(appointmentListModel: appointmentListModel!),
),
),
const Icon(
Icons.arrow_forward,
),
],
),
],
),
),
],
),
],
).onPress(onTapped).toWhiteContainer(width: double.infinity, allPading: 12),
);
}
}

@ -1,267 +0,0 @@
import 'dart:async';
import 'package:car_customer_app/views/branches/components/branch_reviews_widget.dart';
import 'package:car_customer_app/views/branches/components/items_list_sheet.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/views/advertisement/components/ads_images_corousel_widget.dart';
import 'package:mc_common_app/widgets/bottom_sheet.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class BranchDetailView extends StatefulWidget {
final BranchDetailModel branchDetailModel;
BranchDetailView({required this.branchDetailModel});
@override
State<BranchDetailView> createState() => _BranchDetailViewState();
}
class _BranchDetailViewState extends State<BranchDetailView> {
late AppointmentsVM appointmentsVM;
@override
void initState() {
appointmentsVM = context.read<AppointmentsVM>();
super.initState();
if (widget.branchDetailModel.branchServices!.length > 0) widget.branchDetailModel.branchServices?.first.isExpandedOrSelected = true;
getBranchReviews();
}
Future<void> getBranchReviews() async {
scheduleMicrotask(() async {
await appointmentsVM.getReviewsByBranchId(serviceProviderBranchID: widget.branchDetailModel.id!);
});
}
@override
void dispose() {
appointmentsVM.resetCurrentBranchRatings();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.branchDetail.tr(),
actions: [
// Padding(
// padding: EdgeInsets.only(top: 8, bottom: 8, right: 21),
// child: const Icon(Icons.messenger_outline_rounded, color: Colors.black, size: 18).toContainer(
// borderRadius: 100,
// borderColor: MyColors.lightGreyEFColor,
// isEnabledBorder: true,
// ),
// ).onPress(() {})
],
),
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Container(
width: double.infinity,
padding: EdgeInsets.all(21),
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ImagesCorouselWidget(imagesList: widget.branchDetailModel.branchImages ?? []),
12.height,
"${widget.branchDetailModel.branchName} | ${widget.branchDetailModel.serviceProviderName}".toString().toText(
fontSize: 16,
isBold: true,
),
Row(
children: [
(LocaleKeys.location.tr() + ":").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
(widget.branchDetailModel.distanceKm.toString() + " km").toText(fontSize: 12, isBold: true),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
(LocaleKeys.time.tr() + ":").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
Flexible(
child: "${widget.branchDetailModel.openTime} - ${widget.branchDetailModel.closeTime}".toText(fontSize: 12, isBold: true),
)
],
),
2.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if ((widget.branchDetailModel.latitude != null && widget.branchDetailModel.latitude!.isNotEmpty) && (widget.branchDetailModel.longitude != null && widget.branchDetailModel.longitude!.isNotEmpty)) ...[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.openMapLocation.tr().toText(
fontSize: 12,
isBold: true,
color: MyColors.primaryColor,
isUnderLine: true,
),
4.width,
Image.asset(
MyAssets.icRightUpPng,
height: 6,
width: 6,
color: MyColors.primaryColor,
),
],
).padding(EdgeInsets.symmetric(vertical: 6, horizontal: 2)).onPress(() async {
double latitude, longitude = 0.0;
latitude = double.parse(widget.branchDetailModel.latitude!);
longitude = double.parse(widget.branchDetailModel.longitude!);
await Utils.openLocationInMaps(latitude: latitude, longitude: longitude);
}),
] else ...[
SizedBox(),
],
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
LocaleKeys.providerProfile.tr().toText(
fontSize: 12,
isBold: true,
color: MyColors.primaryColor,
isUnderLine: true,
),
2.width,
Icon(
Icons.arrow_forward,
size: 12,
color: MyColors.primaryColor,
),
],
).padding(EdgeInsets.symmetric(vertical: 6, horizontal: 2)).onPress(() => navigateWithName(context, AppRoutes.providerProfileView, arguments: widget.branchDetailModel.serviceProviderId)),
],
),
20.height,
LocaleKeys.servicesOffer.tr().toText(
fontSize: 16,
color: MyColors.lightTextColor,
isBold: true,
),
if (widget.branchDetailModel.branchServices!.length == 0)
LocaleKeys.noServicesAvailable.tr().toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
buildServicesList(),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
10.height,
BranchReviewsWidget(branchRateAvg: widget.branchDetailModel.branchRateAvg ?? 0.0),
],
),
),
),
),
ShowFillButton(
maxHeight: 55,
isDisabled: widget.branchDetailModel.branchServices!.length == 0,
title: LocaleKeys.bookAppointment.tr(),
margin: EdgeInsets.all(12),
maxWidth: double.infinity,
onPressed: () {
if (widget.branchDetailModel.branchServices!.length == 0) {
Utils.showToast(LocaleKeys.noServicesAvailable.tr());
return;
}
navigateWithName(context, AppRoutes.bookAppointmenServicesView);
context.read<AppointmentsVM>().updateSelectedBranch(widget.branchDetailModel);
},
),
],
),
);
}
Widget buildServicesList() {
return ListView.separated(
itemBuilder: (context, index) {
return ExpansionTile(
tilePadding: EdgeInsets.zero,
title: (widget.branchDetailModel.branchServices![index].serviceDescription ?? "").toText(fontSize: 16),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showItem(LocaleKeys.allowingHomeService.tr() + " :", (widget.branchDetailModel.branchServices![index].isAllowAppointment ?? false) ? LocaleKeys.yes.tr() : LocaleKeys.no.tr(), valueColor: Colors.green),
if ((widget.branchDetailModel.branchServices![index].isAllowAppointment ?? false)) ...[
showItem(LocaleKeys.homeServiceRange.tr() + " :", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + "KM"),
showItem(LocaleKeys.chargesPerKM.tr() + " :", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + LocaleKeys.sar.tr()),
],
8.height,
((widget.branchDetailModel.branchServices![index].itemsCount != null && widget.branchDetailModel.branchServices![index].itemsCount! > 0)
? widget.branchDetailModel.branchServices![index].itemsCount.toString() + " items"
: "No" + " items")
.toText(
fontSize: 12,
isBold: true,
color: MyColors.primaryColor,
isUnderLine: true,
),
20.height,
],
).onPress(() {
if (widget.branchDetailModel.branchServices![index].itemsCount != null && widget.branchDetailModel.branchServices![index].itemsCount! > 0) {
showMyBottomSheet(context, child: ItemsListSheet(widget.branchDetailModel.branchServices![index].serviceProviderServiceId ?? 0));
}
}),
],
onExpansionChanged: (value) {
setState(() {
widget.branchDetailModel.branchServices![index].isExpandedOrSelected = value;
});
},
backgroundColor: Colors.transparent,
collapsedBackgroundColor: Colors.transparent,
initiallyExpanded: widget.branchDetailModel.branchServices![index].isExpandedOrSelected,
trailing: widget.branchDetailModel.branchServices![index].isExpandedOrSelected ? Icon(Icons.keyboard_arrow_up) : Icon(Icons.keyboard_arrow_down),
);
},
separatorBuilder: (context, index) {
return Divider(
height: 1,
);
},
itemCount: widget.branchDetailModel.branchServices!.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
);
}
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
item.toText(fontSize: 12, color: MyColors.lightTextColor),
4.width,
value.toText(fontSize: 12, color: valueColor),
],
);
}
}

@ -1,108 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_review_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class BranchReviewsWidget extends StatelessWidget {
final double branchRateAvg;
const BranchReviewsWidget({super.key, required this.branchRateAvg});
@override
Widget build(BuildContext context) {
return Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocaleKeys.review.tr().toText(fontSize: 18, isBold: true, letterSpacing: 0.1),
if (branchRateAvg != 0.0) ...[
"$branchRateAvg".toString().toText(fontSize: 18, isBold: true, letterSpacing: 0.1),
]
],
),
10.height,
if (appointmentsVM.state == ViewState.busy) ...[
Center(child: CircularProgressIndicator())
] else if (appointmentsVM.currentBranchReviews.isEmpty) ...[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.noReviewsBranch.tr().toText(fontSize: 14, color: MyColors.lightTextColor),
],
),
] else ...[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(
5,
(index) => MyAssets.icStar.buildSvg(
color: (index <= branchRateAvg - 1) ? MyColors.lightPrimaryColor : MyColors.lightGreyDDColor,
height: 50,
),
),
),
10.height,
ListView.separated(
separatorBuilder: (context, index) => Divider(height: 1),
itemCount: !appointmentsVM.isReadMoreEnabled ? 3 : appointmentsVM.currentBranchReviews.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
BranchRatingModel rating = appointmentsVM.currentBranchReviews[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
10.height,
Row(
children: [
("${rating.title} - ${rating.ratNo}.0").toText(fontSize: 14, isBold: true),
MyAssets.icStar.buildSvg(color: MyColors.darkPrimaryColor, height: 13).paddingOnly(left: 5, bottom: 2),
],
),
3.height,
Row(
children: [
Expanded(
flex: 9,
child: "${rating.review}".toText(fontSize: 12, color: MyColors.lightTextColor),
),
Expanded(
flex: 3,
child: "-${rating.customerName ?? "Unknown"}".toText(fontSize: 2, color: MyColors.lightTextColor),
),
],
),
10.height,
],
);
},
),
if (appointmentsVM.isReadMoreEnabled) ...[
LocaleKeys.readLess.tr().toText(fontSize: 13, color: MyColors.darkPrimaryColor, isUnderLine: true).onPress(() {
appointmentsVM.updateIsReadMoreEnabled(false);
}),
] else ...[
LocaleKeys.readMoreReviews.tr().toText(fontSize: 13, color: MyColors.darkPrimaryColor, isUnderLine: true).onPress(() {
appointmentsVM.updateIsReadMoreEnabled(true);
}),
]
]
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
);
});
}
}

@ -1,119 +0,0 @@
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/empty_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class ItemsListSheet extends StatefulWidget {
final int serviceProviderServiceId;
ItemsListSheet(this.serviceProviderServiceId);
@override
State<ItemsListSheet> createState() => _ItemsListSheetState();
}
class _ItemsListSheetState extends State<ItemsListSheet> {
void initState() {
super.initState();
scheduleMicrotask(() {
context.read<AppointmentsVM>().getServiceItems(serviceId: widget.serviceProviderServiceId);
});
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.2,
child: Consumer<AppointmentsVM>(
builder: (context, appointmentsVM, _) {
if (appointmentsVM.state == ViewState.busy) {
return Center(child: CircularProgressIndicator());
}
return appointmentsVM.serviceItemsFromApi.isEmpty
? EmptyWidget(text: LocaleKeys.noItemsToShow.tr(), isWrappedColumn: false)
: ListView.separated(
itemCount: appointmentsVM.serviceItemsFromApi.length,
itemBuilder: (BuildContext context, int index) {
ItemData serviceItemModel = appointmentsVM.serviceItemsFromApi[index];
return SizedBox(
width: double.infinity,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
serviceItemModel.name.toString().toText(fontSize: 16, isBold: true),
serviceItemModel.description.toString().toText(fontSize: 12, color: MyColors.lightTextColor),
8.height,
if (serviceItemModel.manufactureDate != null && serviceItemModel.manufactureDate!.isNotEmpty) ...[
showItem(LocaleKeys.manufacturedOn.tr() + ":", (DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(serviceItemModel.manufactureDate!))),
valueColor: MyColors.darkTextColor),
],
showItem(LocaleKeys.availableforAppointment.tr() + ":", (serviceItemModel.isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem(LocaleKeys.allowingWorkshopService.tr() + ":", (serviceItemModel.isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem(LocaleKeys.allowingHomeService.tr() + ":", (serviceItemModel.isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
12.height,
LocaleKeys.serviceAmount.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
serviceItemModel.price!.toText(fontSize: 22, isBold: true),
2.width,
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: LocaleKeys.sar.tr().toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
),
],
),
],
),
),
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset(
// MyAssets.icEdit,
// width: 16,
// height: 16,
// ),
// )
],
),
).toWhiteContainer(width: double.infinity, allPading: 12);
},
separatorBuilder: (BuildContext context, int index) {
return 12.height;
},
padding: const EdgeInsets.all(20),
);
},
),
);
}
Widget showItem(String item, String value, {Color valueColor = Colors.black}) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
item.toText(fontSize: 12, color: MyColors.lightTextColor),
4.width,
value.toText(fontSize: 12, color: valueColor, isBold: true),
],
);
}
}

@ -1,93 +0,0 @@
import 'dart:async';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_profile_model.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class FavoriteListView extends StatefulWidget {
const FavoriteListView({Key? key}) : super(key: key);
@override
State<FavoriteListView> createState() => _FavoriteListViewState();
}
class _FavoriteListViewState extends State<FavoriteListView> {
@override
void initState() {
scheduleMicrotask(() async => context.read<AppointmentsVM>().getMyFavoriteProviders());
super.initState();
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.favoriteList.tr(),
isRemoveBackButton: false,
),
body: RefreshIndicator(
onRefresh: () async {
await context.read<AppointmentsVM>().getMyFavoriteProviders();
},
child: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: Container(
width: double.infinity,
child: appointmentsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: appointmentsVM.myFavProvidersList.isEmpty
? Center(
child: (LocaleKeys.noProvidersInFav.tr()).toText(
fontSize: 16,
color: MyColors.lightTextColor,
),
)
: ListView.separated(
itemCount: appointmentsVM.myFavProvidersList.length,
itemBuilder: (context, index) {
ProviderProfileModel providerProfileModel = appointmentsVM.myFavProvidersList[index];
return ProviderDetailCard(
isFromFavoriteList: true,
onCardTapped: () => navigateWithName(context, AppRoutes.providerProfileView, arguments: providerProfileModel.providerID),
providerImageUrl: providerProfileModel.profileImage ?? "",
title: providerProfileModel.name ?? "",
description: providerProfileModel.companyDescription ?? "",
startedSince: DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(providerProfileModel.memberSince ?? ""))),
branches: providerProfileModel.serviceProviderBranch ?? [],
totalBranches: (providerProfileModel.noOfBranches ?? 0).toString(),
);
},
separatorBuilder: (context, index) => 12.height,
padding: const EdgeInsets.all(12),
),
).paddingOnly(left: 10, right: 10),
),
],
),
),
),
);
},
);
}
}

@ -1,161 +0,0 @@
import 'dart:async';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/branch_details_card.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class ProviderProfileView extends StatefulWidget {
final int providerId;
ProviderProfileView({required this.providerId});
@override
State<ProviderProfileView> createState() => _ProviderProfileViewState();
}
class _ProviderProfileViewState extends State<ProviderProfileView> {
@override
void initState() {
super.initState();
scheduleMicrotask(() async => context.read<AppointmentsVM>().getProviderProfileWithBranchesAndServices(widget.providerId));
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy || appointmentsVM.providerProfileModel == null) {
return Scaffold(
backgroundColor: MyColors.white,
appBar: CustomAppBar(
title: LocaleKeys.providerDetails.tr(),
),
body: Center(child: CircularProgressIndicator()),
);
}
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.providerDetails.tr(),
actions: [
Icon(
appointmentsVM.providerProfileModel!.isFavorite! ? Icons.favorite : Icons.favorite_border,
color: appointmentsVM.providerProfileModel!.isFavorite! ? MyColors.darkPrimaryColor : MyColors.black,
).horPaddingMain().onPress(
() async {
if (appointmentsVM.providerProfileModel!.isFavorite!) {
bool status = await appointmentsVM.removeProviderFromFavorite(serviceProviderID: appointmentsVM.providerProfileModel!.id!, context: context);
if (status) {
appointmentsVM.providerProfileModel!.isFavorite = false;
appointmentsVM.getMyFavoriteProviders();
setState(() {});
}
} else {
bool status = await appointmentsVM.addProviderToFavorite(serviceProviderID: appointmentsVM.providerProfileModel!.id!, context: context);
if (status) {
appointmentsVM.providerProfileModel!.isFavorite = true;
setState(() {});
}
}
},
),
],
),
body: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 21),
child: SingleChildScrollView(
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(child: appointmentsVM.providerProfileModel!.profileImage.buildNetworkImage(height: 250, width: double.infinity, fit: BoxFit.cover)),
12.height,
if (appointmentsVM.providerProfileModel!.memberSince!.isNotEmpty) ...[
Row(
children: [
("${LocaleKeys.companyName.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
(appointmentsVM.providerProfileModel!.companyName ?? appointmentsVM.providerProfileModel!.name).toString().toText(
fontSize: 16,
isBold: true,
),
],
),
],
if (appointmentsVM.providerProfileModel!.memberSince!.isNotEmpty) ...[
Row(
children: [
("${LocaleKeys.memberSince.tr()}:").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
"${DateHelper.formatAsMonthYear(
DateHelper.parseStringToDate(
DateHelper.formatDateT(
appointmentsVM.providerProfileModel!.memberSince ?? "",
),
),
)}"
.toText(fontSize: 12, isBold: true),
],
),
],
4.height,
appointmentsVM.providerProfileModel!.companyDescription!.toText(color: MyColors.lightTextColor, fontSize: 12),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
12.height,
appointmentsVM.providerProfileModel!.serviceProviderBranch == null
? Center(
child: (LocaleKeys.noBranchFound.tr()).toText(
fontSize: 16,
color: MyColors.lightTextColor,
),
)
: appointmentsVM.providerProfileModel!.serviceProviderBranch!.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
BranchDetailModel branchModel = appointmentsVM.providerProfileModel!.serviceProviderBranch![index];
return BranchDetailCard(
onCardTapped: () {
navigateWithName(context, AppRoutes.branchDetailView, arguments: branchModel);
},
providerImageUrl: (branchModel.branchImages != null && branchModel.branchImages!.isNotEmpty) ? (branchModel.branchImages!.first.imageUrl ?? "") : "",
title: branchModel.branchName ?? "",
providerLocation: branchModel.distanceKm.toString() + " KM",
providerName: branchModel.serviceProviderName ?? "",
providerRatings: (branchModel.branchRateAvg ?? 0.0),
services: branchModel.branchServices,
);
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: appointmentsVM.providerProfileModel!.serviceProviderBranch!.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
)
],
),
),
),
);
},
);
}
}

@ -0,0 +1,104 @@
import 'dart:async';
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:car_customer_app/views/dashboard/fragments/ads_fragment.dart';
import 'package:car_customer_app/views/dashboard/fragments/appointments_fragment.dart';
import 'package:car_customer_app/views/dashboard/fragments/home_fragment.dart';
import 'package:car_customer_app/views/dashboard/fragments/providers_fragment.dart';
import 'package:car_customer_app/views/dashboard/fragments/settings_fragment.dart';
import 'package:car_customer_app/views/dashboard/widgets/bottom_nav_bar.dart';
import 'package:car_customer_app/views/dashboard/widgets/drawer_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class DashboardPage extends StatefulWidget {
const DashboardPage({Key? key}) : super(key: key);
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
// late DashboardVM dashboardVM;
@override
void initState() {
super.initState();
// dashboardVM = Provider.of<DashboardVM>(context, listen: false);
fetchUsername();
scheduleMicrotask(() {
context.read<AppointmentsVM>().populateAppointmentsFilterList();
context.read<ProvidersVM>().populateProvidersFilterList();
context.read<AdVM>().populateAdsFilterList();
_onRefresh();
});
}
Future<void> _onRefresh() async {
AdVM adVm = Provider.of<AdVM>(context, listen: false);
AppointmentsVM appointmentsVM = Provider.of<AppointmentsVM>(context, listen: false);
if (appointmentsVM.myAppointments.isEmpty) {
await appointmentsVM.getMyAppointments();
}
if (adVm.myAds.isEmpty) {
await adVm.getMyAds();
}
if (adVm.exploreAds.isEmpty) {
await adVm.getExploreAds();
}
}
fetchUsername() async {}
List<Widget> fragments = [
const ProvidersFragment(),
const AppointmentsFragment(),
const HomeFragment(),
AdsFragment(),
const SettingsFragment(),
];
String getPageTitle(int index) {
if (index == 0) {
return "Providers";
}
if (index == 1) {
return "Appointments";
}
if (index == 2) {
return "";
}
if (index == 3) {
return "Ads";
}
if (index == 4) {
return "";
}
return "";
}
@override
Widget build(BuildContext context) {
bool isHomePage = context.watch<DashboardVM>().selectedNavbarBarIndex == 2;
return Scaffold(
appBar: CustomAppBar(
backgroundColor: null,
leadingWidth: 100,
title: getPageTitle(context.watch<DashboardVM>().selectedNavbarBarIndex),
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: true,
isDrawerEnabled: isHomePage ? true : false,
actions: [(isHomePage ? MyAssets.notificationsBellIcon : MyAssets.searchIcon).buildSvg().paddingOnly(right: 21)],
),
drawer: CustomDrawer(dashboardVM: context.watch<DashboardVM>()),
bottomNavigationBar: CustomBottomNavbar(),
body: fragments[context.watch<DashboardVM>().selectedNavbarBarIndex],
);
}
}

@ -1,79 +0,0 @@
import 'dart:async';
import 'package:car_customer_app/views/dashboard/fragments/appointments_fragment.dart';
import 'package:car_customer_app/views/dashboard/fragments/home_fragment.dart';
import 'package:car_customer_app/views/dashboard/widgets/bottom_nav_bar.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/views/common_fragments/ads_fragment.dart';
import 'package:mc_common_app/views/common_fragments/requests_fragment.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'fragments/branches_fragment.dart';
class DashboardView extends StatefulWidget {
final DashboardRouteEnum dashboardRouteEnum;
const DashboardView({Key? key, required this.dashboardRouteEnum}) : super(key: key);
@override
State<DashboardView> createState() => _DashboardViewState();
}
class _DashboardViewState extends State<DashboardView> {
late DashboardVmCustomer dashboardVM;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
dashboardVM = context.read<DashboardVmCustomer>();
scheduleMicrotask(() async => await dashboardVM.onRefresh(context, dashboardRouteEnum: widget.dashboardRouteEnum));
}
@override
Widget build(BuildContext context) {
List<Widget> fragments = [
const BranchesFragment(),
const AppointmentsFragment(),
const HomeFragment(),
const AdsFragment(),
const MyRequestsFragment(),
];
// return GestureDetector(
// behavior: HitTestBehavior.translucent,
// onTap: () {
// if (AppState().getIsViewOnly) {
// Utils.showToast("message");
// } else {
// print("========NN========");
// }
// },
// child: child,
// )
return PopScope(
canPop: false,
child: Scaffold(
key: _scaffoldKey,
bottomNavigationBar: CustomBottomNavbar(),
body: fragments[context.watch<DashboardVmCustomer>().selectedNavbarBarIndex],
),
);
// return PopScope(
// canPop: false,
// child: Scaffold(
// key: _scaffoldKey,
// bottomNavigationBar: CustomBottomNavbar(),
// body: fragments[context.watch<DashboardVmCustomer>().selectedNavbarBarIndex],
// ),
// );
}
}

@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class AdsFragment extends StatelessWidget {
AdsFragment({Key? key}) : super(key: key);
Future<void> onRefreshAds(BuildContext context) async {
AdVM adVM = context.read<AdVM>();
await adVM.getExploreAds();
await adVM.getMyAds();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Column(
children: [
16.height,
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column(
children: [
Row(
children: [
Expanded(
child: ShowFillButton(
isFilled: adVM.isExploreAdsTapped,
maxHeight: 55,
title: "Explore Ads",
txtColor: adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
onPressed: () {
print("ads: ${AppState().getUser.data!.accessToken}");
adVM.updateIsExploreAds(true);
},
),
),
12.width,
Expanded(
child: ShowFillButton(
isFilled: !adVM.isExploreAdsTapped,
txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
maxHeight: 55,
title: "My Ads",
onPressed: () {
adVM.updateIsExploreAds(false);
},
),
),
],
).horPaddingMain(),
if (adVM.isExploreAdsTapped && adVM.exploreAds.isNotEmpty) ...[
16.height,
FiltersList(filterList: adVM.exploreAdsFilterOptions, onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(index: index), needLeftPadding: false)
.paddingOnly(left: 21),
],
if (!adVM.isExploreAdsTapped && adVM.myAds.isNotEmpty) ...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnMyAds(index: index, selectedFilterId: selectedFilterId),
needLeftPadding: false)
.paddingOnly(left: 21),
],
],
);
},
),
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () => onRefreshAds(context),
child: Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return BuildAdsList(
isAdsFragment: true,
shouldShowAdStatus: !adVM.isExploreAdsTapped,
adsList: adVM.isExploreAdsTapped && adVM.exploreAdsFilteredList.isNotEmpty
? adVM.exploreAdsFilteredList
: !adVM.isExploreAdsTapped && adVM.myAdsFilteredList.isNotEmpty
? adVM.myAdsFilteredList
: [],
);
},
),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<AdVM>().getVehicleTypes();
navigateWithName(context, AppRoutes.createAdView);
},
backgroundColor: MyColors.darkPrimaryColor,
child: Icon(
Icons.add,
color: MyColors.white,
),
),
);
}
}

@ -1,141 +1,56 @@
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/views/appointments/widgets/common_appointment_slider_widget.dart';
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/filters_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class AppointmentsFragment extends StatelessWidget {
const AppointmentsFragment({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.appointments.tr(),
isRemoveBackButton: true,
actions: [
Padding(
padding: EdgeInsets.only(top: appointmentsVM.appointmentFiltersCounter > 0 ? 20 : 0, right: 21),
child: Badge(
isLabelVisible: appointmentsVM.appointmentFiltersCounter > 0,
largeSize: 15,
smallSize: 20,
backgroundColor: MyColors.darkPrimaryColor,
label: Text('${appointmentsVM.appointmentFiltersCounter}'),
child: MyAssets.searchIcon.buildSvg(),
),
).onPress(() {
navigateWithName(context, AppRoutes.appoinmentSearchFilterPage);
})
return Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnAppointmentsVM(index: index),
),
16.height,
Expanded(
child: appointmentsVM.myAppointments.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Appointments to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
],
)
: ListView.builder(
shrinkWrap: true,
itemCount: appointmentsVM.myAppointments.length,
itemBuilder: (BuildContext context, int index) {
return BuildAppointmentContainerForCustomer(
onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentsVM.myAppointments[index]),
appointmentListModel: appointmentsVM.myAppointments[index],
);
},
),
),
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
16.height,
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum());
},
),
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () async {
int index = appointmentsVM.appointmentsFilterOptions.indexWhere((element) => element.isSelected);
if (index != -1) {
AppointmentStatusEnum appointmentStatusEnum = appointmentsVM.appointmentsFilterOptions[index].id.toAppointmentStatusEnum();
appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: appointmentStatusEnum);
}
},
child: appointmentsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: appointmentsVM.myFilteredAppointmentsForCustomers.isEmpty
? AppState().getIsViewOnly
? LocaleKeys.loginToViewAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
LocaleKeys.noAppointmentstoShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor),
if (appointmentsVM.appointmentFiltersCounter > 0) ...[
8.height,
InkWell(
onTap: () async {
appointmentsVM.clearAppointmentFilters();
await appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
},
child: LocaleKeys.clearFilters.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.darkPrimaryColor,
),
),
],
],
)
: ListView.separated(
separatorBuilder: (context, index) => 12.height,
shrinkWrap: true,
itemCount: appointmentsVM.myFilteredAppointmentsForCustomers.length,
itemBuilder: (BuildContext context, int index) {
return AppointmentFragmentTileWidget(
onTapped: () {
AppointmentListModel appointmentModel = appointmentsVM.myFilteredAppointmentsForCustomers[index];
appointmentModel.appointmentServicesList!.forEach((service) {
double totalServicePrice = 0.0;
service.serviceItems!.forEach((item) {
totalServicePrice = totalServicePrice + (double.parse("${item.price ?? 0.0}"));
});
service.currentTotalServicePrice = totalServicePrice;
});
navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentModel);
},
appointmentListModel: appointmentsVM.myFilteredAppointmentsForCustomers[index],
).margin(left: 21, right: 21).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
});
},
),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
context.read<DashboardVmCustomer>().onNavbarTapped(0);
},
backgroundColor: MyColors.darkPrimaryColor,
child: Icon(
Icons.add,
color: MyColors.white,
),
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
);
},
);
},
),
);
}
}

@ -1,108 +0,0 @@
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/branch_details_card.dart';
import 'package:mc_common_app/widgets/common_widgets/filters_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class BranchesFragment extends StatelessWidget {
const BranchesFragment({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.branches.tr(),
isRemoveBackButton: true,
actions: [
Padding(
padding: EdgeInsets.only(top: appointmentsVM.branchFiltersCounter > 0 ? 20 : 0, right: 21),
child: Badge(
largeSize: 15,
smallSize: 20,
isLabelVisible: appointmentsVM.branchFiltersCounter > 0,
backgroundColor: MyColors.darkPrimaryColor,
label: Text('${appointmentsVM.branchFiltersCounter}'),
child: MyAssets.searchIcon.buildSvg(),
),
).onPress(() {
navigateWithName(context, AppRoutes.branchSearchFilterPage);
}),
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
if (appointmentsVM.branchesCategoriesFilterOptions.isNotEmpty) ...[
16.height,
FiltersList(
filterList: appointmentsVM.branchesCategoriesFilterOptions,
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnBranches(index: index),
),
],
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () async {
context.read<AppointmentsVM>().getAllNearBranches(isNeedToRebuild: true, isFromRefresh: true);
},
child: Container(
width: double.infinity,
child: appointmentsVM.state == ViewState.busy
? const Center(
child: CircularProgressIndicator(),
)
: appointmentsVM.nearbyBranches.isEmpty
? Center(
child: LocaleKeys.no_branch.tr().toText(
fontSize: 16,
color: MyColors.lightTextColor,
),
)
: ListView.separated(
itemCount: appointmentsVM.nearbyBranches.length,
itemBuilder: (context, index) {
BranchDetailModel branchDetailModel = appointmentsVM.nearbyBranches[index];
return BranchDetailCard(
onCardTapped: () => navigateWithName(context, AppRoutes.branchDetailView, arguments: branchDetailModel),
providerImageUrl: branchDetailModel.branchProfileImage ?? "",
title: branchDetailModel.branchName ?? "",
providerLocation: branchDetailModel.distanceKm.toString() + " KM",
providerName: branchDetailModel.serviceProviderName ?? "",
providerRatings: branchDetailModel.branchRateAvg ?? 0.0,
services: branchDetailModel.branchServices,
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
});
},
separatorBuilder: (context, index) => 12.height,
padding: const EdgeInsets.all(12),
),
).paddingOnly(left: 10, right: 10),
),
),
],
),
),
);
},
);
}
}

@ -1,18 +1,13 @@
import 'package:car_customer_app/views/dashboard/widgets/drawer_widget.dart';
import 'package:car_customer_app/views/dashboard/widgets/my_services_categories_widget.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/views/advertisement/components/ads_list_widget.dart';
import 'package:mc_common_app/views/appointments/widgets/common_appointment_slider_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart';
import 'package:mc_common_app/widgets/common_widgets/my_service_provider.dart';
import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
@ -22,137 +17,37 @@ class HomeFragment extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: CustomDrawer(dashboardVM: context.watch<DashboardVmCustomer>()),
appBar: CustomAppBar(
isDrawerEnabled: true,
leadingWidth: 100,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsMore),
actions: [
// IconButton(
// onPressed: () {},
// icon: const b.Badge(
// badgeContent: Text(
// '3',
// style: TextStyle(
// fontSize: 10,
// color: Colors.white,
// ),
// ),
// badgeStyle: b.BadgeStyle(
// badgeColor: MyColors.primaryColor,
// padding: EdgeInsets.all(5),
// ),
// child: Icon(Icons.notifications_active),
// ),
// ),
// 10.width,
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: RefreshIndicator(
onRefresh: () async => await context.read<DashboardVmCustomer>().onRefresh(context),
child: ListView(
return SizedBox(
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
16.height,
ViewAllWidget(
title: LocaleKeys.upcoming_appointment.tr().toUpperCase(),
subTitle: LocaleKeys.view_all.tr(),
title: "Upcoming Appointment".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVmCustomer>().onNavbarTapped(1);
context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
context.read<DashboardVM>().onNavbarTapped(1);
context.read<AppointmentsVM>().applyFilterOnAppointmentsVM(index: 0);
},
).horPaddingMain().toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
CommonAppointmentSliderWidget()
.toWhiteContainer(
width: double.infinity,
backgroundColor: Colors.transparent,
)
.margin(left: 21, right: 21)
.toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
// SERVICES SECTION
14.height,
Consumer(
builder: (BuildContext context, AppointmentsVM appointmentVM, Widget? child) {
if (appointmentVM.state == ViewState.busy) {
return Center(child: CircularProgressIndicator());
}
if (appointmentVM.branchesCategoriesFilterOptions.isNotEmpty) {
return Column(
children: [
ViewAllWidget(
title: LocaleKeys.services.tr().toUpperCase(),
subTitle: '',
onSubtitleTapped: () {},
).horPaddingMain().toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
MyServicesCategoriesWidget(homeCategories: appointmentVM.branchesCategoriesFilterOptions).horPaddingMain()
],
);
}
return SizedBox();
},
),
// NEARBY BRANCHES SECTION
// 7.height,
// Consumer(
// builder: (BuildContext context, AppointmentsVM appointmentVM, Widget? child) {
// if (appointmentVM.state == ViewState.busy) {
// return Center(child: CircularProgressIndicator());
// }
//
// if (appointmentVM.myRecentBranches.isNotEmpty) {
// return Column(
// children: [
// ViewAllWidget(
// title: LocaleKeys.myRecentBranches.tr().toUpperCase(),
// subTitle: '',
// onSubtitleTapped: () {
// // context.read<DashboardVmCustomer>().onNavbarTapped(0);
// // context.read<AppointmentsVM>().applyFilterOnBranches(index: 0);
// },
// ).horPaddingMain(),
// MyRecentBranchesWidget(nearbyBranches: appointmentVM.myRecentBranches).horPaddingMain(),
// ],
// );
// }
// if (appointmentVM.nearbyBranches.isNotEmpty) {
// return Column(
// children: [
// ViewAllWidget(
// title: LocaleKeys.myNearbyBranches.tr().toUpperCase(),
// subTitle: LocaleKeys.view_all.tr(),
// onSubtitleTapped: () {
// context.read<DashboardVmCustomer>().onNavbarTapped(0);
// context.read<AppointmentsVM>().applyFilterOnBranches(index: 0);
// },
// ).horPaddingMain(),
// MyRecentBranchesWidget(nearbyBranches: appointmentVM.nearbyBranches).horPaddingMain(),
// ],
// );
// }
//
// return SizedBox();
// },
// ),
// ADS SECTION
).horPaddingMain(),
CustomerAppointmentSliderWidget(myUpComingAppointments: context.watch<AppointmentsVM>().myAppointments),
7.height,
ViewAllWidget(
title: "My Recent Service Providers".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
print("value: ${AppState().getUser.data!.accessToken}");
context.read<DashboardVM>().onNavbarTapped(0);
context.read<ProvidersVM>().applyFilterOnProviders(index: 0);
}).horPaddingMain(),
const ServiceProviderWidget().horPaddingMain(),
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.state == ViewState.busy) {
return Center(child: CircularProgressIndicator());
}
return Column(
children: [
if (adVM.myActiveAdsForHome.isNotEmpty) ...[
@ -160,23 +55,18 @@ class HomeFragment extends StatelessWidget {
children: [
15.height,
ViewAllWidget(
title: LocaleKeys.my_active_Ads.tr().toUpperCase(),
subTitle: LocaleKeys.view_all.tr(),
title: "My Active Ads".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<DashboardVM>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(false);
}).horPaddingMain().toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
AdsListWidget(
}).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: true,
isAdsFragment: false,
adsList: adVM.myActiveAdsForHome,
scrollPhysics: NeverScrollableScrollPhysics(),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
),
],
)
],
@ -185,20 +75,19 @@ class HomeFragment extends StatelessWidget {
children: [
15.height,
ViewAllWidget(
title: LocaleKeys.myRecommendedAds.tr().toUpperCase(),
subTitle: LocaleKeys.view_all.tr(),
title: "My Recommended Ads".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<DashboardVM>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(true);
context.read<AdVM>().applyFilterOnExploreAds(vehicleBrandId: 0);
context.read<AdVM>().applyFilterOnExploreAds(index: 0);
},
).horPaddingMain(),
AdsListWidget(
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds,
isAdsFragment: false,
scrollPhysics: NeverScrollableScrollPhysics(),
hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
),
],
)

@ -1,60 +1,60 @@
// import 'package:car_customer_app/view_models/appointments_view_model.dart';
// import 'package:flutter/material.dart';
// import 'package:mc_common_app/classes/consts.dart';
// import 'package:mc_common_app/config/routes.dart';
// import 'package:mc_common_app/extensions/int_extensions.dart';
// import 'package:mc_common_app/theme/colors.dart';
// import 'package:mc_common_app/utils/navigator.dart';
// import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
// import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
// import 'package:provider/provider.dart';
//
// class ProvidersFragment extends StatelessWidget {
// const ProvidersFragment({Key? key}) : super(key: key);
//
// @override
// Widget build(BuildContext context) {
// return Container(
// color: MyColors.backgroundColor,
// width: double.infinity,
// height: double.infinity,
// child: Consumer(
// builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
// return Column(
// children: [
// 16.height,
// FiltersList(
// filterList: appointmentsVM.providersFilterOptions,
// onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnProviders(index: index),
// ),
// 16.height,
// Expanded(
// child: Container(
// child: ListView.builder(
// shrinkWrap: true,
// itemCount: 30,
// itemBuilder: (BuildContext context, int index) {
// return ProviderDetailsCard(
// onCardTapped: () {
// if (context.read<AppointmentsVM>().branchCategories.isEmpty) {
// context.read<AppointmentsVM>().getBranchCategories();
// }
// navigateWithName(context, AppRoutes.bookAppointmenServicesView);
// },
// providerImageUrl: MyAssets.bnCar,
// title: "",
// providerLocation: " 3km",
// providerName: "Al Ahmed Maintenance",
// providerRatings: "4.9",
// );
// },
// ),
// ),
// ),
// ],
// );
// },
// ),
// );
// }
// }
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
import 'package:provider/provider.dart';
class ProvidersFragment extends StatelessWidget {
const ProvidersFragment({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, ProvidersVM providersVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: providersVM.providersFilterOptions,
onFilterTapped: (index, selectedFilterId) => providersVM.applyFilterOnProviders(index: index),
),
16.height,
Expanded(
child: Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return ProviderDetailsCard(
onCardTapped: () {
if (context.read<AppointmentsVM>().providerCategories.isEmpty) {
context.read<AppointmentsVM>().getProviderCategories();
}
navigateWithName(context, AppRoutes.bookAppointmenServicesView);
},
providerImageUrl: MyAssets.bnCar,
providerLocation: " 3km",
providerName: "Al Ahmed Maintenance",
providerRatings: "4.9",
);
},
),
),
),
],
);
},
),
);
}
}

@ -0,0 +1,10 @@
import 'package:flutter/material.dart';
class SettingsFragment extends StatelessWidget {
const SettingsFragment({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container();
}
}

@ -1,111 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class AdWidget extends StatelessWidget {
final int count;
const AdWidget({Key? key, required this.count}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: count,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: buildAdContainer(),
);
});
}
Widget buildAdContainer() {
return Row(
children: [
Image.asset(
"assets/images/bn_car.jpeg",
width: 80,
height: 80,
fit: BoxFit.cover,
),
12.width,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Toyota Crolla".toText(fontSize: 16, isBold: true),
Row(
children: [
"Model:".toText(
color: MyColors.lightTextColor,
),
2.width,
"2019".toText(),
],
),
Row(
children: [
"Mileage:".toText(
color: MyColors.lightTextColor,
),
2.width,
"73,000 km".toText(),
],
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Riyadh".toText(
color: MyColors.lightTextColor,
),
"9 Hours Ago".toText(
color: MyColors.lightTextColor,
),
],
),
],
),
8.height,
Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
),
const Icon(Icons.arrow_forward)
],
),
],
),
),
],
).toWhiteContainer(width: double.infinity, allPading: 12);
}
}

@ -1,90 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class AppointmentSliderWidget extends StatelessWidget {
const AppointmentSliderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Olaya Brach".toText(
color: MyColors.lightTextColor,
isBold: true,
),
"Abdullah Alhbas".toText(
isBold: true,
fontSize: 14,
),
Row(
children: [
"Appt. On:".toText(
color: MyColors.lightTextColor,
),
2.width,
"19-Mar-2023 11:48 AM".toText(),
],
),
],
),
),
"1+ Requests".toText(fontSize: 10).toContainer(
borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor,
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
),
],
),
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Column(
children: [
showServices("Maintenance"),
2.height,
showServices("Accessories and Modification"),
],
),
),
const Icon(
Icons.arrow_forward,
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 0);
}
Widget showServices(String title) {
return Row(
children: [
const Icon(
Icons.ac_unit,
color: MyColors.primaryColor,
size: 18,
),
8.width,
title.toText(
fontSize: 14,
isBold: true,
),
],
);
}
}

@ -1,6 +1,4 @@
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -15,13 +13,13 @@ class CustomBottomNavbar extends StatelessWidget {
@override
Widget build(BuildContext context) {
DashboardVmCustomer dashboardVM = context.watch<DashboardVmCustomer>();
DashboardVM dashboardVM = context.watch<DashboardVM>();
return BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.branchesIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.branchesIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.branches.tr(),
icon: SvgPicture.asset(MyAssets.providersIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.providersIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.providers.tr(),
),
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.appointmentsIcon).paddingAll(5),
@ -34,7 +32,7 @@ class CustomBottomNavbar extends StatelessWidget {
color: MyColors.lightIconColor,
).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.homeIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.explore.tr(),
label: LocaleKeys.home.tr(),
),
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.announcementIcon).paddingAll(5),
@ -42,9 +40,9 @@ class CustomBottomNavbar extends StatelessWidget {
label: LocaleKeys.ads.tr(),
),
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.icRequests).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.icRequests, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.requests.tr(),
icon: SvgPicture.asset(MyAssets.settingsIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.settingsIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.settings.tr(),
),
],
currentIndex: dashboardVM.selectedNavbarBarIndex,

@ -1,5 +1,4 @@
import 'package:mc_common_app/models/user_models/image_response.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
@ -9,6 +8,7 @@ import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/user/image_response.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
@ -16,7 +16,7 @@ import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomDrawer extends StatefulWidget {
final DashboardVmCustomer dashboardVM;
final DashboardVM dashboardVM;
const CustomDrawer({Key? key, required this.dashboardVM}) : super(key: key);
@ -29,10 +29,10 @@ class _CustomDrawerState extends State<CustomDrawer> {
showDialog<ImageSource>(
context: context,
builder: (context) => AlertDialog(
content: Text(LocaleKeys.chooseImageSource.tr()),
content: const Text("Choose image source"),
actions: [
TextButton(child: Text(LocaleKeys.camera.tr()), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 0)),
TextButton(child: Text(LocaleKeys.gallery.tr()), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 1)),
TextButton(child: const Text("Camera"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 0)),
TextButton(child: const Text("Gallery"), onPressed: () => widget.dashboardVM.pickImageFromPhone(context, 1)),
],
),
);
@ -92,7 +92,7 @@ class _CustomDrawerState extends State<CustomDrawer> {
Utils.showLoading(context);
ImageResponse response = await widget.dashboardVM.updateUserImage("");
if (response.messageStatus == 1) {
Utils.showToast(LocaleKeys.imageIsDeleted.tr());
Utils.showToast("Image is Deleted");
setState(() {
AppState().getUser.data!.userInfo!.userImageUrl = response.data;
});
@ -118,7 +118,7 @@ class _CustomDrawerState extends State<CustomDrawer> {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocaleKeys.profile_reset_password_username.toText(
"userName".toText(
isBold: true,
fontSize: 20,
letterSpacing: -1.44,

@ -1,46 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class MyRecentBranchesWidget extends StatelessWidget {
final List<BranchDetailModel> nearbyBranches;
const MyRecentBranchesWidget({Key? key, required this.nearbyBranches}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 140,
child: ListView.builder(
itemCount: nearbyBranches.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
BranchDetailModel branchDetailModel = nearbyBranches[index];
return SizedBox(
width: 90,
child: Column(
children: [
branchDetailModel.branchProfileImage.buildNetworkImage(height: 73, width: 73, fit: BoxFit.cover).toCircle(borderRadius: 100),
9.height,
Flexible(
child: branchDetailModel.branchName!.toText(fontSize: 14, textAlign: TextAlign.center, letterSpacing: -0.84, height: 18 / 14),
),
],
),
).onPress(() => navigateWithName(
context,
AppRoutes.branchDetailView,
arguments: branchDetailModel,
));
},
),
);
}
}

@ -1,58 +0,0 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class MyServicesCategoriesWidget extends StatelessWidget {
final List<FilterListModel> homeCategories;
const MyServicesCategoriesWidget({Key? key, required this.homeCategories}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 140,
child: ListView.builder(
itemCount: homeCategories.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
FilterListModel category = homeCategories[index];
if (category.id == 0) {
return SizedBox();
}
return SizedBox(
width: 90,
child: Column(
children: [
category.iconUrl.buildNetworkImage(height: 73, width: 73, fit: BoxFit.cover).toCircle(borderRadius: 100),
9.height,
Flexible(
child: category.title.toText(
fontSize: 14,
textAlign: TextAlign.center,
maxLines: 2,
overflow: TextOverflow.ellipsis,
letterSpacing: -0.84,
height: 18 / 14,
),
),
],
),
).onPress(() {
final appointmentVM = context.read<AppointmentsVM>();
final dashboardCustomerVM = context.read<DashboardVmCustomer>();
context.read<DashboardVmCustomer>().onNavbarTapped(0);
dashboardCustomerVM.onNavbarTapped(0);
appointmentVM.applyFilterOnBranches(index: index);
});
},
),
);
}
}

@ -1,30 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
class ViewAllWidget extends StatelessWidget {
final String title;
final String subTitle;
const ViewAllWidget({Key? key, required this.title, required this.subTitle}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(bottom: 10),
child: Row(
children: [
Expanded(child: title.toText(isBold: true, fontSize: 18)),
subTitle.toText(
fontSize: 11,
isBold: true,
color: MyColors.primaryColor,
textDecoration: TextDecoration.underline,
)
],
),
);
}
}

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.17.0 <3.0.0"
sdk: ">=2.12.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@ -36,8 +36,7 @@ dependencies:
cupertino_icons: ^1.0.2
mc_common_app:
path: /Volumes/Data/Projects/Flutter/car_common_app
# path: /Users/aamir/StudioProjects/car_common_app
path: D:/Development/car_common_app
dev_dependencies:
flutter_test:
@ -75,13 +74,12 @@ flutter:
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Poppins
# fonts:
# - asset: assets/fonts/Poppins-Medium.ttf
# fonts:
# - family: Poppins
# fonts:
# - asset: assets/fonts/Poppins-Medium.ttf
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

Loading…
Cancel
Save