Compare commits

...

42 Commits

Author SHA1 Message Date
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 2 years ago
Faiz Hashmi ce9aab8db7 ad vehicle type 2 years ago
FaizHashmiCS22 e6c6c127f0 Schedules in appointments (In Progress) 2 years ago
FaizHashmiCS22 533952e14e Services merging in Schedules (In Progress) 2 years ago
FaizHashmiCS22 436befd111 Updated the MOdels 2 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
2 years ago
FaizHashmiCS22 f0130d189a Merged the code 2 years ago
FaizHashmiCS22 ab723b4b97 Merged the code 2 years ago
FaizHashmiCS22 8bc13dff34 Updated the New Models 2 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
2 years ago
mirza.shafique 694567653a Merge branch 'master' into mirza_development 2 years ago
mirza.shafique e39c697ed0 Provider Profile 1.2 2 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
2 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
2 years ago
mirza.shafique 274e407fa9 Branches list & provider profile 1.0 2 years ago
FaizHashmiCS22 3f0178e1cd Completed the new design for the Appointment Flow 2 years ago
mirza.shafique 4ccbf361fe Fetch Branches & services 2 years ago
FaizHashmiCS22 3390112aa3 test commit to GitTea 2 years ago
FaizHashmiCS22 50baaacb74 Design in Progress For Appointment Module. 2 years ago
mirza.shafique 237911d711 Common Setup 1 2 years ago

@ -44,8 +44,8 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.car_customer_app"
minSdkVersion 20
targetSdkVersion 31
minSdkVersion 23
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.6.10'
ext.kotlin_version = '1.8.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
@ -24,6 +24,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="29.159" height="24.616" viewBox="0 0 29.159 24.616">
<g id="promotion" transform="translate(-2 -3.116)">
<path id="Path_4626" data-name="Path 4626" d="M26.785,3.408a.292.292,0,0,0-.417-.263L11.455,10.236h.021V20.442h-.021l14.913,7.092a.292.292,0,0,0,.417-.263ZM10.019,20.078V10.6H6.544A4.644,4.644,0,0,0,2,15.339a4.722,4.722,0,0,0,3.191,4.525l2.395,7.663a.292.292,0,0,0,.278.2h3.945a.292.292,0,0,0,.278-.378L9.814,20.078ZM7.728,16.068a.729.729,0,0,0,.729-.729v-.208a.729.729,0,0,0-.729-.729H6.686a.729.729,0,0,0-.729.729v.208a.729.729,0,0,0,.729.729Z" transform="translate(0 0)" fill="#767676" fill-rule="evenodd"/>
<path id="Path_4627" data-name="Path 4627" d="M22.29,17.715a5.1,5.1,0,0,0,0-9.224ZM20.832,8.052a5.1,5.1,0,1,0,0,10.1Z" transform="translate(5.953 2.236)" fill="#767676" fill-rule="evenodd"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 878 B

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.034" height="25.034" viewBox="0 0 25.034 25.034">
<g id="weekly-calendar-page-symbol" transform="translate(139)">
<path id="Path_4379" data-name="Path 4379" d="M22.53,0H2.5A2.511,2.511,0,0,0,0,2.5V22.53a2.512,2.512,0,0,0,2.5,2.5H22.53a2.512,2.512,0,0,0,2.5-2.5V2.5A2.511,2.511,0,0,0,22.53,0ZM6.756,22.031H2.921V18.62H6.756v3.411Zm0-4.555H2.921v-3.41H6.756v3.41ZM6.467,3.794A1.063,1.063,0,1,1,7.529,2.731,1.062,1.062,0,0,1,6.467,3.794Zm5.406,18.237H8.039V18.62h3.834Zm0-4.555H8.039v-3.41h3.834Zm0-4.552H8.039V9.514h3.834ZM11.455,2.731a1.062,1.062,0,1,1,1.062,1.062A1.062,1.062,0,0,1,11.455,2.731Zm5.54,14.745H13.159v-3.41H17v3.41Zm0-4.552H13.159V9.514H17v3.41ZM17.5,2.731a1.062,1.062,0,1,1,1.062,1.062A1.062,1.062,0,0,1,17.5,2.731Zm4.609,14.745H18.278v-3.41h3.835Zm0-4.552H18.278V9.514h3.835Z" transform="translate(-139)" fill="#767676"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 908 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.409" height="25.409" viewBox="0 0 25.409 25.409">
<path id="close_3_" data-name="close (3)" d="M10.63,9.119l7-7A1.164,1.164,0,1,0,15.98.477l-7,7-7-7A1.164,1.164,0,0,0,.341,2.123l7,7-7,7a1.164,1.164,0,1,0,1.646,1.646l7-7,7,7a1.164,1.164,0,1,0,1.646-1.646Zm0,0" transform="translate(-0.096 12.609) rotate(-45)" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 382 B

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="23.889" height="10.642" viewBox="0 0 23.889 10.642">
<g id="Group_8170" data-name="Group 8170" transform="translate(-61.5 -50.884)">
<path id="Path_66" data-name="Path 66" d="M4.5,18H19.3" transform="translate(58.5 42.025)" fill="none" stroke="#2e303a" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Path_67" data-name="Path 67" d="M4.5,9H25.389" transform="translate(58.5 43.384)" fill="none" stroke="#2e303a" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 577 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28.123" height="26.245" viewBox="0 0 28.123 26.245">
<path id="XMLID_219_" d="M28.984,15.637A2.077,2.077,0,0,1,27.025,17h-.716V27.309a.938.938,0,0,1-.937.937H19.748V21.685a4.687,4.687,0,0,0-9.374,0v6.562H4.749a.938.938,0,0,1-.937-.937V17H3.095a2.1,2.1,0,0,1-1.378-3.675L12.665,2.955a3.486,3.486,0,0,1,4.792,0L28.431,13.347A2.066,2.066,0,0,1,28.984,15.637Z" transform="translate(-0.999 -2.001)" fill="#273139"/>
</svg>

After

Width:  |  Height:  |  Size: 467 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8.852" height="8.852" viewBox="0 0 8.852 8.852">
<path id="clock_7_" data-name="clock (7)" d="M4.426,0A4.426,4.426,0,1,0,8.852,4.426,4.431,4.431,0,0,0,4.426,0Zm2.1,6.715a.368.368,0,0,1-.521,0L4.165,4.871a.367.367,0,0,1-.108-.261v-2.4a.369.369,0,1,1,.738,0V4.458L6.531,6.194A.368.368,0,0,1,6.531,6.715Zm0,0" fill="#a9a9a9"/>
</svg>

After

Width:  |  Height:  |  Size: 380 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="12.375" height="9" viewBox="0 0 12.375 9">
<path id="next_3_" data-name="next (3)" d="M13.21,8.1,9.273,4.165a.562.562,0,1,0-.8.8l2.977,2.977H1.563a.562.562,0,1,0,0,1.125h9.892L8.477,12.04a.562.562,0,1,0,.8.8L13.21,8.9a.563.563,0,0,0,0-.8Z" transform="translate(-1 -4)" fill="#06161c"/>
</svg>

After

Width:  |  Height:  |  Size: 342 B

@ -0,0 +1,6 @@
<svg id="bell_2_" data-name="bell (2)" xmlns="http://www.w3.org/2000/svg" width="20.255" height="22.097" viewBox="0 0 20.255 22.097">
<path id="Path_4605" data-name="Path 4605" d="M358.833,25.324a.921.921,0,0,1-.921-.921,9.606,9.606,0,0,0-2.831-6.836.921.921,0,0,1,1.3-1.3,11.433,11.433,0,0,1,3.371,8.138A.921.921,0,0,1,358.833,25.324Zm0,0" transform="translate(-339.499 -15.305)" fill="#28323a"/>
<path id="Path_4606" data-name="Path 4606" d="M.921,25.324A.921.921,0,0,1,0,24.4a11.434,11.434,0,0,1,3.371-8.138.921.921,0,0,1,1.3,1.3A9.6,9.6,0,0,0,1.841,24.4.921.921,0,0,1,.921,25.324Zm0,0" transform="translate(0 -15.305)" fill="#28323a"/>
<path id="Path_4607" data-name="Path 4607" d="M39.174,15.572a6.167,6.167,0,0,1-2.19-4.719V8.286A6.45,6.45,0,0,0,31.46,1.915V.921a.921.921,0,0,0-1.841,0v.994a6.449,6.449,0,0,0-5.524,6.371v2.567a6.174,6.174,0,0,1-2.2,4.726,1.611,1.611,0,0,0,1.048,2.835H38.135a1.611,1.611,0,0,0,1.039-2.842Zm0,0" transform="translate(-20.411)" fill="#28323a"/>
<path id="Path_4608" data-name="Path 4608" d="M159.672,450.762A3.458,3.458,0,0,0,163.054,448h-6.765A3.458,3.458,0,0,0,159.672,450.762Zm0,0" transform="translate(-149.544 -428.665)" fill="#28323a"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.783" height="30.979" viewBox="0 0 25.783 30.979">
<g id="automobile-with-wrench" transform="translate(-30.265)">
<path id="Path_4647" data-name="Path 4647" d="M106.524,16.93c2.071,0,6.941-2.493,6.941-8.465,0-.833-.02-1.638-.089-2.4a7.177,7.177,0,0,0-1.182-3.839C111.214.845,109.5,0,106.524,0s-4.69.844-5.669,2.227a7.175,7.175,0,0,0-1.183,3.84c-.069.76-.089,1.565-.089,2.4C99.583,14.437,104.452,16.93,106.524,16.93ZM108.789,3.1l-.506,1.277a5.736,5.736,0,0,0-3.52,0L104.258,3.1A7.109,7.109,0,0,1,108.789,3.1ZM100.615,7.17c.08.175.42.847.946.91.6.073,1.608-2.141,4.963-2.146s4.358,2.219,4.963,2.146c.526-.063.866-.735.946-.91.016.429.022.862.022,1.3a7.548,7.548,0,0,1-2.37,5.732,6.062,6.062,0,0,1-3.56,1.723,6.062,6.062,0,0,1-3.56-1.723,7.547,7.547,0,0,1-2.371-5.732C100.593,8.032,100.6,7.6,100.615,7.17Z" transform="translate(-63.367)" fill="#767676"/>
<path id="Path_4648" data-name="Path 4648" d="M56.042,197.513c-.354-2.2-1.084-5.041-2.547-6.05-1-.689-4.486-2.552-5.974-3.347L47.5,188.1a.486.486,0,0,0-.53.046,6.325,6.325,0,0,1-2.539,1.226.486.486,0,0,0-.349.3l-.921,2.429-.922-2.429a.486.486,0,0,0-.349-.3,6.324,6.324,0,0,1-2.539-1.226.487.487,0,0,0-.53-.046c-1.471.786-5,2.687-5.995,3.357-1.684,1.135-2.421,5.241-2.551,6.053a.488.488,0,0,0,.022.24c.036.1.593,1.544,3.379,2.7a1.384,1.384,0,0,1,.615-.442,1.374,1.374,0,0,1-.749-1.955,4.071,4.071,0,0,1,6.959-.316h5.316a4.079,4.079,0,0,1,3.38-1.808h0a4.079,4.079,0,0,1,3.575,2.112A1.374,1.374,0,0,1,52.025,200a1.382,1.382,0,0,1,.624.448c2.779-1.16,3.335-2.6,3.371-2.7A.49.49,0,0,0,56.042,197.513Z" transform="translate(0 -171.901)" fill="#767676"/>
<path id="Path_4649" data-name="Path 4649" d="M97.425,297.952h0l-2.561,0a4.839,4.839,0,0,1,0-2.244l2.561,0a.173.173,0,0,0,.151-.257,2.872,2.872,0,0,0-5.184.319H85.634a2.869,2.869,0,0,0-5.185-.31.173.173,0,0,0,.152.256h0l2.561,0a4.839,4.839,0,0,1,0,2.244l-2.561,0a.173.173,0,0,0-.151.256,2.873,2.873,0,0,0,2.517,1.489h0a2.871,2.871,0,0,0,2.663-1.808h6.753a2.876,2.876,0,0,0,2.665,1.808h0a2.874,2.874,0,0,0,2.517-1.5.173.173,0,0,0-.152-.256Z" transform="translate(-45.857 -268.725)" fill="#767676"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25.211" height="20.945" viewBox="0 0 25.211 20.945">
<path id="menu_6_" data-name="menu (6)" d="M-.551,81.687H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,83.429a1.617,1.617,0,0,1,1.45-1.742ZM21.76,83.193H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,72.957H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,74.7a1.617,1.617,0,0,1,1.45-1.742ZM21.76,74.462H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,90.418H21.76a1.772,1.772,0,0,1,0,3.484H-.551A1.617,1.617,0,0,1-2,92.16a1.617,1.617,0,0,1,1.45-1.742ZM21.76,91.923H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473ZM-.551,74.935H21.76a.24.24,0,0,0,0-.473H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236ZM21.76,83.193H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473Zm0,8.731H-.551a.219.219,0,0,0-.2.236.219.219,0,0,0,.2.236H21.76a.24.24,0,0,0,0-.473Z" transform="translate(2.001 -72.956)" fill="#767676" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

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

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@ -68,7 +68,6 @@
C74C73D850C4D4FC94940060 /* Pods-Runner.release.xcconfig */,
3643750A79F4A25346F39B6F /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
@ -140,6 +139,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9A2045E27F192C87BCD2FA50 /* [CP] Embed Pods Frameworks */,
4CC2E88FCFA89EAD7EEA637B /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -156,7 +156,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@ -200,10 +200,12 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
@ -212,8 +214,26 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
4CC2E88FCFA89EAD7EEA637B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -340,7 +360,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
@ -356,9 +376,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -414,7 +439,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -463,11 +488,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@ -480,9 +506,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -499,9 +530,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.carCustomerApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

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

@ -2,6 +2,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>NSCameraUsageDescription</key>
<string>Used to access media images for car parts</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
@ -28,18 +30,22 @@
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

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

@ -1,14 +1,31 @@
import 'package:car_customer_app/views/appointments/appointment_detail_view.dart';
import 'package:car_customer_app/views/appointments/book_appointment_services_view.dart';
import 'package:car_customer_app/views/appointments/pick_items_view.dart';
import 'package:mc_common_app/models/requests_models/offers_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.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/pick_items_view.dart';
import 'package:mc_common_app/views/appointments/review_appointment_view.dart';
import 'package:car_customer_app/views/dashboard/dashboard_page.dart';
import 'package:car_customer_app/views/provider/branch_detail_page.dart';
import 'package:car_customer_app/views/provider/provider_profile_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/views/advertisement/ads_detail_view.dart';
import 'package:mc_common_app/views/advertisement/create_ad_view.dart';
import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart';
import 'package:mc_common_app/views/advertisement/ads_filter_view.dart';
import 'package:mc_common_app/views/requests/create_request_page.dart';
import 'package:mc_common_app/views/requests/offer_list_page.dart';
import 'package:mc_common_app/views/setting_options/setting_options_faqs.dart';
import 'package:mc_common_app/views/setting_options/setting_options_invite_friends.dart';
import 'package:mc_common_app/views/setting_options/setting_options_language.dart';
import 'package:mc_common_app/views/chat/chat_view.dart';
class CustomerAppRoutes {
static final Map<String, WidgetBuilder> routes = {
@ -17,7 +34,24 @@ class CustomerAppRoutes {
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.adsFilterView: (context) => AdsFilterView(),
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(isProvider: ModalRoute.of(context)!.settings.arguments as bool),
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.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
AppRoutes.branchDetailPage: (context) => BranchDetailPage(branchDetailModel: ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
AppRoutes.providerProfilePage: (context) => ProviderProfilePage(providerId: ModalRoute.of(context)!.settings.arguments as int),
AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments),
AppRoutes.createRequestPage: (context) => CreateRequestPage(),
AppRoutes.chatView: (context) => ChatView(
chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments,
),
AppRoutes.settingOptionsFaqs: (context) => SettingOptionsFAQs(),
AppRoutes.settingOptionsLanguages: (context) => SettingOptionsLanguage(),
AppRoutes.settingOptionsInviteFriends: (context) => SettingOptionsInviteFriends(),
};
}

@ -1,14 +1,19 @@
import 'package:car_customer_app/config/customer_dependencies.dart';
import 'package:car_customer_app/config/customer_routes.dart';
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/repositories/provider_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/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:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.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/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart';
@ -25,52 +30,57 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:sizer/sizer.dart';
import 'package:intl/date_symbol_data_local.dart';
//test commit
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
CustomerDependencies.addDependencies();
await EasyLocalization.ensureInitialized();
CustomerAppRoutes.routes.addAll(AppRoutes.routes);
runApp(
MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(create: (_) => BaseVM()),
ChangeNotifierProvider<DashboardVM>(
create: (_) => DashboardVM(
commonServices: injector.get<CommonAppServices>(),
userRepo: injector.get<UserRepo>(),
),
),
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()),
),
ChangeNotifierProvider<AdVM>(
create: (_) => AdVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
adsRepo: injector.get<AdsRepo>(),
),
),
ChangeNotifierProvider<ProvidersVM>(
create: (_) => ProvidersVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(paymentService: injector.get<PaymentService>(), paymentRepo: injector.get<PaymentsRepo>()),
),
],
child: const MyApp(),
).setupLocale(),
);
initializeDateFormatting().then((_) => runApp(
MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(create: (_) => BaseVM()),
ChangeNotifierProvider<DashboardVmCustomer>(
create: (_) => DashboardVmCustomer(
commonServices: injector.get<CommonAppServices>(),
userRepo: injector.get<UserRepo>(),
),
),
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()),
),
ChangeNotifierProvider<AdVM>(
create: (_) => AdVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
adsRepo: injector.get<AdsRepo>(),
),
),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
scheduleRepo: injector.get<AppointmentRepo>(),
providerRepo: injector.get<ProviderRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(paymentService: injector.get<PaymentService>(), paymentRepo: injector.get<PaymentsRepo>()),
),
ChangeNotifierProvider<ChatVM>(create: (_) => ChatVM(chatRepo: injector.get<ChatRepo>())),
ChangeNotifierProvider<RequestsVM>(
create: (_) => RequestsVM(
requestRepo: injector.get<RequestRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
],
child: MyApp(),
).setupLocale(),
));
}
// todo terminal command to generate translation files

@ -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),
);
}
}

@ -1,21 +1,28 @@
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/my_requests_fragment.dart';
import 'package:mc_common_app/classes/app_state.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/utils/enums.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:car_customer_app/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/config/routes.dart';
import 'package:mc_common_app/models/general_models/widgets_models.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/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'fragments/branches_fragment.dart';
class DashboardPage extends StatefulWidget {
const DashboardPage({Key? key}) : super(key: key);
@ -31,42 +38,65 @@ class _DashboardPageState extends State<DashboardPage> {
void initState() {
super.initState();
// dashboardVM = Provider.of<DashboardVM>(context, listen: false);
fetchUsername();
scheduleMicrotask(() {
context.read<AppointmentsVM>().populateAppointmentsFilterList();
context.read<ProvidersVM>().populateProvidersFilterList();
context.read<AppointmentsVM>().populateBranchesFilterList();
context.read<RequestsVM>().populateRequestsFilterList();
context.read<AdVM>().populateAdsFilterList();
_onRefresh();
});
}
Future<void> _onRefresh() async {
AdVM adVm = Provider.of<AdVM>(context, listen: false);
AdVM adVM = Provider.of<AdVM>(context, listen: false);
AppointmentsVM appointmentsVM = Provider.of<AppointmentsVM>(context, listen: false);
RequestsVM requestsVM = Provider.of<RequestsVM>(context, listen: false);
ChatVM chatVM = Provider.of<ChatVM>(context, listen: false);
if (appointmentsVM.myAppointments.isEmpty) {
await appointmentsVM.getMyAppointments();
}
if (adVm.myAds.isEmpty) {
await adVm.getMyAds();
if (appointmentsVM.nearbyBranches.isEmpty) {
await appointmentsVM.getAllNearBranches();
}
if (adVm.exploreAds.isEmpty) {
await adVm.getExploreAds();
if (adVM.myAds.isEmpty) {
await adVM.getMyAds();
}
if (adVM.exploreAds.isEmpty) {
await adVM.getExploreAds();
}
if (requestsVM.myRequests.isEmpty) {
await requestsVM.getRequests(appType: AppType.customer);
}
if (adVM.vehicleTypes.isEmpty) {
await adVM.getVehicleTypes();
}
}
fetchUsername() async {}
if (adVM.vehicleAdsDurations.isEmpty) {
await adVM.getVehicleAdsDuration();
}
await chatVM.buildHubConnection();
adVM.updateVehicleAdDurationId(
SelectionModel(
selectedId: adVM.vehicleAdsDurations.first.id ?? 0,
selectedOption: "${adVM.vehicleAdsDurations.first.days} Days",
itemPrice: adVM.vehicleAdsDurations.first.price!.toInt().toString(),
),
);
}
List<Widget> fragments = [
const ProvidersFragment(),
const BranchesFragment(),
const AppointmentsFragment(),
const HomeFragment(),
AdsFragment(),
const SettingsFragment(),
MyRequestsFragment(),
];
String getPageTitle(int index) {
if (index == 0) {
return "Providers";
return "Select Branch";
}
if (index == 1) {
return "Appointments";
@ -78,27 +108,56 @@ class _DashboardPageState extends State<DashboardPage> {
return "Ads";
}
if (index == 4) {
return "";
return "My Requests";
}
return "";
}
@override
Widget build(BuildContext context) {
bool isHomePage = context.watch<DashboardVM>().selectedNavbarBarIndex == 2;
DashboardVmCustomer dashboardVM = context.read<DashboardVmCustomer>();
bool isHomePage = dashboardVM.selectedNavbarBarIndex == 2;
return Scaffold(
appBar: CustomAppBar(
backgroundColor: null,
leadingWidth: 100,
title: getPageTitle(context.watch<DashboardVM>().selectedNavbarBarIndex),
title: getPageTitle(dashboardVM.selectedNavbarBarIndex),
profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: true,
isDrawerEnabled: isHomePage ? true : false,
actions: [(isHomePage ? MyAssets.notificationsBellIcon : MyAssets.searchIcon).buildSvg().paddingOnly(right: 21)],
onTap: () {
if (isHomePage) {
navigateWithName(context, AppRoutes.settingOptionsLanguages);
}
},
actions: [
(isHomePage
? Row(
children: [
"${AppState().currentAppType}".toText(color: MyColors.darkTextColor).onPress(() {
print("myId: ${AppState().getUser.data!.userInfo!.userId}");
// context.read<ChatVM>().buildHubConnection();
}),
10.width,
MyAssets.notificationsBellIcon.buildSvg().onPress(() {}),
15.width,
Icon(Icons.message, color: MyColors.darkTextColor).onPress(() {}),
],
)
: InkWell(
onTap: () async {
if (dashboardVM.selectedNavbarBarIndex == 3) {
await context.read<AdVM>().populateDataForAdFilter();
navigateWithName(context, AppRoutes.adsFilterView);
}
},
child: MyAssets.searchIcon.buildSvg(),
))
.paddingOnly(right: 21)
],
),
drawer: CustomDrawer(dashboardVM: context.watch<DashboardVM>()),
bottomNavigationBar: CustomBottomNavbar(),
body: fragments[context.watch<DashboardVM>().selectedNavbarBarIndex],
body: fragments[context.watch<DashboardVmCustomer>().selectedNavbarBarIndex],
);
}
}

@ -1,8 +1,12 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.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/advertisment_models/ad_details_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/view_models/ad_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart';
@ -20,6 +24,16 @@ class AdsFragment extends StatelessWidget {
await adVM.getMyAds();
}
List<AdDetailsModel> getAdsList(AdVM adVM) {
if (adVM.isExploreAdsTapped) {
return adVM.exploreAdsFilteredList;
}
if (adVM.myAdsFilteredList.isNotEmpty) {
return adVM.myAdsFilteredList;
}
return [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -62,18 +76,21 @@ class AdsFragment extends StatelessWidget {
),
],
).horPaddingMain(),
if (adVM.isExploreAdsTapped && adVM.exploreAds.isNotEmpty) ...[
if (adVM.isExploreAdsTapped) ...[
16.height,
FiltersList(filterList: adVM.exploreAdsFilterOptions, onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(index: index), needLeftPadding: false)
FiltersList(
filterList: adVM.exploreAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()),
needLeftPadding: false)
.paddingOnly(left: 21),
],
if (!adVM.isExploreAdsTapped && adVM.myAds.isNotEmpty) ...[
if (!adVM.isExploreAdsTapped) ...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnMyAds(index: index, selectedFilterId: selectedFilterId),
needLeftPadding: false)
.paddingOnly(left: 21),
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum()),
needLeftPadding: false,
).paddingOnly(left: 21),
],
],
);
@ -85,15 +102,7 @@ class AdsFragment extends StatelessWidget {
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
: [],
);
return BuildAdsList(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM));
},
),
),
@ -102,10 +111,8 @@ class AdsFragment extends StatelessWidget {
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<AdVM>().getVehicleTypes();
navigateWithName(context, AppRoutes.createAdView);
onPressed: () async {
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: injector.get<AppState>().currentAppType == AppType.provider);
},
backgroundColor: MyColors.darkPrimaryColor,
child: Icon(

@ -1,10 +1,14 @@
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package: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/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:provider/provider.dart';
@ -14,42 +18,72 @@ class AppointmentsFragment extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnAppointmentsVM(index: index),
),
16.height,
Expanded(
child: appointmentsVM.myAppointments.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Appointments to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
],
)
: ListView.builder(
shrinkWrap: true,
itemCount: appointmentsVM.myAppointments.length,
itemBuilder: (BuildContext context, int index) {
return BuildAppointmentContainerForCustomer(
onTapped: () => navigateWithName(context, AppRoutes.appointmentDetailView, arguments: appointmentsVM.myAppointments[index]),
appointmentListModel: appointmentsVM.myAppointments[index],
);
},
),
),
],
);
return Scaffold(
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(appointmentStatusEnum: selectedFilterId.toAppointmentStatusEnum());
}),
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () async {
appointmentsVM.getMyAppointments(isNeedToRebuild: true);
},
child: appointmentsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: appointmentsVM.myFilteredAppointments.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Appointments to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
],
)
: ListView.builder(
shrinkWrap: true,
itemCount: appointmentsVM.myFilteredAppointments.length,
itemBuilder: (BuildContext context, int index) {
return BuildAppointmentContainerForCustomer(
onTapped: () {
AppointmentListModel appointmentModel = appointmentsVM.myFilteredAppointments[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.myFilteredAppointments[index],
);
},
),
),
),
],
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
context.read<DashboardVmCustomer>().onNavbarTapped(0);
},
backgroundColor: MyColors.darkPrimaryColor,
child: Icon(
Icons.add,
color: MyColors.white,
),
),
);
}

@ -0,0 +1,78 @@
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/categories_list.dart';
import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart';
import 'package:provider/provider.dart';
class BranchesFragment extends StatelessWidget {
const BranchesFragment({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: appointmentsVM.providersFilterOptions,
onFilterTapped: (index, selectedFilterId) => appointmentsVM.applyFilterOnProviders(index: index),
),
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () async {
context.read<AppointmentsVM>().getAllNearBranches(isNeedToRebuild: true);
},
child: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height / 1.37,
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 ProviderDetailsCard(
onCardTapped: () {
navigateWithName(context, AppRoutes.branchDetailPage, arguments: branchDetailModel);
},
providerImageUrl: MyAssets.bnCar,
title: branchDetailModel.branchName ?? "",
providerLocation: branchDetailModel.distanceKm.toString() + " KM",
providerName: branchDetailModel.serviceProviderName ?? "",
providerRatings: "4.9",
services: branchDetailModel.branchServices,
);
},
separatorBuilder: (context, index) {
return 12.height;
},
padding: const EdgeInsets.all(12),
)),
),
),
],
);
},
),
);
}
}

@ -1,10 +1,10 @@
import 'package:car_customer_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:car_customer_app/view_models/providers_view_model.dart';
import 'package:car_customer_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:car_customer_app/views/dashboard/widgets/drawer_widget.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/customer_appointment_slider_widget.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/utils/enums.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/common_widgets/my_service_provider.dart';
@ -17,87 +17,91 @@ class HomeFragment extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
16.height,
ViewAllWidget(
title: "Upcoming Appointment".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(1);
context.read<AppointmentsVM>().applyFilterOnAppointmentsVM(index: 0);
},
).horPaddingMain(),
CustomerAppointmentSliderWidget(myUpComingAppointments: context.watch<AppointmentsVM>().myAppointments),
7.height,
ViewAllWidget(
title: "My Recent Service Providers".toUpperCase(),
return Scaffold(
drawer: CustomDrawer(dashboardVM: context.watch<DashboardVmCustomer>()),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 8),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
16.height,
ViewAllWidget(
title: "Upcoming Appointment".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
print("value: ${AppState().getUser.data!.accessToken}");
context.read<DashboardVM>().onNavbarTapped(0);
context.read<ProvidersVM>().applyFilterOnProviders(index: 0);
}).horPaddingMain(),
const ServiceProviderWidget().horPaddingMain(),
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column(
children: [
if (adVM.myActiveAdsForHome.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Active Ads".toUpperCase(),
context.read<DashboardVmCustomer>().onNavbarTapped(1);
context.read<AppointmentsVM>().applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments);
},
).horPaddingMain(),
CustomerAppointmentSliderWidget(myUpComingAppointments: context.read<AppointmentsVM>().myUpComingAppointments),
7.height,
ViewAllWidget(
title: "My Recent Service Providers".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVmCustomer>().onNavbarTapped(0);
context.read<AppointmentsVM>().applyFilterOnProviders(index: 0);
}).horPaddingMain(),
Consumer(builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) {
return ServiceProviderWidget(nearbyBranches: context.read<AppointmentsVM>().nearbyBranches).horPaddingMain();
}),
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column(
children: [
if (adVM.myActiveAdsForHome.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Active Ads".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(false);
}).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: true,
isAdsFragment: false,
adsList: adVM.myActiveAdsForHome,
scrollPhysics: NeverScrollableScrollPhysics(),
),
],
)
],
if (adVM.exploreAds.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Recommended Ads".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(false);
}).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: true,
isAdsFragment: false,
adsList: adVM.myActiveAdsForHome,
scrollPhysics: NeverScrollableScrollPhysics(),
),
],
)
context.read<DashboardVmCustomer>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(true);
context.read<AdVM>().applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds);
},
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds,
isAdsFragment: false,
scrollPhysics: NeverScrollableScrollPhysics(),
),
],
)
]
],
if (adVM.exploreAds.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Recommended Ads".toUpperCase(),
subTitle: "View All",
onSubtitleTapped: () {
context.read<DashboardVM>().onNavbarTapped(3);
context.read<AdVM>().updateIsExploreAds(true);
context.read<AdVM>().applyFilterOnExploreAds(index: 0);
},
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: false,
adsList: adVM.exploreAds.length >= 3 ? adVM.exploreAds.take(3).toList() : adVM.exploreAds,
isAdsFragment: false,
scrollPhysics: NeverScrollableScrollPhysics(),
),
],
)
]
],
);
},
),
20.height,
],
);
},
),
20.height,
],
),
),
),
),

@ -0,0 +1,71 @@
import 'package:mc_common_app/view_models/requests_view_model.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/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/views/requests/widget/request_item.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:provider/provider.dart';
class MyRequestsFragment extends StatelessWidget {
const MyRequestsFragment({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) {
return Column(
children: [
16.height,
FiltersList(
filterList: requestsVM.requestsTypeFilterOptions,
onFilterTapped: (index, selectedFilterId) {
requestsVM.applyFilterOnRequestsVM(requestsTypeEnum: selectedFilterId.toRequestTypeStatusEnum());
},
),
8.height,
Expanded(
child: RefreshIndicator(
onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true, appType: AppType.customer),
child: requestsVM.state == ViewState.busy
? const Center(child: CircularProgressIndicator())
: requestsVM.myFilteredRequests.isEmpty
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor),
],
)
: ListView.separated(
itemBuilder: (context, index) {
return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppType.customer);
},
separatorBuilder: (context, index) {
return 16.height;
},
itemCount: requestsVM.myFilteredRequests.length,
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16, top: 8),
),
))
],
);
}),
),
floatingActionButton: FloatingActionButton(
onPressed: () => navigateWithName(context, AppRoutes.createRequestPage),
backgroundColor: MyColors.darkPrimaryColor,
child: const Icon(
Icons.add,
color: MyColors.white,
),
),
);
}
}

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

@ -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,4 @@
import 'package:car_customer_app/view_models/dashboard_view_model.dart';
import 'package:mc_common_app/view_models/dashboard_view_model_customer.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@ -13,13 +13,13 @@ class CustomBottomNavbar extends StatelessWidget {
@override
Widget build(BuildContext context) {
DashboardVM dashboardVM = context.watch<DashboardVM>();
DashboardVmCustomer dashboardVM = context.watch<DashboardVmCustomer>();
return BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.providersIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.providersIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.providers.tr(),
icon: SvgPicture.asset(MyAssets.branchesIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.branchesIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.branches.tr(),
),
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.appointmentsIcon).paddingAll(5),
@ -40,9 +40,9 @@ class CustomBottomNavbar extends StatelessWidget {
label: LocaleKeys.ads.tr(),
),
BottomNavigationBarItem(
icon: SvgPicture.asset(MyAssets.settingsIcon).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.settingsIcon, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.settings.tr(),
icon: SvgPicture.asset(MyAssets.icRequests).paddingAll(5),
activeIcon: SvgPicture.asset(MyAssets.icRequests, color: MyColors.darkIconColor).paddingAll(5),
label: LocaleKeys.requests.tr(),
),
],
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:flutter/material.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/string_extensions.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/models/user/image_response.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
@ -16,7 +16,7 @@ import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
class CustomDrawer extends StatefulWidget {
final DashboardVM dashboardVM;
final DashboardVmCustomer dashboardVM;
const CustomDrawer({Key? key, required this.dashboardVM}) : super(key: key);

@ -0,0 +1,39 @@
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/widgets/extensions/extensions_widget.dart';
class ServiceProviderWidget extends StatelessWidget {
const ServiceProviderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 150,
child: ListView.builder(
itemCount: 9,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
width: 90,
child: Column(
children: [
Image.asset(
"assets/images/bn_car.jpeg",
width: 80,
height: 80,
fit: BoxFit.cover,
).toCircle(borderRadius: 100),
8.height,
"Olaya Branch".toText(fontSize: 14, isBold: true, textAlign: TextAlign.center),
],
),
);
},
),
);
}
}

@ -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,
)
],
),
);
}
}

@ -0,0 +1,223 @@
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:car_customer_app/views/provider/sheet/items_list_sheet.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/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 BranchDetailPage extends StatefulWidget {
final BranchDetailModel branchDetailModel;
BranchDetailPage({required this.branchDetailModel});
@override
State<BranchDetailPage> createState() => _BranchDetailPageState();
}
class _BranchDetailPageState extends State<BranchDetailPage> {
@override
void initState() {
// TODO: implement initState
super.initState();
if (widget.branchDetailModel.branchServices!.length > 0) widget.branchDetailModel.branchServices?.first.isExpandedOrSelected = true;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Branch Detail",
onBackButtonTapped: () {
context.read<AppointmentsVM>().resetCategorySelectionBottomSheet();
Navigator.pop(context);
},
),
body: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Container(
width: double.infinity,
padding: EdgeInsets.all(21),
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(MyAssets.bnCar),
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(
children: [
("Time" + ":").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
"${widget.branchDetailModel.openTime} - ${widget.branchDetailModel.closeTime}".toText(fontSize: 12, isBold: true),
],
),
2.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//TODO: Needs to implement url launcher
"Open Map Location".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)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
"Provider Profile".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.providerProfilePage, arguments: widget.branchDetailModel.serviceProviderId)),
],
),
20.height,
"Services Offer".toText(
fontSize: 16,
color: MyColors.lightTextColor,
isBold: true,
),
if (widget.branchDetailModel.branchServices!.length == 0) "No Services Available".toText(fontSize: 12, isBold: true),
showServicesList(),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
),
],
),
),
),
),
ShowFillButton(
title: "Book Appointment",
maxWidth: double.infinity,
margin: EdgeInsets.all(21),
onPressed: () {
navigateWithName(context, AppRoutes.bookAppointmenServicesView);
context.read<AppointmentsVM>().updateSelectedBranch(widget.branchDetailModel);
},
).toContainer(paddingAll: 0, backgroundColor: Colors.white),
],
),
);
}
Widget showServicesList() {
return ListView.separated(
itemBuilder: (context, index) {
return ExpansionTile(
tilePadding: EdgeInsets.zero,
title: (widget.branchDetailModel.branchServices![index].serviceDescription ?? "").toText(
fontSize: 16,
isBold: true,
),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showItem("Allowing home service:", (widget.branchDetailModel.branchServices![index].isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Home service range", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + "KM"),
showItem("Charges per KM", widget.branchDetailModel.branchServices![index].customerLocationRange.toString() + "SAR"),
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, isBold: true),
4.width,
value.toText(fontSize: 12, color: valueColor, isBold: true),
],
);
}
}

@ -0,0 +1,113 @@
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/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/provider_details_card.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 ProviderProfilePage extends StatefulWidget {
final int providerId;
ProviderProfilePage({required this.providerId});
@override
State<ProviderProfilePage> createState() => _ProviderProfilePageState();
}
class _ProviderProfilePageState extends State<ProviderProfilePage> {
@override
void initState() {
super.initState();
context.read<AppointmentsVM>().getBranchAndServices(widget.providerId);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: "Provider Details",
),
body: Container(
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(21),
child: Consumer<AppointmentsVM>(
builder: (context, model, _) {
return model.providerProfileModel == null
? const Center(child: CircularProgressIndicator())
: model.providerProfileModel == null
? const EmptyWidget()
: SingleChildScrollView(
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//TODO: company logo/banner not added form provider app yet
Image.asset(MyAssets.bnCar),
12.height,
model.providerProfileModel!.companyName.toString().toText(
fontSize: 16,
isBold: true,
),
Row(
children: [
("Mowater Member Since:").toText(color: MyColors.lightTextColor, fontSize: 12),
4.width,
//TODO: date is missing from API side
"2023".toText(fontSize: 12, isBold: true),
],
),
4.height,
//TODO: company description not added form provider app yet
// model.providerModel!.data!.companyDescription!.toText(color: MyColors.lightTextColor, fontSize: 12),
"Some description about the provider and their years of experience and their reputation".toText(color: MyColors.lightTextColor, fontSize: 12),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
),
12.height,
model.providerProfileModel!.serviceProviderBranch == null
? const Center(child: Text("No Branch Found"))
: model.providerProfileModel!.serviceProviderBranch!.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
return ProviderDetailsCard(
onCardTapped: () {
navigateWithName(context, AppRoutes.branchDetailPage, arguments: model.providerProfileModel!.serviceProviderBranch![index]);
},
providerImageUrl: MyAssets.bnCar,
title: model.providerProfileModel!.serviceProviderBranch![index].branchName ?? "",
providerLocation: model.providerProfileModel!.serviceProviderBranch![index].distanceKm.toString() + " KM",
providerName: model.providerProfileModel!.serviceProviderBranch![index].serviceProviderName ?? "",
providerRatings: "4.9",
services: model.providerProfileModel!.serviceProviderBranch![index].branchServices,
);
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: model.providerProfileModel!.serviceProviderBranch!.length,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
)
],
),
);
},
),
),
);
}
}

@ -0,0 +1,104 @@
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.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/theme/colors.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 serviceId;
ItemsListSheet(this.serviceId);
@override
State<ItemsListSheet> createState() => _ItemsListSheetState();
}
class _ItemsListSheetState extends State<ItemsListSheet> {
@override
void initState() {
super.initState();
context.read<AppointmentsVM>().getServiceItems(widget.serviceId);
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: MediaQuery.of(context).size.height / 1.2,
child: Consumer<AppointmentsVM>(
builder: (context, appointmentsVM, _) {
return appointmentsVM.serviceItemsFromApi.isEmpty
? const EmptyWidget()
: 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),
4.height,
showItem("Available for appointment:", (serviceItemModel.isAllowAppointment ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Allowing Workshop service:", (serviceItemModel.isAppointmentCompanyLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
showItem("Allowing home service:", (serviceItemModel.isAppointmentCustomerLoc ?? false) ? "Yes" : "No", valueColor: Colors.green),
12.height,
"Service Amount".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: "SAR".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, isBold: true),
4.width,
value.toText(fontSize: 12, color: valueColor, isBold: true),
],
);
}
}

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@ -36,7 +36,7 @@ dependencies:
cupertino_icons: ^1.0.2
mc_common_app:
path: D:/Development/car_common_app
path: C:/Users/mirza.shafique/AndroidStudioProjects/mc_common_app
dev_dependencies:
flutter_test:
@ -74,7 +74,7 @@ flutter:
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:

Loading…
Cancel
Save