Compare commits

...

127 Commits

Author SHA1 Message Date
Faiz Hashmi bf32a2baf2 12 feb,2025 1 year ago
Faiz Hashmi cbffe18384 Check appointmnet filter for provider 1 year ago
Faiz Hashmi e1a97cc5a7 Check appointmnet filter for provider 1 year ago
Faiz Hashmi d581bbd3ab Merge branch 'aamir_dev' into faiz_development 1 year ago
Faiz Hashmi 933c15188f Check appointmnet filter for provider 1 year ago
Aamir Muhammad ba62c5782f fixes 1 year ago
Faiz Hashmi f459cb0610 Check appointmnet filter for provider 1 year ago
Faiz Hashmi a36a702117 Check appointmnet filter for provider 1 year ago
Faiz Hashmi e829e4b316 Merge branch 'aamir_dev' into faiz_development 1 year ago
Faiz Hashmi f5ed622dd8 Check appointmnet filter for provider 1 year ago
Aamir Muhammad a4be87fee0 Merge branch 'refs/heads/master' into aamir_dev
# Conflicts:
#	pubspec.yaml
1 year ago
Faiz Hashmi 4218973a53 Check appointmnet filter for provider 1 year ago
Faiz Hashmi ed4b565d62 Merge branch 'aamir_dev' into faiz_development
# Conflicts:
#	pubspec.yaml
1 year ago
Faiz Hashmi a71e17baed added lazy loading 1 year ago
Aamir b666876927 Merge branch 'faiz_development' into aamir_dev
# Conflicts:
#	pubspec.yaml
1 year ago
Faiz Hashmi 8a2f2fbdb6 Dropped the JIRA Count to 23 1 year ago
faizatflutter f9584c14cc Added Services Widget on HomeScreen 1 year ago
faizatflutter 0b63e00a14 294, 295 Fixed 1 year ago
Aamir d2a2fd1f8e ios 1 year ago
Aamir 957407a7ab Merge branch 'faiz_development' into aamir_dev 1 year ago
Faiz Hashmi 79a3737c03 Dropped the JIRA Count to 23 1 year ago
Faiz Hashmi 015f1483a5 Fixing JIRA Issues 1 year ago
Faiz Hashmi 062cd4db2f Fixing JIRA Issues 1 year ago
Faiz Hashmi 10f4803781 Fixing JIRA Issues 1 year ago
Aamir 275b64fb3b Merge branch 'master' into aamir_dev
# Conflicts:
#	pubspec.yaml
1 year ago
Faiz Hashmi fddfabe2b2 Upgraded to latest 1 year ago
Faiz Hashmi 28d96b3427 Merge remote-tracking branch 'origin/faiz_development' into faiz_development 1 year ago
Faiz Hashmi d82d2e37f1 Issues Fixed 1 year ago
FaizHashmiCS22 bbf4a549e5 Merge branch 'faiz_development' of http://34.17.52.180/Haroon6138/car_customer_app into faiz_development 1 year ago
FaizHashmiCS22 6af484ebc9 Appointmnent FLow testing 1 year ago
Aamir 3fe34a6c0f Merge branch 'faiz_development' into aamir_dev 1 year ago
Aamir 39d1b75fb2 Merge branch 'master' into aamir_dev 1 year ago
Faiz Hashmi b6e1a6e95c Issues Fixed 1 year ago
Faiz Hashmi e2a1ee7f58 Issues Fixed 1 year ago
Faiz Hashmi 4370f36ab2 Issues Fixed 1 year ago
Faiz Hashmi df25461575 Issues Fixed 1 year ago
Aamir b3966b83ce location 1 year ago
Faiz Hashmi 1d8a19472c Issues Fixed 1 year ago
Aamir 5654434fe2 Merge branch 'faiz_development' into aamir_dev 1 year ago
Aamir 45443cf8c3 IOS firebase fix 1 year ago
Faiz Hashmi 1a7705bdac Added Settings Modules 1 year ago
Faiz Hashmi e671565d04 Added Shipping Management 1 year ago
Faiz Hashmi 5f8422d68c fixed Things before QA 1 year ago
Faiz Hashmi 56673db6bc fixed Things before QA 1 year ago
Faiz Hashmi 0a8b1c2281 fixed Things before QA 1 year ago
Faiz Hashmi 77b8be6f20 Added Images support in ReqChat 1 year ago
Faiz Hashmi eec6420064 Merge branch 'aamir_dev' into faiz_development
# Conflicts:
#	lib/views/dashboard/dashboard_view.dart
1 year ago
Faiz Hashmi 5f3c12fcb0 Fixed the notes list 1 year ago
Faiz Hashmi b00624c406 Fixed the notes list 1 year ago
Aamir.Muhammad 9bfb4cb6a3 IOS firebase fix 1 year ago
Faiz Hashmi b6e75da894 RequestModule Completed 1 year ago
Faiz Hashmi ad8e0501f1 Refactoring 2 years ago
Aamir.Muhammad 55028d60c5 IOS firebase fix 2 years ago
Faiz Hashmi 44a7f0ab72 Added MainActivity 2 years ago
Faiz Hashmi 7f9d9dba71 Fixes 2 years ago
Faiz Hashmi fcc4f0ada0 Merge branch 'aamir_dev' into faiz_development
# Conflicts:
#	lib/main.dart
2 years ago
Faiz Hashmi 6235fd2a09 Fixes 2 years ago
Aamir.Muhammad f769b440e9 IOS firebase fix 2 years ago
Faiz Hashmi 2ac8099825 rEFACTORING 2 years ago
Faiz Hashmi bc71201dfd Merge branch 'aamir_dev' into faiz_development
# Conflicts:
#	lib/views/dashboard/dashboard_page.dart
#	lib/views/dashboard/fragments/ads_fragment.dart
#	lib/views/dashboard/fragments/home_fragment.dart
2 years ago
Faiz Hashmi 7c8211b85c Fixed Few Things 2 years ago
Faiz Hashmi 931d5acb6f Added Damage Pictures in ad_detail_view and extend edit ad 2 years ago
Faiz Hashmi 6f527b7e8f Added Damage Pictures in ad_detail_view and extend edit ad 2 years ago
Faiz Hashmi 91ea03c834 Updated both apps' structure 2 years ago
Aamir.Muhammad 2f9c07c6d8 changes 2 years ago
Faiz Hashmi 360048c3bf Added Firebase and Notifications 2 years ago
Faiz Hashmi b2a597bac7 few changes 2 years ago
Aamir.Muhammad eeec5aeb85 appointment slider fix 2 years ago
Faiz Hashmi d962424650 Merge branch 'aamir_dev' into faiz_development 2 years ago
Faiz Hashmi 87546dfec9 resolved merged error 2 years ago
Aamir.Muhammad 6ed7e2fa3d dashbord skip 2 years ago
Aamir.Muhammad ea9c8ae346 User Profile API's & Image 2 years ago
Aamir.Muhammad 82a5af9170 User Profile API's & Image 2 years ago
Faiz Hashmi fdf432f30d Bug Fixes 2 years ago
Faiz Hashmi 3ffbc85b46 Added Ads Filters 2 years ago
Faiz Hashmi 71030bf0fa Added Ads Filters and Appointments Filter 2 years ago
Faiz Hashmi 0b953bbe7d Added BranchFilters and their API integrations 2 years ago
Faiz Hashmi e2de476581 Added Branch FilterView 2 years ago
Faiz Hashmi 27fb9a2eab Merge branch 'mirza_development' 2 years ago
Faiz Hashmi 42eca4c26f debug changes 2 years ago
FaizHashmiCS22 67c7c485d9 Appointmnent FLow testing 2 years ago
Faiz Hashmi fb7dbe95cf test changes 2 years ago
FaizHashmiCS22 b5ce0a4b09 merge changes 2 years ago
Faiz Hashmi 4adc6bb5c2 chat implementation changes 1.0 2 years ago
Faiz Hashmi cd3699a510 chat implementation changes 1.0 2 years ago
devshafique a8a7a87108 request management 1.2 2 years ago
devshafique 08f6c55a10 Merge branch 'faiz_development' into mirza_development 2 years ago
devshafique e79ad123fd Merge branch 'faiz_development' of http://34.17.52.79/Haroon6138/car_customer_app into faiz_development 2 years ago
Faiz Hashmi 2b640c5624 chat module changes 2 years ago
Faiz Hashmi c7953189e3 refined models 2 years ago
Faiz Hashmi f510711768 added setting screens 2 years ago
Faiz Hashmi 8fbd859005 Special Service Appoinment 2 years ago
Faiz Hashmi 37ce6494dd Request Module added to common 2 years ago
devshafique 657d3bbd6a Merge branch 'master' into mirza_development
# Conflicts:
#	lib/config/customer_dependencies.dart
#	lib/config/customer_routes.dart
#	lib/main.dart
#	lib/views/dashboard/dashboard_page.dart
2 years ago
Faiz Hashmi 711be7f5da Request and Chat WIP 2 years ago
FaizHashmiCS22 39d2add60f Design Progress 3-20 2 years ago
devshafique 13100cafce Merge branch 'master' into mirza_development
# Conflicts:
#	lib/config/customer_dependencies.dart
#	lib/config/customer_routes.dart
#	lib/main.dart
#	lib/views/dashboard/dashboard_page.dart
2 years ago
Faiz Hashmi a47cae92f2 Merge remote-tracking branch 'origin/mirza_development' into faiz_development
# Conflicts:
#	lib/config/customer_dependencies.dart
#	lib/config/customer_routes.dart
#	lib/main.dart
#	lib/views/dashboard/dashboard_page.dart
2 years ago
Faiz Hashmi 54fd8736c7 Merge branch 'faiz_development' 2 years ago
Faiz Hashmi 9638deea3d Completed the Appointment Payments 2 years ago
Faiz Hashmi 937a1db5d9 Completed the Appointment Payments 2 years ago
Faiz Hashmi 2dd1952b20 Completed the Appointment Flow 2 years ago
Faiz Hashmi 120dc86309 aDDED cUSTOM cALENDER 2 years ago
devshafique 7163c6c1ba request management 1.0 2 years ago
Faiz Hashmi 5bc5ca8954 Started changing the Appointment Structure 2 years ago
Mirza Shafique 1c78b0e134 Merge pull request 'Ad Module Completion' (#3) from faiz_development into master
Reviewed-on: http://34.17.52.79/Haroon6138/car_customer_app/pulls/3
2 years ago
Faiz Hashmi fa35392611 Ad Module Page 2 years ago
Faiz Hashmi 045ccc6f70 Ad Details Page Checls 3 years ago
Faiz Hashmi ce9aab8db7 ad vehicle type 3 years ago
FaizHashmiCS22 e6c6c127f0 Schedules in appointments (In Progress) 3 years ago
FaizHashmiCS22 533952e14e Services merging in Schedules (In Progress) 3 years ago
FaizHashmiCS22 436befd111 Updated the MOdels 3 years ago
FaizHashmiCS22 83287f3b37 Merge branch 'faiz_development' of http://34.17.52.79/Haroon6138/car_customer_app into faiz_development
 Conflicts:
	lib/config/customer_routes.dart
	lib/repositories/provider_repo.dart
	lib/view_models/appointments_view_model.dart
	lib/view_models/providers_view_model.dart
	lib/views/dashboard/fragments/branches_fragment.dart
	lib/views/dashboard/fragments/providers_fragment.dart
	lib/views/provider/branch_detail_page.dart
	lib/views/provider/provider_profile_page.dart
	pubspec.yaml
3 years ago
FaizHashmiCS22 f0130d189a Merged the code 3 years ago
FaizHashmiCS22 ab723b4b97 Merged the code 3 years ago
FaizHashmiCS22 8bc13dff34 Updated the New Models 3 years ago
Mirza Shafique 9499c902a8 Merge pull request 'mirza_development' (#2) from mirza_development into master
Reviewed-on: http://34.17.52.79/Haroon6138/car_customer_app/pulls/2
3 years ago
mirza.shafique 694567653a Merge branch 'master' into mirza_development 3 years ago
mirza.shafique e39c697ed0 Provider Profile 1.2 3 years ago
FaizHashmiCS22 86c9419484 Merge branch 'master' of http://34.17.52.79/Haroon6138/car_customer_app into faiz_development
 Conflicts:
	lib/config/customer_dependencies.dart
3 years ago
Mirza Shafique 0c9d4dfa7d Merge pull request 'mirza_development' (#1) from mirza_development into master
Reviewed-on: http://34.17.52.79/Haroon6138/car_customer_app/pulls/1
3 years ago
mirza.shafique 274e407fa9 Branches list & provider profile 1.0 3 years ago
FaizHashmiCS22 3f0178e1cd Completed the new design for the Appointment Flow 3 years ago
mirza.shafique 4ccbf361fe Fetch Branches & services 3 years ago
FaizHashmiCS22 3390112aa3 test commit to GitTea 3 years ago
FaizHashmiCS22 50baaacb74 Design in Progress For Appointment Module. 3 years ago
mirza.shafique 237911d711 Common Setup 1 3 years ago

2
.gitignore vendored

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

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

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

@ -1,17 +1,45 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.car_customer_app"> package="com.cloud.solutions.mowater.ksa.customer">
<uses-permission android:name="android.permission.INTERNET" /> <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 <application
android:label="car_customer_app" android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher"
android:label="Customer"
android:requestLegacyExternalStorage="true">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true" android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
@ -19,8 +47,7 @@
to determine the Window background behind the Flutter UI. --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" android:resource="@style/NormalTheme" />
/>
<!-- Displays an Android View that continues showing the launch screen <!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual screen fades out. A splash screen is useful to avoid any visual
@ -28,13 +55,21 @@
Flutter's first frame. --> Flutter's first frame. -->
<meta-data <meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable" android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" android:resource="@drawable/launch_background" />
/>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter> </intent-filter>
</activity> </activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8" />
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

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

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

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

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

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

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

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

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

@ -1,12 +1,27 @@
import UIKit import UIKit
import Flutter import Flutter
import GoogleMaps
import Firebase
import flutter_local_notifications
@UIApplicationMain
@main
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
override func application( override func application(
_ application: UIApplication, _ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool { ) -> 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) GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions) return super.application(application, didFinishLaunchingWithOptions: launchOptions)
} }

@ -0,0 +1,30 @@
<?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,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@ -22,22 +24,33 @@
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSCameraUsageDescription</key>
<string>Used to access media images for car parts</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>Main</string>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
</array> </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> <key>UISupportedInterfaceOrientations~ipad</key>
<array> <array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>

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

@ -1,23 +1,37 @@
import 'package:car_customer_app/views/appointments/appointment_detail_view.dart'; import 'package:car_customer_app/views/branches/branch_detail_view.dart';
import 'package:car_customer_app/views/appointments/book_appointment_services_view.dart'; import 'package:car_customer_app/views/branches/favourite_list_view.dart';
import 'package:car_customer_app/views/appointments/pick_items_view.dart'; import 'package:car_customer_app/views/branches/provider_profile_view.dart';
import 'package:car_customer_app/views/dashboard/dashboard_page.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:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/config/routes.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/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart'; import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; import 'package:mc_common_app/views/branches/branches_filter_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart'; import 'package:mc_common_app/views/appointments/appointments_filter_view.dart';
class CustomerAppRoutes { class CustomerAppRoutes {
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {
AppRoutes.dashboard: (context) => DashboardPage(), AppRoutes.dashboard: (context) => DashboardView(dashboardRouteEnum: (ModalRoute.of(context)!.settings.arguments ?? DashboardRouteEnum.none) as DashboardRouteEnum),
AppRoutes.bookProviderAppView: (context) => BookProviderAppView(),
AppRoutes.appointmentDetailView: (context) => AppointmentDetailView(appointmentListModel: ModalRoute.of(context)!.settings.arguments as AppointmentListModel), 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.bookAppointmenServicesView: (context) => BookAppointmentServicesView(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(), 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(),
}; };
} }
//314187

@ -1,14 +1,27 @@
import 'dart:io';
import 'package:car_customer_app/config/customer_dependencies.dart'; import 'package:car_customer_app/config/customer_dependencies.dart';
import 'package:car_customer_app/config/customer_routes.dart'; import 'package:car_customer_app/config/customer_routes.dart';
import 'package:car_customer_app/view_models/appointments_view_model.dart'; import 'package:flutter/services.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart'; import 'package:mc_common_app/repositories/branch_repo.dart';
import 'package:car_customer_app/view_models/providers_view_model.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:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.dart'; import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/post_params_model.dart'; import 'package:mc_common_app/models/general_models/post_params_model.dart';
import 'package:mc_common_app/repositories/ads_repo.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/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart'; import 'package:mc_common_app/repositories/payments_repo.dart';
@ -20,30 +33,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/ad_view_model.dart';
import 'package:mc_common_app/view_models/base_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/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/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart'; import 'package:provider/single_child_widget.dart';
import 'package:sizer/sizer.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 { Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
CustomerDependencies.addDependencies();
await EasyLocalization.ensureInitialized(); await EasyLocalization.ensureInitialized();
CustomerAppRoutes.routes.addAll(AppRoutes.routes); 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();
}
runApp( CustomerDependencies.addDependencies();
injector.get<FirebaseMessagingService>().initializeNotifications().whenComplete(() {
injector.get<Location>().handleLocationPermission();
});
CustomerAppRoutes.routes.addAll(AppRoutes.routes);
initializeDateFormatting().then(
(_) => runApp(
MultiProvider( MultiProvider(
providers: <SingleChildWidget>[ providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(create: (_) => BaseVM()), ChangeNotifierProvider<BaseVM>(
ChangeNotifierProvider<DashboardVM>( create: (_) => BaseVM(),
create: (_) => DashboardVM( ),
ChangeNotifierProvider<DashboardVmCustomer>(
create: (_) => DashboardVmCustomer(
commonServices: injector.get<CommonAppServices>(), commonServices: injector.get<CommonAppServices>(),
userRepo: injector.get<UserRepo>(), userRepo: injector.get<UserRepo>(),
), ),
), ),
ChangeNotifierProvider<UserVM>( ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()), create: (_) => UserVM(
userRepo: injector.get<UserRepo>(),
commanServices: injector.get<CommonAppServices>(),
),
), ),
ChangeNotifierProvider<AdVM>( ChangeNotifierProvider<AdVM>(
create: (_) => AdVM( create: (_) => AdVM(
@ -52,24 +91,42 @@ Future<void> main() async {
adsRepo: injector.get<AdsRepo>(), adsRepo: injector.get<AdsRepo>(),
), ),
), ),
ChangeNotifierProvider<ProvidersVM>( ChangeNotifierProvider<AppointmentsVM>(
create: (_) => ProvidersVM( create: (_) => AppointmentsVM(
appointmentRepo: injector.get<AppointmentRepo>(),
commonServices: injector.get<CommonAppServices>(), commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(), commonRepo: injector.get<CommonRepo>(),
branchRepo: injector.get<BranchRepo>(),
), ),
), ),
ChangeNotifierProvider<AppointmentsVM>( ChangeNotifierProvider<PaymentVM>(
create: (_) => AppointmentsVM( create: (_) => PaymentVM(
paymentService: injector.get<PaymentService>(),
paymentRepo: injector.get<PaymentsRepo>(),
),
),
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>(), commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(), commonRepo: injector.get<CommonRepo>(),
), ),
), ),
ChangeNotifierProvider<PaymentVM>( ChangeNotifierProvider<SettingOptionsVM>(
create: (_) => PaymentVM(paymentService: injector.get<PaymentService>(), paymentRepo: injector.get<PaymentsRepo>()), create: (_) => SettingOptionsVM(
settingOptionsRepo: injector.get<SettingOptionsRepo>(),
),
), ),
], ],
child: const MyApp(), child: MyApp(),
).setupLocale(), ).setupLocale(),
),
); );
} }
@ -84,6 +141,10 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return Sizer( return Sizer(
builder: (context, orientation, deviceType) { builder: (context, orientation, deviceType) {
injector.get<AppState>().setAppType(AppType.customer); injector.get<AppState>().setAppType(AppType.customer);
@ -92,10 +153,10 @@ class MyApp extends StatelessWidget {
languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2, languageID: EasyLocalization.of(context)?.locale.languageCode == "ar" ? 1 : 2,
), ),
); );
return MaterialApp( return MaterialApp(
theme: AppTheme.getTheme( navigatorKey: navigatorKey,
isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar", theme: AppTheme.getTheme(isArabic: EasyLocalization.of(context)?.locale.languageCode == "ar"),
),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates, localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales, supportedLocales: context.supportedLocales,
@ -107,3 +168,10 @@ 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",

@ -1,102 +0,0 @@
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();
}
}

@ -1,55 +0,0 @@
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);
}
}

@ -1,35 +0,0 @@
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();
}
}

@ -1,128 +0,0 @@
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,
),
),
],
],
),
),
],
),
),
);
}
}

@ -1,325 +0,0 @@
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());
}
}

@ -1,168 +0,0 @@
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),
);
}
}

@ -1,199 +0,0 @@
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),
);
}
}

@ -0,0 +1,267 @@
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),
],
);
}
}

@ -0,0 +1,108 @@
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,
);
});
}
}

@ -0,0 +1,119 @@
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),
],
);
}
}

@ -0,0 +1,93 @@
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),
),
],
),
),
),
);
},
);
}
}

@ -0,0 +1,161 @@
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,
)
],
),
),
),
);
},
);
}
}

@ -1,104 +0,0 @@
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],
);
}
}

@ -0,0 +1,79 @@
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],
// ),
// );
}
}

@ -1,118 +0,0 @@
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,56 +1,141 @@
import 'package:car_customer_app/view_models/appointments_view_model.dart'; import 'package:mc_common_app/classes/app_state.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.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:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_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/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.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/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:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class AppointmentsFragment extends StatelessWidget { class AppointmentsFragment extends StatelessWidget {
const AppointmentsFragment({Key? key}) : super(key: key); const AppointmentsFragment({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Consumer(
color: MyColors.backgroundColor, 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);
})
],
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
body: SizedBox(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Consumer( child: Column(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
children: [ children: [
16.height, 16.height,
FiltersList( FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions, filterList: appointmentsVM.appointmentsFilterOptions,
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnAppointmentsVM(index: index), onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum());
},
), ),
16.height, 16.height,
Expanded( Expanded(
child: appointmentsVM.myAppointments.isEmpty child: RefreshIndicator(
? Column( 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, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
"No Appointments to show.".toText(fontSize: 16, color: MyColors.lightTextColor), 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.builder( : ListView.separated(
separatorBuilder: (context, index) => 12.height,
shrinkWrap: true, shrinkWrap: true,
itemCount: appointmentsVM.myAppointments.length, itemCount: appointmentsVM.myFilteredAppointmentsForCustomers.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return BuildAppointmentContainerForCustomer( return AppointmentFragmentTileWidget(
onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentsVM.myAppointments[index]), onTapped: () {
appointmentListModel: appointmentsVM.myAppointments[index], 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);
}),
);
},
); );
} }
} }

@ -0,0 +1,108 @@
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,13 +1,18 @@
import 'package:car_customer_app/view_models/appointments_view_model.dart'; import 'package:car_customer_app/views/dashboard/widgets/drawer_widget.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart'; import 'package:car_customer_app/views/dashboard/widgets/my_services_categories_widget.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:flutter/material.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/extensions/int_extensions.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/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart'; import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/my_service_provider.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/widgets/common_widgets/view_all_widget.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:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -17,37 +22,137 @@ class HomeFragment extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( 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, width: double.infinity,
height: double.infinity, height: double.infinity,
child: SingleChildScrollView( child: RefreshIndicator(
child: Padding( onRefresh: () async => await context.read<DashboardVmCustomer>().onRefresh(context),
padding: const EdgeInsets.only(top: 8), child: ListView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [ children: [
16.height, 16.height,
ViewAllWidget( ViewAllWidget(
title: "Upcoming Appointment".toUpperCase(), title: LocaleKeys.upcoming_appointment.tr().toUpperCase(),
subTitle: "View All", subTitle: LocaleKeys.view_all.tr(),
onSubtitleTapped: () { onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(1); context.read<DashboardVmCustomer>().onNavbarTapped(1);
context.read<AppointmentsVM>().applyFilterOnAppointmentsVM(index: 0); context.read<AppointmentsVM>().applyFilterOnAppointmentsVMForCustomers(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
}, },
).horPaddingMain(), ).horPaddingMain().toViewOnly(context, onTap: () {
CustomerAppointmentSliderWidget(myUpComingAppointments: context.watch<AppointmentsVM>().myAppointments), navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
7.height, }),
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( ViewAllWidget(
title: "My Recent Service Providers".toUpperCase(), title: LocaleKeys.services.tr().toUpperCase(),
subTitle: "View All", subTitle: '',
onSubtitleTapped: () { onSubtitleTapped: () {},
print("value: ${AppState().getUser.data!.accessToken}"); ).horPaddingMain().toViewOnly(context, onTap: () {
context.read<DashboardVM>().onNavbarTapped(0); navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
context.read<ProvidersVM>().applyFilterOnProviders(index: 0); }),
}).horPaddingMain(), MyServicesCategoriesWidget(homeCategories: appointmentVM.branchesCategoriesFilterOptions).horPaddingMain()
const ServiceProviderWidget().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
Consumer( Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) { builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.state == ViewState.busy) {
return Center(child: CircularProgressIndicator());
}
return Column( return Column(
children: [ children: [
if (adVM.myActiveAdsForHome.isNotEmpty) ...[ if (adVM.myActiveAdsForHome.isNotEmpty) ...[
@ -55,18 +160,23 @@ class HomeFragment extends StatelessWidget {
children: [ children: [
15.height, 15.height,
ViewAllWidget( ViewAllWidget(
title: "My Active Ads".toUpperCase(), title: LocaleKeys.my_active_Ads.tr().toUpperCase(),
subTitle: "View All", subTitle: LocaleKeys.view_all.tr(),
onSubtitleTapped: () { onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(3); context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(false); context.read<AdVM>().updateIsExploreAds(false);
}).horPaddingMain(), }).horPaddingMain().toViewOnly(context, onTap: () {
BuildAdsList( navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
AdsListWidget(
shouldShowAdStatus: true, shouldShowAdStatus: true,
isAdsFragment: false, isAdsFragment: false,
adsList: adVM.myActiveAdsForHome, adsList: adVM.myActiveAdsForHome,
scrollPhysics: NeverScrollableScrollPhysics(), scrollPhysics: NeverScrollableScrollPhysics(),
), hasMoreData: adVM.isExploreAdsTapped ? adVM.hasMoreDataForExploreAds : adVM.hasMoreDataForMyAds,
).toViewOnly(context, onTap: () {
navigateWithName(context, AppRoutes.loginWithPassword, arguments: false);
}),
], ],
) )
], ],
@ -75,19 +185,20 @@ class HomeFragment extends StatelessWidget {
children: [ children: [
15.height, 15.height,
ViewAllWidget( ViewAllWidget(
title: "My Recommended Ads".toUpperCase(), title: LocaleKeys.myRecommendedAds.tr().toUpperCase(),
subTitle: "View All", subTitle: LocaleKeys.view_all.tr(),
onSubtitleTapped: () { onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(3); context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(true); context.read<AdVM>().updateIsExploreAds(true);
context.read<AdVM>().applyFilterOnExploreAds(index: 0); context.read<AdVM>().applyFilterOnExploreAds(vehicleBrandId: 0);
}, },
).horPaddingMain(), ).horPaddingMain(),
BuildAdsList( AdsListWidget(
shouldShowAdStatus: false, shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds, adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds,
isAdsFragment: false, isAdsFragment: false,
scrollPhysics: NeverScrollableScrollPhysics(), 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: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:flutter/material.dart'; // import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/classes/consts.dart'; // import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/config/routes.dart'; // import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; // import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/theme/colors.dart'; // import 'package:mc_common_app/utils/navigator.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/categories_list.dart'; // import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart'; // import 'package:provider/provider.dart';
import 'package:provider/provider.dart'; //
// class ProvidersFragment extends StatelessWidget {
class ProvidersFragment extends StatelessWidget { // const ProvidersFragment({Key? key}) : super(key: key);
const ProvidersFragment({Key? key}) : super(key: key); //
// @override
@override // Widget build(BuildContext context) {
Widget build(BuildContext context) { // return Container(
return Container( // color: MyColors.backgroundColor,
color: MyColors.backgroundColor, // width: double.infinity,
width: double.infinity, // height: double.infinity,
height: double.infinity, // child: Consumer(
child: Consumer( // builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
builder: (BuildContext context, ProvidersVM providersVM, Widget? child) { // return Column(
return Column( // children: [
children: [ // 16.height,
16.height, // FiltersList(
FiltersList( // filterList: appointmentsVM.providersFilterOptions,
filterList: providersVM.providersFilterOptions, // onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnProviders(index: index),
onFilterTapped: (index, selectedFilterId) => providersVM.applyFilterOnProviders(index: index), // ),
), // 16.height,
16.height, // Expanded(
Expanded( // child: Container(
child: Container( // child: ListView.builder(
child: ListView.builder( // shrinkWrap: true,
shrinkWrap: true, // itemCount: 30,
itemCount: 30, // itemBuilder: (BuildContext context, int index) {
itemBuilder: (BuildContext context, int index) { // return ProviderDetailsCard(
return ProviderDetailsCard( // onCardTapped: () {
onCardTapped: () { // if (context.read<AppointmentsVM>().branchCategories.isEmpty) {
if (context.read<AppointmentsVM>().providerCategories.isEmpty) { // context.read<AppointmentsVM>().getBranchCategories();
context.read<AppointmentsVM>().getProviderCategories(); // }
} // navigateWithName(context, AppRoutes.bookAppointmenServicesView);
navigateWithName(context, AppRoutes.bookAppointmenServicesView); // },
}, // providerImageUrl: MyAssets.bnCar,
providerImageUrl: MyAssets.bnCar, // title: "",
providerLocation: " 3km", // providerLocation: " 3km",
providerName: "Al Ahmed Maintenance", // providerName: "Al Ahmed Maintenance",
providerRatings: "4.9", // providerRatings: "4.9",
); // );
}, // },
), // ),
), // ),
), // ),
], // ],
); // );
}, // },
), // ),
); // );
} // }
} // }

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

@ -0,0 +1,111 @@
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);
}
}

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

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

@ -0,0 +1,46 @@
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,
));
},
),
);
}
}

@ -0,0 +1,58 @@
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);
});
},
),
);
}
}

@ -0,0 +1,30 @@
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 version: 1.0.0+1
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work. # Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions # To automatically upgrade your package dependencies to the latest versions
@ -36,7 +36,8 @@ dependencies:
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
mc_common_app: mc_common_app:
path: D:/Development/car_common_app path: /Volumes/Data/Projects/Flutter/car_common_app
# path: /Users/aamir/StudioProjects/car_common_app
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -77,9 +78,10 @@ flutter:
# "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 # list giving the asset and other descriptors for the font. For
# example: # example:
# fonts: # fonts:
# - family: Poppins # - family: Poppins
# fonts: # fonts:
# - asset: assets/fonts/Poppins-Medium.ttf # - asset: assets/fonts/Poppins-Medium.ttf
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages

Loading…
Cancel
Save