Compare commits

...

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

46
.gitignore vendored

@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 18116933e77adc82f80866c928266a5b4f1ed645
channel: stable
project_type: app

@ -1,93 +1,16 @@
# car_provider_app # car_provider_app
A new Flutter project.
## Getting Started
## Getting started This project is a starting point for a Flutter application.
To make it easy for you to get started with GitLab, here's a list of recommended next steps. A few resources to get you started if this is your first Flutter project:
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
## Add your files
- [ ] [Create](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.com/mirza.shafique/car_provider_app.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://gitlab.com/mirza.shafique/car_provider_app/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Automatically merge when pipeline succeeds](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://gitlab.com/-/experiment/new_project_readme_content:9529efb8c774508b24431e4d43ca8b4e?https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

13
android/.gitignore vendored

@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

@ -0,0 +1,68 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.ejadaa.hmg"
minSdkVersion 23
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

@ -0,0 +1,42 @@
{
"project_info": {
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063",
"android_client_info": {
"package_name": "com.ejada.hmg"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.car_provider_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

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

@ -0,0 +1,6 @@
package com.example.car_provider_app
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.car_provider_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

@ -0,0 +1,29 @@
buildscript {
ext.kotlin_version = '1.8.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

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

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -0,0 +1,11 @@
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

@ -0,0 +1,14 @@
## For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Wed Dec 13 16:00:22 AST 2023
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"

34
ios/.gitignore vendored

@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>9.0</string>
</dict>
</plist>

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

@ -0,0 +1,44 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

@ -0,0 +1,539 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
5E9559759AEA0E089FDD9FD7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFCFDCCDB03A7D75BCB22117 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
589B0447F002C308698802BD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B5D2F47A7F9A7D8C8678860A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
BFCFDCCDB03A7D75BCB22117 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F095357B123772C701252686 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5E9559759AEA0E089FDD9FD7 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
CF641C50961DBDC07AA7AD64 /* Pods */,
C0F0C01C1B0541A9B1F8E6D5 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
C0F0C01C1B0541A9B1F8E6D5 /* Frameworks */ = {
isa = PBXGroup;
children = (
BFCFDCCDB03A7D75BCB22117 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
CF641C50961DBDC07AA7AD64 /* Pods */ = {
isa = PBXGroup;
children = (
589B0447F002C308698802BD /* Pods-Runner.debug.xcconfig */,
F095357B123772C701252686 /* Pods-Runner.release.xcconfig */,
B5D2F47A7F9A7D8C8678860A /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
719FDEEFEE98A49E1AC9E990 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
C9CF36692C973DF3840AB8D9 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
719FDEEFEE98A49E1AC9E990 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
C9CF36692C973DF3840AB8D9 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carProviderApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carProviderApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.example.carProviderApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>car_provider_app</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>NSCameraUsageDescription</key>
<string>Access to take a photo by camera</string>
<key>NSAppleMusicUsageDescription</key>
<string>Access to pick a photo</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Access to pick a photo</string>
</dict>
</plist>

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

@ -0,0 +1,17 @@
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/repositories/subscription_repo.dart';
class ProviderAppDependencies {
static void addDependencies() {
AppDependencies.addDependencies();
injector.registerSingleton<BranchRepo>(() => BranchRepoImp());
injector.registerSingleton<ItemsRepo>(() => ItemsRepoImp());
// injector.registerSingleton<CommonRepo>(() => CommonRepoImp());
injector.registerSingleton<SubscriptionRepo>(() => SubscriptionRepoImp());
injector.registerSingleton<ScheduleRepo>(() => ScheduleRepoImp());
}
}

@ -0,0 +1,159 @@
import 'package:car_provider_app/views/appoinments/add_new_service_appointment_page.dart';
import 'package:car_provider_app/views/appoinments/appoinment_detail_list_page.dart';
import 'package:car_provider_app/views/appoinments/appointment_page.dart';
import 'package:car_provider_app/views/appoinments/merge_appointment_page.dart';
import 'package:car_provider_app/views/appoinments/update_appointment_page.dart';
import 'package:car_provider_app/views/requests/request_detail_page.dart';
import 'package:car_provider_app/views/requests/send_offer_page.dart';
import 'package:car_provider_app/views/settings/branch/branch_detail_page.dart';
import 'package:car_provider_app/views/settings/branch/branch_list_page.dart';
import 'package:car_provider_app/views/settings/branch/dealer/dealer_user_page.dart';
import 'package:car_provider_app/views/settings/branch/define_branch_page.dart';
import 'package:car_provider_app/views/settings/create_services_page.dart';
import 'package:car_provider_app/views/settings/schedule/add_schedules_page.dart';
import 'package:car_provider_app/views/settings/schedule/schedules_list_page.dart';
import 'package:car_provider_app/views/settings/services/create_item_page.dart';
import 'package:car_provider_app/views/settings/services/create_services_page2.dart';
import 'package:car_provider_app/views/settings/dealership_page.dart';
import 'package:car_provider_app/views/settings/define_license_page.dart';
import 'package:car_provider_app/views/settings/services/create_services_page3.dart';
import 'package:car_provider_app/views/settings/services/duplication/matched_services_page.dart';
import 'package:car_provider_app/views/settings/services/duplication/sheet/approved_branches_list_sheet.dart';
import 'package:car_provider_app/views/settings/services/items_list_page.dart';
import 'package:car_provider_app/views/settings/services/services_list_page.dart';
import 'package:car_provider_app/views/subscriptions/my_subscritions_page.dart';
import 'package:car_provider_app/views/subscriptions/subscriptions_page.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
import 'package:flutter/material.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/chat/chat_view.dart';
import 'package:mc_common_app/views/payments/payment_methods_view.dart';
import '../views/dashboard/dashboard_page.dart';
class ProviderAppRoutes {
//settings
static const defineLicense = "/defineLicese";
static const String dealershipSetting = "/dealershipSetting";
static const String branchList = "/branchList";
static const String branchDetail = "/branchDetail";
static const String defineBranch = "/defineBranch";
//Appointments
static const String appointment = "/appointment";
static const String appointmentDetailList = "/appointmentDetailList";
static const String updateAppointmentPage = "/updateAppointmentPage";
static const String addServiceInAppointment = "/addServiceInAppointment";
static const String mergeAppointments = "/mergeAppointments";
//Requests
static const String requestsDetailPage = "/requestsDetailPage";
static const String sendOfferPage = "/sendOfferPage";
//Services
static const String dealerUser = "/dealerUser";
static const String servicesList = "/servicesList";
static const String itemsList = "/itemsList";
static const String createItem = "/createItem";
static const String createServices = "/createServices";
static const String createServices2 = "/createServices2";
static const String createServices3 = "/createServices3";
//Schedules
static const String schedulesList = "/schedulesList";
static const String addSchedule = "/addSchedule";
// Subscriptions
static const String mySubscriptionsPage = "/mySubscriptionsPage";
static const String subscriptionsPage = "/subscriptionsPage";
//Bracnh Duplication
static const String matchServices = "/matchServices";
static final Map<String, WidgetBuilder> routes = {
//Home page
AppRoutes.dashboard: (context) => const DashboardPage(),
AppRoutes.adsDetailView: (context) => AdsDetailView(
adDetails:
ModalRoute.of(context)!.settings.arguments as AdDetailsModel),
AppRoutes.createAdView: (context) => const CreateAdView(),
//setting
defineLicense: (context) => DefineLicensePage(),
dealershipSetting: (context) => DealershipPage(),
// branchList: (context) => BranchListPage(),
defineBranch: (context) => DefineBranchPage(
(ModalRoute.of(context)!.settings.arguments) == null
? null
: (ModalRoute.of(context)!.settings.arguments
as BranchDetailModel)),
branchDetail: (context) => BranchDetailPage(
ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
//Appointments
appointment: (context) => AppointmentPage(
branch:
ModalRoute.of(context)!.settings.arguments as BranchDetailModel),
appointmentDetailList: (context) => AppointmentDetailListPage(),
updateAppointmentPage: (context) => UpdateAppointmentPage(),
addServiceInAppointment: (context) => AddNewServiceAppointmentPage(
ModalRoute.of(context)!.settings.arguments as AppointmentListModel),
mergeAppointments: (context) => MergeAppointmentListPage(),
//Requests
AppRoutes.requestsDetailPage: (context) => RequestDetailPage(
requestDetailPageArguments: ModalRoute.of(context)!.settings.arguments
as RequestDetailPageArguments,
),
AppRoutes.sendOfferPage: (context) => const SendOfferPage(),
//Subscriptions
mySubscriptionsPage: (context) => const MySubscriptionsPage(),
subscriptionsPage: (context) => const SubscriptionsPage(),
AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes),
//Services
dealerUser: (context) =>
DealerUserPage(ModalRoute.of(context)!.settings.arguments as String),
servicesList: (context) => const ServicesListPage(),
itemsList: (context) => ItemsListPage(),
createItem: (context) => const CreateItemPage(),
//createServices: (context) => CreateServicesPage((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
//createServices2: (context) => CreateServicesPage2((ModalRoute.of(context)!.settings.arguments) == null ? null : (ModalRoute.of(context)!.settings.arguments as ServiceProviderBranch)),
createServices3: (context) => CreateServicesPage3(
(ModalRoute.of(context)!.settings.arguments) == null
? null
: (ModalRoute.of(context)!.settings.arguments
as CreateBranchModel)),
//Schedules
schedulesList: (context) => SchedulesListPage(
(ModalRoute.of(context)!.settings.arguments) == null
? null
: (ModalRoute.of(context)!.settings.arguments as String)),
addSchedule: (context) => AddSchedulesPage(),
//Branch Duplication
matchServices: (context) => MatchedServicesPage(
(ModalRoute.of(context)!.settings.arguments) == null
? null
: (ModalRoute.of(context)!.settings.arguments
as MatchServicesArguments)),
AppRoutes.chatView: (context) => ChatView(
chatViewArguments:
ModalRoute.of(context)!.settings.arguments as ChatViewArguments,
),
//ADS:
AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(
isProvider: ModalRoute.of(context)!.settings.arguments as bool),
};
}

@ -0,0 +1,406 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
// ignore_for_file: prefer_single_quotes
import 'dart:ui';
import 'package:easy_localization/easy_localization.dart' show AssetLoader;
class CodegenLoader extends AssetLoader{
const CodegenLoader();
@override
Future<Map<String, dynamic>> load(String fullPath, Locale locale ) {
return Future.value(mapLocales[locale.toString()]);
}
static const Map<String,dynamic> ar_SA = {
"firstTimeLogIn": "تسجيل الدخول لأول مره",
"signUp": "التسجيل",
"changeMobile": "تغيير رقم الجوال",
"notifications": "الاشعارات",
"general": "عام",
"defineLicences": "تحديد الرخص",
"dealershipSettings": "اعدادات البيع",
"changePassword": "تغيير كلمة المرور",
"retrievePassword": "استرجاع كلمة المرور",
"changeEmail": "تغيير الايميل",
"verify": "تحقق",
"verified": "تم التحقق",
"signOut": "تسجيل خروج",
"enterEmail": "ادخل الايميل",
"enterNewEmail": "ادخل ايميل جديد",
"enterCurrentPassword": "كلمة المرور الحاليه",
"enterNewPassword": "كلمة المرور الجديده",
"enterOldPassword": "كلمة المرور القديمه",
"confirm": "تأكيد",
"enterNewPhoneNumber": "رقم جوال جديد",
"completeProfile": "الملف الشخصي",
"continu": "استمرار",
"confirmPassword": "تأكيد كلمة المرور",
"createPassword": "انشاء كلمة مرور جديده",
"email": "ايميل",
"firstName": "الأسم الأول *",
"surname": "اسم العائله *",
"confirmPass": "تأكيد كلمة المرور *",
"createPass": "انشاء كلمة مرور جديده *",
"newPassword": " كلمة مرور جديده",
"forgetPassword": "نسيت كلمة المرور",
"forgetPasswordQ": "نسيت كلمة المرور؟",
"recover": "استعادة",
"forgetPasswordRecover": "نسيت كلمة المرور؟ استعادة",
"editAccount": "تعديل الحساب",
"change": "تغيير",
"verifyAccount": "التحقق من الحساب",
"login": "تسجيل دخول",
"log_in": "تسجيل الدخول",
"welcomeMessage": "مرحبا",
"welcomeDes": "أنت مكان واحد لكل ما تحتاجه سيارتك",
"forgetPass": "نسيت كلمة المرور ؟",
"enterPhoneNumber": "رقم جوال ",
"phoneNumberVerified": "تم التحقق من الجوال",
"verifyNewPassword": "التحقق من كلمة المرور",
"EnterPass": "ادخل كلمة المرور",
"send": "إرسال",
"retrivePassword": "استرجع كلمة المرور بإحدى الطرق التالية",
"retriveOnPhone": "سوف نرسل الاختيار إلى رقم هاتفك المحمول المسجل",
"retriveOnEmail": "سوف نرسل الاختيار إلى عنوان بريدك الإلكتروني المسجل",
"enterPhoneForVerfication": "الرجاء إدخال رقم هاتفك وسنرسل لك رمز التحقق",
"selectYourCountry": "اختر بلدك",
"welcomeBack": "مرحبًا بعودتك!!!",
"alreadySigned": " تم تسجيل الدخول",
"emailChangedSuccessfully": "تم تغيير الايميل بنجاح",
"passwordIsUpdated": "تم تحجيث كلمة المرور",
"passwordShouldContains": "كلمة المرور يجب ان تحتوي على رمز رقم حرف كبير حرف صغير",
" successfullyRegistered": "تم التسجيل بنجاح",
"pleaseEnterSamePassword": "ادخل كلمة مرور مطابقه",
"firstNameMandatory": "ادخل الأسم الأول ",
"surnameNameMandatory": "ادخل اسم العائله",
"passwordNameMandatory": "ادخل كلمة المرور",
"enterValidEmail": "ادخل ايميل صحيح",
"pleaseAcceptTerms": "يجب الموافقه على الشروط",
"emailVerified": "تم التحقق من الايميل بنجاح",
"selectMethod": "اختر",
"emailAddress": "ايميل",
"loginSelection": "اختر",
"selectCountryCode": "اختر رمز الدوله",
"selectProviderRole": "اختر نوع الخدمه",
"addPhoneNo": "اضف الهاتف",
"onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات",
"imageUploaded": "تم تحميل الصوره",
"fileLarger": "1KB حجم الملف اكبر من",
"account": "الحساب",
"edit": "تعديل",
"imageDeleted": "تم حذف الصوره",
"dashboard": "الصفحه الرئيسيه",
"pickAddress": "اختر العنوان",
"pickLocation": "اختر الموقع",
"save": "حفظ",
"defineServices": "تحديد الخدمات",
"selectBranch ": "اختر الفرع",
"selectServiceCategory": "اختر فئة الخدمة",
"defineBranches": "تحديد الفروع",
"defineProviders": "تحديد الموفرين",
"closeAccount": "اغلاق الحساب",
"createBranch": "انشاء فرع",
"updateBranch": "فرع التحديث",
"address": "العنوان",
"branchDescription": "وصف الفرع",
"branchName": "اسم الفرع",
"chooseCity": "اختر المدينه",
"chooseCountry": "اختر الدوله",
"selectAttachment": "اختيار مرفق",
"somethingWrong": "هناك خطأ ما",
"documentsUploaded": "تم ارفاق الملف بنجاح",
"update": "تحديث",
"termsOfService": "من خلال إنشاء حساب فإنك توافق على",
"terms": "بنود الخدمة وخصوصية السياسة",
"profileMsg": "أدخل التفاصيل أدناه وأكمل معلومات الملف الشخصي",
"branchInfo": "معلومات الفرع و الخدمات",
"profileCompleted": "الملف الشخصي مكتمل",
"selectLocationMap": "اختر الموقع",
"licensesAndCertifications": "الرخص و الشهادات",
"completeProfile1": "اكمل الملف الشخصي 1/3",
"completeProfile2": "اكمل الملف الشخصي 2/3",
"completeProfile3": "اكمل الملف الشخصي 3/3",
"userInformation": "معلومات المتسخدم",
"faceRecognition": "تحقق مع بصمة الوجه",
"fingerPrint": "تحقق مع بصمة الاصبع",
"whatsapp": "تحقق مع Whatsapp",
"SMS": "رسائل قصيره",
"selectRole": "حدد الدور",
"userRoleOrTitle": "عنوان المستخدم",
"codeSentToEmail": "تم ارسال الرمز للايميل",
"number": "موبايل",
"phoneNumber": "رقم الهاتف",
"english": "English",
"provider": "Provider",
"title": "Hello",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"profile": {
"reset_password": {
"label": "Reset Password",
"username": "Username",
"password": "password"
}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {
"zero": "Your amount : {} ",
"one": "Your amount : {} ",
"two": "Your amount : {} ",
"few": "Your amount : {} ",
"many": "Your amount : {} ",
"other": "Your amount : {} "
},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {
"male": "Hi man ;) {}",
"female": "Hello girl :) {}"
}
},
"reset_locale": "Reset Language",
"insert_otp_code": "ادخل الرمز",
"type_code": "الرجاء كتابة الرمز الذي أرسلناه إلى",
"resend_code": "أعد إرسال الرمز",
"check_code": "التحقق من الشفرة",
"time_will_expire": "إعادة إرسال الرمز بتنسيق",
"sec": "ثانية",
"no_city_available": "لا توجد مدينة متاحة لهذا البلد",
"branch_created": "تم إنشاء الفرع بنجاح",
"branch_updated": "تم تحديث الفرع بنجاح",
"branch_deleted": "تم حذف الفرع بنجاح",
"dashboard_main": "لوحة القيادة / الصفحة الرئيسية",
"logo_brand": "الشعار / العلامة التجارية",
"remove": "إزالة",
"no_branch": "لم يتم إضافة فرع حتى الآن",
"login_once": "الرجاء تسجيل الدخول مرة واحدة",
"defineLicenese": "تحميل التراخيص والشهادات",
"description": "وصف",
"attachFile": "أرفق ملف",
"branchLocation": "معلومات الفرع والموقع",
"tapToEdit": "انقر للتعديل",
"myServiceBranches": "فروع خدمتي",
"enter_licence_detail": "الرجاء إدخال تفاصيل السجلات التجارية وإرفاق صور الترخيص",
"country": "بلد",
"city": "مدينة",
"editServices": "تحرير الخدمات",
"providers": "الموفرون",
"appointments": "تعيينات",
"home": "بيت",
"ads": "إعلانات",
"settings": "إعدادات",
"view_all": "مشاهدة الكل",
"my_active_Ads": "إعلاناتي النشطة",
"recommended_ads": "الإعلانات الموصى بها",
"upcoming_appointment": "الموعد القادم",
"my_service_providers": "مزودي الخدمة الجدد",
"appointment_details": "تفاصيل الموعد"
};
static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In",
"signUp": "Register",
"changeMobile": "Change Mobile",
"notifications": "Notifications",
"general": "General",
"defineLicences": "Register Licences",
"dealershipSettings": "Dealership Settings",
"changePassword": "Change Password",
"retrievePassword": "Retrieve Password",
"changeEmail": "Change Email",
"verify": "Verify",
"verified": "Verified",
"signOut": "Sign Out",
"enterEmail": "Enter Email and Password",
"enterNewEmail": "Enter New Email",
"enterNewPassword": "Enter New Password",
"enterCurrentPassword": "Enter Current Password",
"enterOldPassword": "Enter Old Password",
"confirm": "Confirm",
"completeProfile": "Complete Profile",
"enterNewPhoneNumber": "Enter New Phone Number",
"enterPhoneNumber": "Enter the login credentials",
"continu": "Continue",
"confirmPassword": "Confirm Password",
"createPassword": "Create Password",
"email": "Email",
"firstName": "First Name *",
"surname": "Surname *",
"confirmPass": "Confirm Password *",
"createPass": "Create Password *",
"newPassword": "New Password",
"forgetPassword": "Forget Password",
"forgetPasswordQ": "Forget Password?",
"recover": "Recover",
"forgetPasswordRecover": "Forget Password? Recover",
"editAccount": "Edit Account",
"change": "Change",
"verifyAccount": "Verify Account",
"login": "Login",
"log_in": "Log In",
"welcomeMessage": "Welcome To Mowater",
"welcomeDes": "You one stop place all your car needs",
"forgetPass": "Forget Password ?",
"phoneNumberVerified": "Phone Number Verified",
"verifyNewPassword": "Verify New Password",
"send": "Send",
"EnterPass": "Enter Password ?",
"retrivePassword": "Retrive password by one of following method",
"retriveOnPhone": "We will send the opt to your registered mobile number",
"retriveOnEmail": "We will send the opt to your registered email address",
"enterPhoneForVerfication": "Please enter your phone number We will send you the verification code",
"selectYourCountry": "Select Your Country",
"welcomeBack": "Welcome Back!!!",
"alreadySigned": " Already Signed Up and Logged In",
"emailChangedSuccessfully": "Email is Changed Successfully",
"passwordIsUpdated": "Password is Updated",
"passwordShouldContains": "Password Should contains Character, Number, Capital and small letters,",
" successfullyRegistered": " Successfully Registered, Please login once,",
"pleaseEnterSamePassword": "Please enter same password",
"firstNameMandatory": "First name is mandatory",
"surnameNameMandatory": "Surname is mandatory",
"passwordNameMandatory": "Password is mandatory",
"enterValidEmail": "Enter Valid Email",
"pleaseAcceptTerms": "Please accept terms",
"emailVerified": "Email is verified successfully",
"selectMethod": "Select Method",
"emailAddress": "Email Address",
"loginSelection": "Login Selection",
"selectCountryCode": "Please select Country Code",
"selectProviderRole": "Please select Provider Role",
"addPhoneNo": "Please add Phone No",
"onlyCustomerApp": "Sorry, Only Customer's can log in this app",
"imageUploaded": "Image is uploaded",
"fileLarger": "File is larger then 1KB",
"account": "Account",
"edit": "EDIT",
"imageDeleted": "Image is Deleted",
"dashboard": "Dashboard/Main Page",
"pickAddress": "Pick Address",
"pickLocation": "Pick Location",
"save": "Save",
"defineServices": "Define Services",
"selectBranch ": "Select Branch ",
"selectServiceCategory": "Select Service Category",
"defineBranches": "Define Branches",
"defineProviders": "Define Providers",
"closeAccount": "Close Account",
"createBranch": "Create Branch",
"updateBranch": "Update Branch",
"address": "Address",
"branchDescription": "Branch Description",
"branchName": "Branch Name",
"chooseCity": "Select City",
"chooseCountry": "Choose Country",
"selectAttachment": "Select Attachment",
"somethingWrong": "Something went wrong",
"documentsUploaded": "Documents uploaded successfully",
"update": "Update",
"termsOfService": "By creating an account you agree to our",
"terms": "Terms of Service and Privacy Policy",
"profileMsg": "Enter the details below and complete the profile info",
"branchInfo": "Branch Info and Services",
"profileCompleted": "Profile is Completed",
"selectLocationMap": "Select Location Map",
"licensesAndCertifications": "licenses & certifications",
"completeProfile1": "Complete Profile 1/3",
"completeProfile2": "Complete Profile 2/3",
"completeProfile3": "Complete Profile 3/3",
"userInformation": "User Information",
"provider": "Provider",
"faceRecognition": "Face Recognition",
"fingerPrint": "Finger Print",
"whatsapp": "With Whatsapp",
"SMS": "With SMS",
"selectRole": "Choose Role",
"userRoleOrTitle": "User role or title",
"codeSentToEmail": "Code is sent to email",
"number": "Number",
"phoneNumber": "Phone Number",
"english": "عربي",
"title": "Hello",
"msg": "Hello {} in the {} world ",
"msg_named": "{} are written in the {lang} language",
"clickMe": "Click me",
"profile": {
"reset_password": {
"label": "Reset Password",
"username": "Username",
"password": "password"
}
},
"clicked": {
"zero": "You clicked {} times!",
"one": "You clicked {} time!",
"two": "You clicked {} times!",
"few": "You clicked {} times!",
"many": "You clicked {} times!",
"other": "You clicked {} times!"
},
"amount": {
"zero": "Your amount : {} ",
"one": "Your amount : {} ",
"two": "Your amount : {} ",
"few": "Your amount : {} ",
"many": "Your amount : {} ",
"other": "Your amount : {} "
},
"gender": {
"male": "Hi man ;) ",
"female": "Hello girl :)",
"with_arg": {
"male": "Hi man ;) {}",
"female": "Hello girl :) {}"
}
},
"reset_locale": "Reset Language",
"insert_otp_code": "Enter the code",
"type_code": "Please type the code we sent to",
"resend_code": "Resend Code",
"check_code": "Check Code",
"time_will_expire": "Resend code in",
"sec": "sec",
"no_city_available": "No City Available for this country",
"branch_created": "Branch is successfully created",
"branch_updated": "Branch is successfully Updated",
"branch_deleted": "Branch is successfully Deleted",
"dashboard_main": "Dashboard/Main Page",
"logo_brand": "Logo/Brand",
"remove": "Remove",
"no_branch": "No Branch Added Yet",
"login_once": "Please login once",
"defineLicenese": "Upload Licenses and Certificates",
"description": "Description",
"attachFile": "Attach File",
"branchLocation": "Branch info and Location",
"tapToEdit": "Tap to edit",
"myServiceBranches": "My Service Branches",
"enter_licence_detail": "Please enter the detail for commercial records and attach the license images",
"country": "country",
"city": "city",
"editServices": "Edit Services",
"providers": "Providers",
"appointments": "Appointments",
"home": "Home",
"ads": "Ads",
"settings": "Settings",
"view_all": "view all",
"my_active_Ads": "My Active Ads",
"recommended_ads": "Recommended Ads",
"upcoming_appointment": "Upcoming Appointment",
"my_service_providers": "My Recent Service Providers",
"appointment_details": "Appointment Details"
};
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
}

@ -0,0 +1,175 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
abstract class LocaleKeys {
static const firstTimeLogIn = 'firstTimeLogIn';
static const signUp = 'signUp';
static const changeMobile = 'changeMobile';
static const notifications = 'notifications';
static const general = 'general';
static const defineLicences = 'defineLicences';
static const dealershipSettings = 'dealershipSettings';
static const changePassword = 'changePassword';
static const retrievePassword = 'retrievePassword';
static const changeEmail = 'changeEmail';
static const verify = 'verify';
static const verified = 'verified';
static const signOut = 'signOut';
static const enterEmail = 'enterEmail';
static const enterNewEmail = 'enterNewEmail';
static const enterCurrentPassword = 'enterCurrentPassword';
static const enterNewPassword = 'enterNewPassword';
static const enterOldPassword = 'enterOldPassword';
static const confirm = 'confirm';
static const enterNewPhoneNumber = 'enterNewPhoneNumber';
static const completeProfile = 'completeProfile';
static const continu = 'continu';
static const confirmPassword = 'confirmPassword';
static const createPassword = 'createPassword';
static const email = 'email';
static const firstName = 'firstName';
static const surname = 'surname';
static const confirmPass = 'confirmPass';
static const createPass = 'createPass';
static const newPassword = 'newPassword';
static const forgetPassword = 'forgetPassword';
static const forgetPasswordQ = 'forgetPasswordQ';
static const recover = 'recover';
static const forgetPasswordRecover = 'forgetPasswordRecover';
static const editAccount = 'editAccount';
static const change = 'change';
static const verifyAccount = 'verifyAccount';
static const login = 'login';
static const log_in = 'log_in';
static const welcomeMessage = 'welcomeMessage';
static const welcomeDes = 'welcomeDes';
static const forgetPass = 'forgetPass';
static const enterPhoneNumber = 'enterPhoneNumber';
static const phoneNumberVerified = 'phoneNumberVerified';
static const verifyNewPassword = 'verifyNewPassword';
static const EnterPass = 'EnterPass';
static const send = 'send';
static const retrivePassword = 'retrivePassword';
static const retriveOnPhone = 'retriveOnPhone';
static const retriveOnEmail = 'retriveOnEmail';
static const enterPhoneForVerfication = 'enterPhoneForVerfication';
static const selectYourCountry = 'selectYourCountry';
static const welcomeBack = 'welcomeBack';
static const alreadySigned = 'alreadySigned';
static const emailChangedSuccessfully = 'emailChangedSuccessfully';
static const passwordIsUpdated = 'passwordIsUpdated';
static const passwordShouldContains = 'passwordShouldContains';
static const successfullyRegistered = ' successfullyRegistered';
static const pleaseEnterSamePassword = 'pleaseEnterSamePassword';
static const firstNameMandatory = 'firstNameMandatory';
static const surnameNameMandatory = 'surnameNameMandatory';
static const passwordNameMandatory = 'passwordNameMandatory';
static const enterValidEmail = 'enterValidEmail';
static const pleaseAcceptTerms = 'pleaseAcceptTerms';
static const emailVerified = 'emailVerified';
static const selectMethod = 'selectMethod';
static const emailAddress = 'emailAddress';
static const loginSelection = 'loginSelection';
static const selectCountryCode = 'selectCountryCode';
static const selectProviderRole = 'selectProviderRole';
static const addPhoneNo = 'addPhoneNo';
static const onlyProviderApp = 'onlyProviderApp';
static const imageUploaded = 'imageUploaded';
static const fileLarger = 'fileLarger';
static const account = 'account';
static const edit = 'edit';
static const imageDeleted = 'imageDeleted';
static const dashboard = 'dashboard';
static const pickAddress = 'pickAddress';
static const pickLocation = 'pickLocation';
static const save = 'save';
static const defineServices = 'defineServices';
static const selectBranch = 'selectBranch ';
static const selectServiceCategory = 'selectServiceCategory';
static const defineBranches = 'defineBranches';
static const defineProviders = 'defineProviders';
static const closeAccount = 'closeAccount';
static const createBranch = 'createBranch';
static const updateBranch = 'updateBranch';
static const address = 'address';
static const branchDescription = 'branchDescription';
static const branchName = 'branchName';
static const chooseCity = 'chooseCity';
static const chooseCountry = 'chooseCountry';
static const selectAttachment = 'selectAttachment';
static const somethingWrong = 'somethingWrong';
static const documentsUploaded = 'documentsUploaded';
static const update = 'update';
static const termsOfService = 'termsOfService';
static const terms = 'terms';
static const profileMsg = 'profileMsg';
static const branchInfo = 'branchInfo';
static const profileCompleted = 'profileCompleted';
static const selectLocationMap = 'selectLocationMap';
static const licensesAndCertifications = 'licensesAndCertifications';
static const completeProfile1 = 'completeProfile1';
static const completeProfile2 = 'completeProfile2';
static const completeProfile3 = 'completeProfile3';
static const userInformation = 'userInformation';
static const faceRecognition = 'faceRecognition';
static const fingerPrint = 'fingerPrint';
static const whatsapp = 'whatsapp';
static const SMS = 'SMS';
static const selectRole = 'selectRole';
static const userRoleOrTitle = 'userRoleOrTitle';
static const codeSentToEmail = 'codeSentToEmail';
static const number = 'number';
static const phoneNumber = 'phoneNumber';
static const english = 'english';
static const provider = 'provider';
static const title = 'title';
static const msg = 'msg';
static const msg_named = 'msg_named';
static const clickMe = 'clickMe';
static const profile_reset_password_label = 'profile.reset_password.label';
static const profile_reset_password_username = 'profile.reset_password.username';
static const profile_reset_password_password = 'profile.reset_password.password';
static const profile_reset_password = 'profile.reset_password';
static const profile = 'profile';
static const clicked = 'clicked';
static const amount = 'amount';
static const gender_with_arg = 'gender.with_arg';
static const gender = 'gender';
static const reset_locale = 'reset_locale';
static const insert_otp_code = 'insert_otp_code';
static const type_code = 'type_code';
static const resend_code = 'resend_code';
static const check_code = 'check_code';
static const time_will_expire = 'time_will_expire';
static const sec = 'sec';
static const no_city_available = 'no_city_available';
static const branch_created = 'branch_created';
static const branch_updated = 'branch_updated';
static const branch_deleted = 'branch_deleted';
static const dashboard_main = 'dashboard_main';
static const logo_brand = 'logo_brand';
static const remove = 'remove';
static const no_branch = 'no_branch';
static const login_once = 'login_once';
static const defineLicenese = 'defineLicenese';
static const description = 'description';
static const attachFile = 'attachFile';
static const branchLocation = 'branchLocation';
static const tapToEdit = 'tapToEdit';
static const myServiceBranches = 'myServiceBranches';
static const enter_licence_detail = 'enter_licence_detail';
static const country = 'country';
static const city = 'city';
static const editServices = 'editServices';
static const providers = 'providers';
static const appointments = 'appointments';
static const home = 'home';
static const ads = 'ads';
static const settings = 'settings';
static const view_all = 'view_all';
static const my_active_Ads = 'my_active_Ads';
static const recommended_ads = 'recommended_ads';
static const upcoming_appointment = 'upcoming_appointment';
static const my_service_providers = 'my_service_providers';
static const appointment_details = 'appointment_details';
}

@ -0,0 +1,170 @@
import 'package:car_provider_app/config/provider_dependencies.dart';
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/view_models/branch_view_model.dart';
import 'package:car_provider_app/view_models/dashboard_view_model.dart';
import 'package:car_provider_app/view_models/items_view_model.dart';
import 'package:car_provider_app/view_models/schedule_view_model.dart';
import 'package:car_provider_app/view_models/service_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/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/models/general_models/post_params_model.dart';
import 'package:mc_common_app/repositories/ads_repo.dart';
import 'package:mc_common_app/repositories/appointment_repo.dart';
import 'package:mc_common_app/repositories/chat_repo.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/repositories/payments_repo.dart';
import 'package:mc_common_app/repositories/provider_repo.dart';
import 'package:mc_common_app/repositories/request_repo.dart';
import 'package:mc_common_app/repositories/subscription_repo.dart';
import 'package:mc_common_app/repositories/user_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/services/payments_service.dart';
import 'package:mc_common_app/theme/app_theme.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/view_models/appointments_view_model.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/payment_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:mc_common_app/view_models/subscriptions_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';
import 'package:sizer/sizer.dart';
import 'config/provider_routes.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
ProviderAppDependencies.addDependencies();
await EasyLocalization.ensureInitialized();
ProviderAppRoutes.routes.addAll(AppRoutes.routes);
runApp(MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<BaseVM>(
create: (_) => BaseVM(),
),
ChangeNotifierProvider<DashboardVM>(
create: (_) => DashboardVM(
userRepo: injector.get<UserRepo>(),
commonServices: injector.get<CommonAppServices>(),
),
),
ChangeNotifierProvider<UserVM>(
create: (_) => UserVM(userRepo: injector.get<UserRepo>()),
),
// ChangeNotifierProvider<BranchVM>(
// create: (_) => BranchVM(
// branchRepo: injector.get<BranchRepo>(),
// commonServices: injector.get<CommonServices>(),
// commonRepo: injector.get<CommonRepo>(),
// ),
// ),
ChangeNotifierProvider<ServiceVM>(
create: (_) => ServiceVM(
branchRepo: injector.get<BranchRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<SubscriptionsVM>(
create: (_) =>
SubscriptionsVM(subscriptionRepo: injector.get<SubscriptionRepo>()),
),
ChangeNotifierProvider<ItemsVM>(
create: (_) => ItemsVM(
itemsRepo: injector.get<ItemsRepo>(),
commonServices: injector.get<CommonAppServices>(),
),
),
ChangeNotifierProvider<ScheduleVM>(
create: (_) => ScheduleVM(
scheduleRepo: injector.get<ScheduleRepo>(),
),
),
ChangeNotifierProvider<AdVM>(
create: (_) => AdVM(
commonServices: injector.get<CommonAppServices>(),
adsRepo: injector.get<AdsRepo>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<RequestsVM>(
create: (_) => RequestsVM(
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
requestRepo: injector.get<RequestRepo>(),
),
),
ChangeNotifierProvider<AppointmentsVM>(
create: (_) => AppointmentsVM(
scheduleRepo: injector.get<AppointmentRepo>(),
providerRepo: injector.get<ProviderRepo>(),
commonServices: injector.get<CommonAppServices>(),
commonRepo: injector.get<CommonRepo>(),
),
),
ChangeNotifierProvider<ChatVM>(
create: (_) => ChatVM(
chatRepo: injector.get<ChatRepo>(),
requestRepo: injector.get<RequestRepo>(),
),
),
ChangeNotifierProvider<PaymentVM>(
create: (_) => PaymentVM(
paymentService: injector.get<PaymentService>(),
paymentRepo: injector.get<PaymentsRepo>()),
),
],
child: const MyApp(),
).setupLocale());
}
// todo terminal command to genertate translation files
// flutter pub run easy_localization:generate --source-dir ./assets/langs
// todo terminal command to genertate translation keys
// flutter pub run easy_localization:generate --source-dir ./assets/langs -f keys -o locale_keys.g.dart
// command to generate languages data from json
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Sizer(
builder: (context, orientation, deviceType) {
injector.get<AppState>().setAppType(AppType.provider);
AppState().setPostParamsModel(
PostParamsModel(
languageID:
EasyLocalization.of(context)?.locale.languageCode == "ar"
? 1
: 2,
),
);
ThemeData data = AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar");
return MaterialApp(
theme: AppTheme.getTheme(
isArabic:
EasyLocalization.of(context)?.locale.languageCode == "ar"),
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
initialRoute: AppRoutes.initialRoute,
routes: ProviderAppRoutes.routes,
);
},
);
}
}

@ -0,0 +1,324 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/branch.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
abstract class BranchRepo {
Future<MResponse> createBranch(String branchName, String branchDescription,
String cityId, String address, String latitude, String longitude);
Future<MResponse> updateBranch(
int id,
String branchName,
String branchDescription,
String cityId,
String address,
String latitude,
String longitude,
{bool isNeedToDelete = true});
Future<Branch> fetchAllBranches();
Future<Category> fetchBranchCategory();
Future<Services> fetchServicesByCategoryId(String serviceCategoryId);
Future<Services> fetchProviderServices(String branchID, String serviceCategoryId);
Future<MResponse> createNewService(List<Map<String, dynamic>> map);
Future<Document> getServiceProviderDocument(dynamic userId);
Future<MResponse> serviceProviderDocumentsUpdate(
List<DocumentData>? documents);
Future<ProviderModel> getBranchAndServices();
Future<MResponse> createService(List<Map<String, dynamic>> map);
Future<MResponse> updateService(List<Map<String, dynamic>> map);
Future<MResponse> getMatchedServices(
int oldBranchId, int newBranchId, int categoryId);
Future<MResponse> duplicateItems(Map<String, dynamic> map);
Future<MResponse> getAllProviderDealers(Map<String, dynamic> map);
Future<MResponse> getBranchUsers(Map<String, dynamic> map);
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map);
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map);
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map);
}
class BranchRepoImp implements BranchRepo {
@override
Future<MResponse> createBranch(String branchName, String branchDescription,
String cityId, String address, String latitude, String longitude) async {
var postParams = {
"serviceProviderID": AppState().getUser.data?.userInfo?.providerId ?? "",
"branchName": branchName,
"branchDescription": branchDescription,
"cityID": cityId,
"address": address,
"latitude": latitude,
"longitude": longitude,
"isActive": true
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.createProviderBranch,
postParams,
token: t);
}
@override
Future<Branch> fetchAllBranches() async {
var postParams = {
"ServiceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Branch.fromJson(json), ApiConsts.ServiceProviderBranchGet,
queryParameters: postParams, token: t);
}
@override
Future<Category> fetchBranchCategory() async {
var postParams = {
"ServiceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Category.fromJson(json), ApiConsts.ServiceCategory_Get,
queryParameters: postParams, token: t);
}
@override
Future<Services> fetchServicesByCategoryId(String serviceCategoryId) async {
var postParams = {"ServiceCategoryID": serviceCategoryId};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Services.fromJson(json), ApiConsts.Services_Get,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> createNewService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Create,
map,
token: t);
}
@override
Future<Document> getServiceProviderDocument(dynamic userId) async {
var queryParameters = {
"ServiceProviderID": userId.toString(),
};
String? token = AppState().getUser.data?.accessToken;
debugPrint(token);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Document.fromJson(json), ApiConsts.GetProviderDocument,
queryParameters: queryParameters,
token: AppState().getUser.data!.accessToken ?? "");
}
@override
Future<MResponse> serviceProviderDocumentsUpdate(
List<DocumentData>? documents) async {
List<Map<String, dynamic>> map = [];
for (int i = 0; i < documents!.length; i++) {
if (documents[i].document != null) {
var postParams = {
"id": documents[i].id,
"serviceProviderID": documents[i].serviceProviderId,
"documentID": documents[i].documentId,
"documentExt": documents[i].fileExt,
"documentImage": documents[i].document,
"isActive": true
};
map.add(postParams);
}
}
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderDocument_Update,
map,
token: t);
}
@override
Future<ProviderModel> getBranchAndServices() async {
var postParams = {
"serviceProviderID":
AppState().getUser.data?.userInfo?.providerId.toString() ?? ""
};
String t = AppState().getUser.data!.accessToken ?? "";
print("tokeen121 " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => ProviderModel.fromJson(json), ApiConsts.BranchesAndServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> updateBranch(
int id,
String branchName,
String branchDescription,
String cityId,
String address,
String latitude,
String longitude,
{bool isNeedToDelete = true}) async {
String lat = "0", long = "0";
try {
lat = latitude.substring(0, 9);
long = longitude.substring(0, 9);
} catch (e) {}
var postParams = {
"id": id,
"serviceProviderID": AppState().getUser.data?.userInfo?.providerId ?? "",
"branchName": branchName,
"branchDescription": branchDescription,
"cityID": cityId,
"address": address,
"latitude": lat,
"longitude": long,
"isActive": isNeedToDelete
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.updateProviderBranch,
postParams,
token: t);
}
@override
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Create,
map,
token: t);
}
@override
Future<MResponse> updateService(List<Map<String, dynamic>> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.ServiceProviderService_Update,
map,
token: t);
}
@override
Future<MResponse> getMatchedServices(
int oldBranchId, int newBranchId, int categoryId) async {
var postParams = {
"ProviderBranchIDExisted": oldBranchId.toString(),
"ProviderBranchIDNew": newBranchId.toString(),
"CategoryID": categoryId.toString(),
};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getMatchedServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.duplicateItems, map,
token: t);
}
@override
Future<MResponse> getAllProviderDealers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getAllProviderDealers,
queryParameters: map, token: t);
}
@override
Future<MResponse> getBranchUsers(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.getBranchUser,
queryParameters: map, token: t);
}
@override
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json), ApiConsts.assignDealerToBranch, map,
token: t);
}
@override
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.removeDealerFromBranch,
map,
token: t);
}
@override
Future<Services> fetchProviderServices(String branchID, String serviceCategoryId) async {
var postParams = {
"ServiceCategoryID": serviceCategoryId,
"ProviderBranchID": branchID,
};
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint("token " + t);
return await injector.get<ApiClient>().getJsonForObject(
(json) => Services.fromJson(json), ApiConsts.GetProviderServices,
queryParameters: postParams, token: t);
}
@override
Future<MResponse> addNewServicesInAppointment(Map<String, dynamic> map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject(
(json) => MResponse.fromJson(json),
ApiConsts.AddNewServicesInAppointment,
map,
token: t);
}
}

@ -0,0 +1,46 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
abstract class ItemsRepo {
Future<MResponse> createServiceItems(Map map);
Future<ItemModel> getServiceItems(int serviceId);
Future<MResponse> updateServiceItem(Map map);
}
class ItemsRepoImp implements ItemsRepo {
@override
Future<MResponse> createServiceItems(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint(t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createItems, map, token: t);
}
@override
Future<ItemModel> getServiceItems(int serviceId) async {
var queryParameters = {
"ServiceProviderServiceID": serviceId.toString(),
};
String? token = AppState().getUser.data?.accessToken;
debugPrint(token);
return await injector
.get<ApiClient>()
.getJsonForObject((json) => ItemModel.fromJson(json), ApiConsts.getServiceItems, queryParameters: queryParameters, token: AppState().getUser.data!.accessToken ?? "");
}
@override
Future<MResponse> updateServiceItem(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
debugPrint(t);
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateServiceItem, map, token: t);
}
}

@ -0,0 +1,62 @@
import 'package:mc_common_app/models/appointments_models/schedule_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/api/api_client.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
abstract class ScheduleRepo {
Future<Services> getAllServices(String branchId);
Future<MResponse> createSchedule(Map map);
Future<MResponse> addServicesInSchedule(Map map);
Future<MResponse> updateSchedule(Map map);
Future<Schedule> getSchedules(String branchId);
Future<MResponse> updateServicesInSchedule(Map map);
}
class ScheduleRepoImp implements ScheduleRepo {
@override
Future<Services> getAllServices(String branchId) async {
print("braanchId $branchId");
Map<String, dynamic> map = {"ProviderBranchID": branchId};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Services.fromJson(json), ApiConsts.getServicesOfBranch, token: t, queryParameters: map);
}
@override
Future<MResponse> createSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createSchedule, map, token: t);
}
@override
Future<MResponse> addServicesInSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.createGroup, map, token: t);
}
@override
Future<Schedule> getSchedules(String branchId) async {
Map<String, dynamic> map = {"ServiceProviderBranchID": branchId};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().getJsonForObject((json) => Schedule.fromJson(json), ApiConsts.getSchedule, token: t, queryParameters: map);
}
@override
Future<MResponse> updateSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateSchedule, map, token: t);
}
@override
Future<MResponse> updateServicesInSchedule(Map map) async {
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => MResponse.fromJson(json), ApiConsts.updateGroup, map, token: t);
}
}

@ -0,0 +1,218 @@
// import 'dart:io';
//
// import 'package:car_provider_app/repositories/branch_repo.dart';
// import 'package:file_picker/file_picker.dart';
// import 'package:mc_common_app/models/m_response.dart';
// import 'package:mc_common_app/models/model/branch2.dart';
// import 'package:mc_common_app/models/profile/branch.dart';
// import 'package:mc_common_app/models/profile/categroy.dart';
// import 'package:mc_common_app/models/profile/document.dart';
// import 'package:mc_common_app/models/profile/services.dart';
// import 'package:mc_common_app/models/user/cities.dart';
// import 'package:mc_common_app/models/user/country.dart';
// import 'package:mc_common_app/repositories/common_repo.dart';
// import 'package:mc_common_app/services/services.dart';
// import 'package:mc_common_app/utils/enums.dart';
// import 'package:mc_common_app/utils/utils.dart';
// import 'package:mc_common_app/view_models/base_view_model.dart';
// import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
// import 'package:permission_handler/permission_handler.dart';
//
// class BranchVM extends BaseVM {
// final BranchRepo branchRepo;
// final CommonServices commonServices;
// final CommonRepo commonRepo;
//
// BranchVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
//
// Document? document;
// Branch2? branchs;
//
// //Create Branch
// String countryCode = "", address = "", branchName = "", branchDescription = "";
// double latitude = 0, longitude = 0;
// int role = -1, countryId = -1, cityId = -1;
// List<DropValue> countryDropList = [];
// List<DropValue> citiesDropList = [];
// DropValue? countryValue;
// DropValue? cityValue;
//
// Country? country;
// Cities? cities;
//
// //Create Service
// String? branchNameForService;
// int categoryId = -1, branchId = -1, serviceId = -1;
// DropValue? branchValue;
//
// List<DropValue> countryDropListForService = [];
// List<DropValue> categoryDropList = [];
// List<DropValue> servicesDropList = [];
//
// Branch? branch;
// Category? category;
// Services? services;
//
// getServiceProviderDocument(int providerId) async {
// setState(ViewState.busy);
// document = await branchRepo.getServiceProviderDocument(providerId);
// setState(ViewState.idle);
// }
//
// selectFile(int index) async {
// File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
//
// if (file != null) {
// int sizeInBytes = file.lengthSync();
// // double sizeInMb = sizeInBytes / (1024 * 1024);
// if (sizeInBytes > 1000) {
// Utils.showToast("File is larger then 1KB");
// } else {
// document!.data![index].document = Utils.convertFileToBase64(file);
// document!.data![index].fileExt = Utils.checkFileExt(file.path);
// document!.data![index].documentUrl = file.path;
// setState(ViewState.idle);
// }
// } else {
// // User canceled the picker
// }
// }
//
// Future<MResponse> updateDocument(List<DocumentData>? data) async {
// return await branchRepo.serviceProviderDocumentsUpdate(data);
// }
//
// //Create new branch
// getBranchAndServices() async {
// setState(ViewState.busy);
// branchs = await branchRepo.getBranchAndServices();
// setState(ViewState.idle);
// }
//
// getAllCountriesList(ServiceProviderBranch? branchData, String countryCode) async {
// setState(ViewState.busy);
// resetValues();
// country = await commonRepo.getAllCountries();
// country!.data?.forEach((element) {
// if (branchData != null) if (branchData.id != null) {
// if (element.id == branchData.countryID) {
// countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
// }
// }
// countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
// });
// if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
// setState(ViewState.idle);
// }
//
// getAllCities(ServiceProviderBranch? branchData, String countryCode) async {
// setState(ViewState.busy);
// citiesDropList.clear();
// cities = null;
// cityId = -1;
// cities = await commonRepo.getAllCites(countryId.toString());
// cities!.data?.forEach((element) {
// if (branchData != null && branchData.id != null) {
// if (element.id == branchData.cityId) {
// address = branchData.address!;
// branchName = branchData.branchName!;
// branchDescription = branchData.branchDescription!;
// latitude = double.parse(branchData.latitude ?? "");
// longitude = double.parse(branchData.longitude ?? "");
// countryId = branchData.countryID!;
// cityId = branchData.cityId!;
// cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
// }
// }
// citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
// });
// setState(ViewState.idle);
// }
//
// resetValues() {
// countryCode = "";
// address = "";
// branchName = "";
// branchDescription = "";
// latitude = 0;
// longitude = 0;
// role = -1;
// countryId = -1;
// cityId = -1;
// countryDropList.clear();
// countryId = -1;
// cityId = -1;
// cities = null;
// branchNameForService = null;
// categoryId = -1;
// branchId = -1;
// branchValue = null;
// serviceId = -1;
//
// countryDropListForService = [];
// categoryDropList = [];
// servicesDropList = [];
//
// branch = null;
// category = null;
// services = null;
// }
//
// Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
// return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
// return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// //Create Service
// fetchBranches() async {
// resetValues();
// setState(ViewState.busy);
// branch = await branchRepo.fetchAllBranches();
// branch!.data?.forEach((element) {
// countryDropListForService.add(DropValue(element.id ?? 0, ((element.branchName!.isEmpty ? "N/A" : element.branchName) ?? "N/A"), ""));
// });
// setState(ViewState.idle);
// }
//
// fetchBranchCategory(String countryCode) async {
// category = null;
// services = null;
// categoryId = -1;
// categoryDropList.clear();
// setState(ViewState.busy);
// category = await branchRepo.fetchBranchCategory();
// category!.data?.forEach((element) {
// categoryDropList.add(DropValue(
// element.id ?? 0,
// ((element.categoryName!.isEmpty
// ? "N/A"
// : countryCode == "SA"
// ? element.categoryNameN
// : element.categoryName) ??
// "N/A"),
// ""));
// });
// setState(ViewState.idle);
// }
//
// fetchServicesByCategoryId() async {
// setState(ViewState.busy);
// services = await branchRepo.fetchServicesByCategoryId(categoryId.toString());
// servicesDropList = [];
// for (var element in services!.data!) {
// servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
// }
// setState(ViewState.idle);
// }
//
// Future<MResponse> createService(List<Map<String, dynamic>> map) async {
// return await branchRepo.createService(map);
// }
//
// Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
// return await branchRepo.updateService(map);
// }
// }

@ -0,0 +1,74 @@
import 'dart:io';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
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_models/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/location/Location.dart';
import 'package:mc_common_app/utils/shared_prefrence.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.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);
}
fetchUsernameAndLocation() async {
String userName = await SharedPrefManager.getPhoneOrEmail();
Location.getCurrentLocation(
(LatLng? latlng) {
AppState().currentLocation = latlng ?? const LatLng(0, 0);
},
);
notifyListeners();
}
updateIndex(int i) {
selectedNavbarBarIndex = i;
notifyListeners();
}
}

@ -0,0 +1,73 @@
import 'dart:io';
import 'package:car_provider_app/repositories/items_repo.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:file_picker/file_picker.dart';
import '../views/settings/schedule/widgets/chips_picker_item.dart';
class ItemsVM extends BaseVM {
final ItemsRepo itemsRepo;
final CommonAppServices commonServices;
ItemsVM({required this.itemsRepo, required this.commonServices});
//Items
ItemModel? serviceItems;
Future<String?> selectFile(BuildContext context) async {
File? file = await commonServices.pickFile(context,fileType: FileType.image);
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000) {
Utils.showToast("File is larger then 1KB");
} else {
return Utils.convertFileToBase64(file);
}
} else {
// User canceled the picker
}
return null;
}
Future<MResponse> createServiceItem(Map map) async {
MResponse response = await itemsRepo.createServiceItems(map);
return response;
}
Future<ItemModel?> getServiceItems(int serviceId,
{List<PickerItem>? list}) async {
serviceItems = null;
setOnlyState(ViewState.busy);
serviceItems = await itemsRepo.getServiceItems(serviceId);
if (list != null) {
for (var element in list) {
for (var innerElement in serviceItems!.data!) {
if (element.id == innerElement.id) {
innerElement.isUpdateOrSelected = true;
}
}
// serviceItems!.data!.where(
// (innerElement) => element.id == innerElement.id
// ? innerElement.isUpdateOrSelected = true
// : innerElement.isUpdateOrSelected = true,
// );
}
}
setState(ViewState.idle);
return serviceItems;
}
Future<MResponse> updateServiceItem(Map map) async {
MResponse response = await itemsRepo.updateServiceItem(map);
return response;
}
}

@ -0,0 +1,114 @@
import 'package:mc_common_app/models/appointments_models/schedule_model.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:car_provider_app/repositories/schedule_repo.dart';
import 'package:car_provider_app/views/settings/schedule/widgets/chips_picker_item.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
List<PickerItem> initDaysList = [
PickerItem(id: 1, title: "Monday", isSelected: false),
PickerItem(id: 2, title: "Tuesday", isSelected: false),
PickerItem(id: 3, title: "Wednesday", isSelected: false),
PickerItem(id: 4, title: "Thursday", isSelected: false),
PickerItem(id: 5, title: "Friday", isSelected: false),
PickerItem(id: 6, title: "Saturday", isSelected: false),
PickerItem(id: 7, title: "Sunday", isSelected: false),
];
class ScheduleVM extends BaseVM {
ScheduleRepo scheduleRepo;
ScheduleVM({required this.scheduleRepo});
List<PickerItem> selectedServicesItems = [];
List<ServicesData>? servicesList;
List<PickerItem> selectedDaysItems = [];
Schedule? schedule;
refresh() {
setState(ViewState.idle);
}
getAllServices(String branchId, ScheduleData selectedSchedule) async {
// if (servicesList == null) {
servicesList = null;
Services services = await scheduleRepo.getAllServices(branchId);
if (services.messageStatus == 1) {
servicesList = services.data;
if (selectedSchedule.id != null) {
for (var element in servicesList!) {
for (var innerElement in selectedSchedule.scheduleServices!) {
if (element.id == innerElement.providerServiceId) {
element.isSelected = true;
}
}
}
}
}
setState(ViewState.idle);
// }
}
filterSelectedServices() {
if (servicesList != null) {
selectedServicesItems = [];
for (var element in servicesList!) {
if (element.isSelected ?? false) {
selectedServicesItems.add(PickerItem(id: element.id ?? 0, title: element.description ?? ""));
}
}
setState(ViewState.idle);
}
}
//Days
List<PickerItem> intiDays() {
for (var element in initDaysList) {
element.isSelected = false;
for (var innerElement in selectedDaysItems) {
if (element.id == innerElement.id) {
element.isSelected = true;
}
}
}
return initDaysList;
}
filterDays(List<PickerItem> picked) {
selectedDaysItems = [];
for (var element in picked) {
if (element.isSelected ?? false) {
selectedDaysItems.add(element);
}
}
setState(ViewState.idle);
}
Future<MResponse> createSchedule(Map map) async {
MResponse response = await scheduleRepo.createSchedule(map);
return response;
}
Future<MResponse> addServicesInSchedule(Map map) async {
MResponse response = await scheduleRepo.addServicesInSchedule(map);
return response;
}
getSchedules(String branchId) async {
schedule = null;
schedule = await scheduleRepo.getSchedules(branchId);
setState(ViewState.idle);
}
Future<MResponse> updateSchedule(Map map) async {
MResponse response = await scheduleRepo.updateSchedule(map);
return response;
}
Future<MResponse> updateServicesInSchedule(Map map) async {
MResponse response = await scheduleRepo.updateServicesInSchedule(map);
return response;
}
}

@ -0,0 +1,633 @@
// import 'dart:convert';
// import 'dart:io';
//
// import 'package:car_provider_app/repositories/branch_repo.dart';
// import 'package:mc_common_app/models/m_response.dart';
//
// import 'package:mc_common_app/models/model/provider_model.dart';
// import 'package:mc_common_app/models/profile/categroy.dart';
// import 'package:mc_common_app/models/profile/document.dart';
// import 'package:mc_common_app/models/profile/services.dart';
// import 'package:mc_common_app/models/services/branch_model.dart';
// import 'package:mc_common_app/models/services/item_model.dart';
// import 'package:mc_common_app/models/services/service_model.dart';
// import 'package:mc_common_app/models/user/cities.dart';
// import 'package:mc_common_app/models/user/country.dart';
// import 'package:mc_common_app/repositories/common_repo.dart';
// import 'package:mc_common_app/services/common_services.dart';
// import 'package:mc_common_app/utils/enums.dart';
// import 'package:mc_common_app/utils/utils.dart';
// import 'package:mc_common_app/view_models/base_view_model.dart';
// import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
// import 'package:file_picker/file_picker.dart';
//
// class ServiceVM extends BaseVM {
// final BranchRepo branchRepo;
// final CommonAppServices commonServices;
// final CommonRepo commonRepo;
//
// ServiceVM({required this.branchRepo, required this.commonServices, required this.commonRepo});
//
// //Documents & Branches
// int selectedBranchStatus = 3;
// Document? document;
// ProviderModel? branchs;
// Country? country;
// Cities? cities;
// DropValue? countryValue;
// DropValue? cityValue;
// List<DropValue> countryDropList = [];
// List<DropValue> citiesDropList = [];
// double latitude = 0, longitude = 0;
// int role = -1, countryId = -1, cityId = -1;
// String countryCode = "", address = "", branchName = "", branchDescription = "";
//
// getServiceProviderDocument(int providerId) async {
// setState(ViewState.busy);
// document = await branchRepo.getServiceProviderDocument(providerId);
// setState(ViewState.idle);
// }
//
// selectFile(int index) async {
// File? file = await commonServices.pickFile(fileType: FileType.custom, allowedExtensions: ['png', 'pdf', 'jpeg']);
//
// if (file != null) {
// int sizeInBytes = file.lengthSync();
// // double sizeInMb = sizeInBytes / (1024 * 1024);
// if (sizeInBytes > 1000) {
// Utils.showToast("File is larger then 1KB");
// } else {
// document!.data![index].document = Utils.convertFileToBase64(file);
// document!.data![index].fileExt = Utils.checkFileExt(file.path);
// document!.data![index].documentUrl = file.path;
// setState(ViewState.idle);
// }
// } else {
// // User canceled the picker
// }
// }
//
// Future<MResponse> updateDocument(List<DocumentData>? data) async {
// return await branchRepo.serviceProviderDocumentsUpdate(data);
// }
//
// //Create new branch
// getBranchAndServices() async {
// setState(ViewState.busy);
// branchs = await branchRepo.getBranchAndServices();
// setState(ViewState.idle);
// }
//
// getAllCountriesList(BranchModel? branchData, String countryCode) async {
// setState(ViewState.busy);
// resetValues();
// country = await commonRepo.getAllCountries();
// country!.data?.forEach((element) {
// if (branchData != null) if (branchData.id != null) {
// if (element.id == branchData.countryID) {
// countryValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? "");
// }
// }
// countryDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.countryNameN ?? "") : (element.countryName ?? ""), element.countryCode ?? ""));
// });
// if (branchData != null) if (branchData.id != null) getAllCities(branchData, countryCode);
// setState(ViewState.idle);
// }
//
// getAllCities(BranchModel? branchData, String countryCode) async {
// setState(ViewState.busy);
// citiesDropList.clear();
// cities = null;
// cityId = -1;
// cities = await commonRepo.getAllCites(countryId.toString());
// cities!.data?.forEach((element) {
// if (branchData != null && branchData.id != null) {
// if (element.id == branchData.cityId) {
// address = branchData.address!;
// branchName = branchData.branchName!;
// branchDescription = branchData.branchDescription!;
// latitude = double.parse(branchData.latitude ?? "");
// longitude = double.parse(branchData.longitude ?? "");
// countryId = branchData.countryID!;
// cityId = branchData.cityId!;
// cityValue = DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? "");
// }
// }
// citiesDropList.add(DropValue(element.id ?? 0, countryCode == "SA" ? (element.cityNameN ?? "") : (element.cityName ?? ""), element.id.toString() ?? ""));
// });
// setState(ViewState.idle);
// }
//
// Future<MResponse> createBranch(String branchName, String branchDescription, String cityId, String address, String latitude, String longitude) async {
// return await branchRepo.createBranch(branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// Future<MResponse> updateBranch(int id, String branchName, String branchDescription, String cityId, String address, String latitude, String longitude, {bool isNeedToDelete = true}) async {
// return await branchRepo.updateBranch(id ?? 0, branchName, branchDescription, cityId.toString(), address, latitude.toString(), longitude.toString());
// }
//
// resetValues() {
// countryCode = "";
// address = "";
// branchName = "";
// branchDescription = "";
// latitude = 0;
// longitude = 0;
// role = -1;
// countryId = -1;
// cityId = -1;
// countryDropList.clear();
// countryId = -1;
// cityId = -1;
// cities = null;
// categoryDropList = [];
// servicesDropList = [];
// services = null;
// }
//
// //Create Services
// Services? services;
// List<DropValue> categoryDropList = [];
// List<DropValue> servicesDropList = [];
//
// fetchBranchCategory(String countryCode) async {
// categoryDropList.clear();
// servicesDropList = [];
// services = null;
// setState(ViewState.busy);
// Category? category = await branchRepo.fetchBranchCategory();
// category.data?.forEach((element) {
// categoryDropList.add(DropValue(
// element.id ?? 0,
// ((element.categoryName!.isEmpty
// ? "N/A"
// : countryCode == "SA"
// ? element.categoryNameN
// : element.categoryName) ??
// "N/A"),
// ""));
// });
// setState(ViewState.idle);
// }
//
// fetchServicesByCategoryId(String categoryId) async {
// servicesDropList = [];
// setState(ViewState.busy);
// services = await branchRepo.fetchServicesByCategoryId(categoryId);
//
// for (var element in services!.data!) {
// servicesDropList.add(DropValue(element.id ?? 0, element.description ?? "N/aA", ""));
// }
// setState(ViewState.idle);
// }
//
// Future<MResponse> createService(List<Map<String, dynamic>> map) async {
// return await branchRepo.createService(map);
// }
//
// Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
// return await branchRepo.updateService(map);
// }
//
// updateSelectedBranchType(int status) {
// selectedBranchStatus = status;
// notifyListeners();
// }
//
// List<ServiceModel>? matchedServices;
// bool isAllSelected = false;
//
// getAllMatchedServices(int oldBranchId, int newBranchId, int categoryId) async {
// matchedServices = null;
// MResponse response = await branchRepo.getMatchedServices(oldBranchId, newBranchId, categoryId);
// matchedServices = [];
// if (response.messageStatus == 1) {
// matchedServices = List<ServiceModel>.from(response.data.map((x) => ServiceModel.fromJson(x)));
// }
// notifyListeners();
// }
//
// selectAllServices(bool value) {
// for (var element in matchedServices!) {
// element.isExpandedOrSelected = value;
// for (var item in element.serviceItems!) {
// item.isUpdateOrSelected = value;
// }
// }
// isAllSelected = value;
// notifyListeners();
// }
//
// updateServiceItem(int serviceIndex, bool value) {
// for (var element in matchedServices![serviceIndex].serviceItems!) {
// element.isUpdateOrSelected = value;
// }
// notifyListeners();
// }
//
// copyItems(int index, List<ItemData> copiedItems) {
// matchedServices![index].serviceItems = copiedItems;
// notifyListeners();
// }
//
// Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
// return await branchRepo.duplicateItems(map);
// }
// }
import 'dart:convert';
import 'dart:io';
import 'package:car_provider_app/repositories/branch_repo.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/document.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/services.dart';
import 'package:mc_common_app/models/provider_branches_models/provider_model.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/models/user_models/branch_user.dart';
import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/country.dart';
import 'package:mc_common_app/repositories/common_repo.dart';
import 'package:mc_common_app/services/common_services.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/base_view_model.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
class ServiceVM extends BaseVM {
final BranchRepo branchRepo;
final CommonAppServices commonServices;
final CommonRepo commonRepo;
ServiceVM({
required this.branchRepo,
required this.commonServices,
required this.commonRepo,
});
// Documents & Branches
int selectedBranchStatus = 3;
Document? document;
ProviderModel? branches;
Country? country;
Cities? cities;
DropValue? countryValue;
DropValue? cityValue;
List<DropValue> countryDropList = [];
List<DropValue> citiesDropList = [];
double latitude = 0;
double longitude = 0;
int role = -1;
int countryId = -1;
int cityId = -1;
String countryCode = "";
String address = "";
String branchName = "";
String branchDescription = "";
Future<void> getServiceProviderDocument(int providerId) async {
setState(ViewState.busy);
document = await branchRepo.getServiceProviderDocument(providerId);
setState(ViewState.idle);
}
Future<void> selectFile(BuildContext context,int index) async {
final File? file = await commonServices.pickFile(
context,
fileType: FileType.custom,
allowedExtensions: ['png', 'pdf', 'jpeg'],
);
// if (result != null) {
// final File file = File(result.files.single.path!);
// final int sizeInBytes = file.lengthSync();
//
// if (sizeInBytes > 1000) {
// Utils.showToast("File is larger than 1KB");
// } else {
// document!.data![index].document = Utils.convertFileToBase64(file);
// document!.data![index].fileExt = Utils.checkFileExt(file.path);
// document!.data![index].documentUrl = file.path;
// setState(ViewState.idle);
// }
// } else {
// // User canceled the picker
// }
if (file != null) {
int sizeInBytes = file.lengthSync();
// double sizeInMb = sizeInBytes / (1024 * 1024);
if (sizeInBytes > 1000) {
Utils.showToast("File is larger then 1KB");
} else {
document!.data![index].document = Utils.convertFileToBase64(file);
document!.data![index].fileExt = Utils.checkFileExt(file.path);
document!.data![index].documentUrl = file.path;
setState(ViewState.idle);
}
} else {
// User canceled the picker
}
}
Future<MResponse> updateDocument(List<DocumentData>? data) async {
return await branchRepo.serviceProviderDocumentsUpdate(data);
}
// Create new branch
Future<void> getBranchAndServices() async {
setState(ViewState.busy);
branches = await branchRepo.getBranchAndServices();
setState(ViewState.idle);
}
Future<void> getAllCountriesList(
BranchDetailModel? branchData, String countryCode) async {
cities = null;
country = null;
setState(ViewState.busy);
resetValues();
country = await commonRepo.getAllCountries();
country!.data?.forEach((element) {
if (branchData != null && branchData.id != null) {
if (element.id == branchData.countryID) {
countryId = element.id ?? -1;
countryValue = DropValue(
element.id ?? 0,
countryCode == "SA"
? (element.countryNameN ?? "")
: (element.countryName ?? ""),
element.countryCode ?? "",
);
}
}
countryDropList.add(
DropValue(
element.id ?? 0,
countryCode == "SA"
? (element.countryNameN ?? "")
: (element.countryName ?? ""),
element.countryCode ?? "",
),
);
});
if (branchData != null && branchData.id != null) {
await getAllCities(branchData, countryCode);
}
setState(ViewState.idle);
}
Future<void> getAllCities(
BranchDetailModel? branchData, String countryCode) async {
setState(ViewState.busy);
citiesDropList = [];
cities = null;
cityId = -1;
cityValue = null;
cities = await commonRepo.getAllCites(countryId.toString());
cities!.data?.forEach((element) {
if (branchData != null && branchData.id != null) {
if (element.id == branchData.cityId) {
address = branchData.address!;
branchName = branchData.branchName!;
branchDescription = branchData.branchDescription!;
latitude = double.parse(branchData.latitude ?? "");
longitude = double.parse(branchData.longitude ?? "");
countryId = branchData.countryID!;
cityId = branchData.cityId!;
cityValue = DropValue(
element.id ?? 0,
countryCode == "SA"
? (element.cityNameN ?? "")
: (element.cityName ?? ""),
element.id.toString() ?? "",
);
}
}
citiesDropList.add(
DropValue(
element.id ?? 0,
countryCode == "SA"
? (element.cityNameN ?? "")
: (element.cityName ?? ""),
element.id.toString() ?? "",
),
);
});
setState(ViewState.idle);
}
Future<MResponse> createBranch(String branchName, String branchDescription,
String cityId, String address, String latitude, String longitude) async {
return await branchRepo.createBranch(branchName, branchDescription,
cityId.toString(), address, latitude.toString(), longitude.toString());
}
Future<MResponse> updateBranch(
int id,
String branchName,
String branchDescription,
String cityId,
String address,
String latitude,
String longitude, {
bool isNeedToDelete = true,
}) async {
return await branchRepo.updateBranch(
id ?? 0,
branchName,
branchDescription,
cityId.toString(),
address,
latitude.toString(),
longitude.toString(),
);
}
void resetValues() {
countryCode = "";
address = "";
branchName = "";
branchDescription = "";
latitude = 0;
longitude = 0;
role = -1;
countryId = -1;
cityId = -1;
countryDropList.clear();
countryId = -1;
cityId = -1;
cities = null;
categoryDropList = [];
servicesDropList = [];
services = null;
}
// Create Services
Services? services;
List<DropValue> categoryDropList = [];
List<DropValue> servicesDropList = [];
Future<void> fetchBranchCategory(String countryCode) async {
categoryDropList.clear();
servicesDropList = [];
services = null;
setOnlyState(ViewState.busy);
Category? category = await branchRepo.fetchBranchCategory();
category.data?.forEach((element) {
categoryDropList.add(
DropValue(
element.id ?? 0,
((element.categoryName!.isEmpty
? "N/A"
: countryCode == "SA"
? element.categoryNameN
: element.categoryName) ??
"N/A"),
"",
),
);
});
setState(ViewState.idle);
}
Future<void> fetchServicesByCategoryId(String categoryId) async {
servicesDropList = [];
setState(ViewState.busy);
services = await branchRepo.fetchServicesByCategoryId(categoryId);
for (var element in services!.data!) {
servicesDropList.add(
DropValue(
element.id ?? 0,
element.description ?? "N/A",
"",
),
);
}
setState(ViewState.idle);
}
Future<void> fetchProviderServices(String branchID, String categoryId) async {
servicesDropList = [];
services = null;
setState(ViewState.busy);
services = await branchRepo.fetchProviderServices(branchID, categoryId);
for (var element in services!.data!) {
servicesDropList.add(
DropValue(
element.id ?? 0,
element.description ?? "N/A",
"",
),
);
}
setState(ViewState.idle);
}
Future<MResponse> createService(List<Map<String, dynamic>> map) async {
return await branchRepo.createService(map);
}
Future<MResponse> updateServices(List<Map<String, dynamic>> map) async {
return await branchRepo.updateService(map);
}
void updateSelectedBranchType(int status) {
selectedBranchStatus = status;
notifyListeners();
}
List<ServiceModel>? matchedServices;
bool isAllSelected = false;
Future<void> getAllMatchedServices(
int oldBranchId, int newBranchId, int categoryId) async {
matchedServices = null;
final MResponse response = await branchRepo.getMatchedServices(
oldBranchId, newBranchId, categoryId);
matchedServices = [];
if (response.messageStatus == 1) {
matchedServices = List<ServiceModel>.from(
response.data.map((x) => ServiceModel.fromJson(x)));
}
notifyListeners();
}
void selectAllServices(bool value) {
for (var element in matchedServices!) {
element.isExpandedOrSelected = value;
for (var item in element.serviceItems!) {
item.isUpdateOrSelected = value;
}
}
isAllSelected = value;
notifyListeners();
}
void updateServiceItem(int serviceIndex, bool value) {
for (var element in matchedServices![serviceIndex].serviceItems!) {
element.isUpdateOrSelected = value;
}
notifyListeners();
}
void copyItems(int index, List<ItemData> copiedItems) {
matchedServices![index].serviceItems = copiedItems;
notifyListeners();
}
Future<MResponse> duplicateItems(Map<String, dynamic> map) async {
return await branchRepo.duplicateItems(map);
}
// Branch Users
List<BranchUser> allProviderDealersList = [];
List<BranchUser> branchUserList = [];
getAllProviderDealers(Map<String, dynamic> map) async {
setState(ViewState.busy);
MResponse response = await branchRepo.getAllProviderDealers(map);
if (response.messageStatus == 1) {
allProviderDealersList = [];
allProviderDealersList = List<BranchUser>.from(
response.data.map((x) => BranchUser.fromJson(x)));
}
setState(ViewState.idle);
}
Future<void> getBranchUsers(Map<String, dynamic> map) async {
setState(ViewState.busy);
MResponse response = await branchRepo.getBranchUsers(map);
if (response.messageStatus == 1) {
branchUserList = [];
branchUserList = List<BranchUser>.from(
response.data.map((x) => BranchUser.fromJson(x)));
}
setState(ViewState.idle);
}
Future<MResponse> assignDealerToBranch(Map<String, dynamic> map) async {
MResponse response = await branchRepo.assignDealerToBranch(map);
return response;
}
Future<MResponse> removeDealerFromBranch(Map<String, dynamic> map) async {
MResponse response = await branchRepo.removeDealerFromBranch(map);
return response;
}
Future<MResponse> addNewServiceInAppointment(Map<String, dynamic> map) async {
MResponse response = await branchRepo.addNewServicesInAppointment(map);
return response;
}
}

@ -0,0 +1,286 @@
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/appoinments/widget/select_items_sheet.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/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/models/general_models/m_response.dart';
import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.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/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
import '../../generated/locale_keys.g.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import '../settings/schedule/widgets/chips_picker_item.dart';
class AddNewServiceAppointmentPage extends StatelessWidget {
AppointmentListModel appointmentListModel;
AddNewServiceAppointmentPage(this.appointmentListModel, {Key? key})
: super(key: key);
DropValue? category;
DropValue? service;
List<ItemData> selectedList = [];
List<PickerItem>? pickedItems;
@override
Widget build(BuildContext context) {
ServiceVM serviceVM = context.read<ServiceVM>();
serviceVM.fetchBranchCategory(
EasyLocalization.of(context)?.currentLocale?.countryCode ?? "SA");
return Scaffold(
appBar: const CustomAppBar(
title: "Add Service",
),
body: Padding(
padding: const EdgeInsets.all(21.0),
child: Column(
children: [
AppointmentSliderWidget(
appointmentListModel: appointmentListModel,
isNeedTotalPayment: true,
isNeedToShowItems: true,
isNeedToShowToMoreText: false,
onTap: () {},
),
12.height,
Expanded(
child: Consumer<ServiceVM>(
builder: (context, model, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Select services you want to add".toText(
fontSize: 18,
isBold: true,
),
12.height,
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
model.categoryDropList.isNotEmpty
? DropdownField(
(DropValue value) async {
category = value;
service = null;
model.fetchProviderServices(
appointmentListModel.branchId
.toString(),
value.id.toString());
},
dropdownValue: category,
list: model.categoryDropList,
hint:
LocaleKeys.selectServiceCategory.tr(),
)
: const Center(
child: CircularProgressIndicator(),
),
12.height,
model.servicesDropList.isNotEmpty
? DropdownField(
(DropValue value) {
service = value;
pickedItems = null;
model.setState(ViewState.idle);
showMyBottomSheet(
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
onSelectItems:
(List<ItemData> selectedList) {
this.selectedList.clear();
this.selectedList = selectedList;
pickedItems = [];
for (var element
in selectedList) {
pickedItems!.add(
PickerItem(
id: element.id ?? 0,
title:
element.name ?? ""),
);
}
model.notifyListeners();
},
),
);
},
dropdownValue: service,
list: model.servicesDropList,
hint: LocaleKeys.defineServices.tr(),
)
: category == null
? Container()
: model.services != null &&
model.servicesDropList.isEmpty
? const Text("No Service Found")
: const CircularProgressIndicator(),
12.height,
(service != null &&
pickedItems != null &&
pickedItems!.length > 0)
? ChipsPickerItem(
hint: 'Select Items',
itemsList: [...pickedItems ?? []],
onClick: () {
showMyBottomSheet(
context,
child: SelectItemsSheet(
serviceId: service?.id ?? 0,
list: pickedItems,
onSelectItems:
(List<ItemData> selectedList) {
pickedItems = [];
for (var element
in selectedList) {
pickedItems!.add(
PickerItem(
id: element.id ?? 0,
title:
element.name ?? ""),
);
}
model.notifyListeners();
},
),
);
},
)
: service != null
? const Text("No Item Selected Yet")
: const SizedBox(),
if ((service != null &&
pickedItems != null &&
pickedItems!.length > 0))
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
16.height,
"Total Additional Amount".toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor,
),
Row(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
calculatePrice().toString().toText(
fontSize: 29,
isBold: true,
),
2.width,
"SAR".toText(
fontSize: 16,
isBold: true,
color: MyColors.lightTextColor,
),
],
),
],
),
],
),
],
).toWhiteContainer(width: double.infinity, allPading: 12),
Row(
children: [
Expanded(
child: ShowFillButton(
title: "Cancel",
maxWidth: double.infinity,
isFilled: false,
txtColor: MyColors.redColor,
borderColor: MyColors.redColor,
onPressed: () {},
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "Add",
maxWidth: double.infinity,
onPressed: () async {
if (pickedItems != null &&
pickedItems!.length > 0) {
List<int> items = [];
pickedItems?.forEach((element) {
items.add(element.id);
});
Utils.showLoading(context);
var postParams = {
"providerBranchID":
appointmentListModel.branchId,
"appointmentID": appointmentListModel.id,
"serviceItemID": items
};
MResponse res = await serviceVM
.addNewServiceInAppointment(postParams);
_updateAppointment(context,
appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
if (res.messageStatus == 1) {
Utils.showToast(
"Items are added Successfully");
pop(context);
} else {
Utils.showToast(res.message.toString());
}
} else {
Utils.showToast("Please select items");
}
},
),
),
],
),
],
);
},
),
),
],
),
),
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
double calculatePrice() {
double total = 0;
for (var element in selectedList) {
total = total + double.parse(element.price ?? "0");
}
return total;
}
}

@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import '../../config/provider_routes.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import 'package:provider/provider.dart';
class AppointmentDetailListPage extends StatelessWidget {
AppointmentDetailListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Appointment Detail",
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![index],
isNeedTotalPayment: true,
isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: true,
onTap: () {
appointmentsVM.selectedAppointmentId =
appointmentsVM
.myFilteredAppointments2[appointmentsVM
.selectedAppointmentIndex]
.customerAppointmentList![index]
.id ??
0;
appointmentsVM.selectedAppointmentSubIndex = index;
navigateWithName(context,
ProviderAppRoutes.updateAppointmentPage,
arguments: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![index]);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!
.length,
padding: const EdgeInsets.all(21),
);
}
}),
),
ShowFillButton(
title: "Merge Appointments",
maxWidth: double.infinity,
margin: const EdgeInsets.all(21),
onPressed: () {
navigateWithName(
context, ProviderAppRoutes.mergeAppointments);
},
),
],
)),
);
}
}

@ -0,0 +1,273 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/appointment_slider_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.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/widgets/common_widgets/app_bar.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:provider/provider.dart';
class AppointmentPage extends StatelessWidget {
BranchDetailModel branch;
String date = "";
AppointmentPage({
required this.branch,
Key? key,
}) : super(key: key);
GlobalKey<RefreshIndicatorState> refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async {
await context.read<AppointmentsVM>().getAppointmentSlotsInfo(
context: context,
map: {
"ProviderBranchID": branch.id.toString(),
"FromDate": date,
"ToDate": date
},
isNeedToRebuild: true,
);
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branch.id.toString(),
"FromDate": date,
"DateTo": date,
});
}
@override
Widget build(BuildContext context) {
date = DateHelper.formatAsYearMonthDay(DateTime.now());
context.read<AppointmentsVM>().setupProviderAppointmentFilter();
_pullRefresh(context);
context.read<AppointmentsVM>().selectedBranch = branch.id ?? 0;
return Scaffold(
appBar: CustomAppBar(
profileImageUrl: MyAssets.carBanner,
title: branch.branchName,
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
progressWidget(context, appointmentsVM),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(
appointmentStatusEnum:
selectedFilterId.toAppointmentStatusEnum(),
isNeedCustomerFilter: true,
);
},
),
if (appointmentsVM.myFilteredAppointments2.isEmpty)
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: "No Appointment Found".toText(),
),
ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel:
appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
context
.read<AppointmentsVM>()
.selectedAppointmentIndex = index;
navigateWithName(
context,
ProviderAppRoutes.appointmentDetailList,
// arguments: appointmentsVM
// .myFilteredAppointments2[index]
// .customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
],
),
),
);
}
}),
),
);
}
Widget progressWidget(BuildContext context, AppointmentsVM appointmentsVM) {
double percent = (appointmentsVM.appointmentSlots?.occupiedSlots ??
0.0 / (appointmentsVM.appointmentSlots?.totalSlots ?? 0.0))
.toDouble() *
100;
return Column(
children: [
Row(
children: [
Expanded(
child: "Slots Overview".toText(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
date.toText(
fontWeight: FontWeight.bold,
),
const Icon(
Icons.keyboard_arrow_down_outlined,
size: 16,
),
],
)
.toContainer(
backgroundColor: MyColors.lightGreyEAColor,
borderRadius: 100,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
)
.onPress(() async {
date = await Utils.pickDateFromDatePicker(
context,
firstDate: null,
);
_pullRefresh(context);
// context.read<AppointmentsVM>().notifyListeners();
}),
],
),
24.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.lightGreyEAColor,
),
4.width,
"Empty: ".toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.emptySlots ?? 0)
.toString()
.toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
8.height,
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.darkPrimaryColor,
),
4.width,
"Occupied: ".toText(
fontSize: 8,
color: Colors.white,
),
(appointmentsVM.appointmentSlots?.occupiedSlots ?? 0)
.toString()
.toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
],
),
CircularPercentIndicator(
radius: 60.0,
lineWidth: 12.0,
percent: percent,
circularStrokeCap: CircularStrokeCap.round,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"Total Slots".toText(
fontSize: 13,
fontWeight: FontWeight.bold,
),
(appointmentsVM.appointmentSlots?.totalSlots ?? 0)
.toString()
.toText(
fontSize: 24,
fontWeight: FontWeight.bold,
),
],
),
backgroundColor: MyColors.lightGreyEAColor,
progressColor: MyColors.darkPrimaryColor,
),
],
)
],
).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
margin: const EdgeInsets.all(21),
);
}
}

@ -0,0 +1,159 @@
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/extensions/int_extensions.dart';
import 'package:mc_common_app/models/general_models/m_response.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import '../../config/provider_routes.dart';
import '../dashboard/widget/appointment_slider_widget.dart';
import 'package:provider/provider.dart';
class MergeAppointmentListPage extends StatelessWidget {
MergeAppointmentListPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Select Appointments",
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
return Column(
children: [
Expanded(
child: Column(
children: [
Expanded(
child: (appointmentsVM.state == ViewState.busy)
? const Center(child: CircularProgressIndicator())
: ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel: appointmentsVM
.myFilteredAppointments2[appointmentsVM
.selectedAppointmentIndex]
.customerAppointmentList![index],
isNeedTotalPayment: true,
isSelectable: true,
isNeedToShowAppointmentStatus: true,
isNeedToShowMergeStatus: true,
onTap: () {
appointmentsVM
.updateCheckBoxInMergeRequest(index);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!
.length,
padding: const EdgeInsets.all(21),
),
),
],
),
),
ShowFillButton(
title: "Merge Appointments",
maxWidth: double.infinity,
margin: const EdgeInsets.all(21),
txtColor: appointmentsVM.inNeedToEnableMergeButton
? MyColors.white
: MyColors.black,
backgroundColor: appointmentsVM.inNeedToEnableMergeButton
? MyColors.primaryColor
: MyColors.greyButtonColor,
onPressed: () async {
Utils.showLoading(context);
List<int> appointmentIDs = [];
for (var element in appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList!) {
if (element.isSelected ?? false) {
appointmentIDs.add(element.id ?? 0);
}
}
Map<String, dynamic> map = {
"serviceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"serviceProviderBranchID": appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.branchId,
"serviceAppointmentIDs": appointmentIDs
};
try {
MResponse response =
await appointmentsVM.createMergeAppointment(map);
Utils.hideLoading(context);
if (response.messageStatus == 1) {
Utils.showToast(
"Appointment Merge is Successfully done");
_updateAppointment(
context,
appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.branchId ??
0);
pop(context);
pop(context);
} else {
Utils.showToast(response.message.toString());
}
} catch (e) {
Utils.showToast(e.toString());
Utils.hideLoading(context);
}
},
),
],
);
},
),
),
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
}

@ -0,0 +1,327 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/appoinments/widget/appointment_detail_list_widget.dart';
import 'package:car_provider_app/views/appoinments/widget/sheets.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/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/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.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';
import '../dashboard/widget/appointment_slider_widget.dart';
class UpdateAppointmentPage extends StatelessWidget {
late AppointmentListModel appointmentListModel;
UpdateAppointmentPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Update Appointment",
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
appointmentListModel = appointmentsVM
.myFilteredAppointments2[
appointmentsVM.selectedAppointmentIndex]
.customerAppointmentList![
appointmentsVM.selectedAppointmentSubIndex];
if (appointmentsVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(21),
children: [
AppointmentSliderWidget(
appointmentListModel: appointmentListModel,
isNeedTotalPayment: true,
isNeedToShowItems: true,
isNeedToShowToMoreText: false,
onTap: () {},
),
21.height,
ShowFillButton(
title: "+ Add New Service",
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
onPressed: () {
navigateWithName(
context,
ProviderAppRoutes.addServiceInAppointment,
arguments: appointmentListModel,
);
},
),
],
),
),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.cancelled)
"Appointment is Canceled".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.booked)
Column(
children: [
showPayNowButton(context, appointmentsVM),
12.height,
showCancelButton(context, appointmentsVM),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.confirmed &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.defaultStatus)
Column(
children: [
showArrivedutton(context, appointmentsVM),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.defaultStatus)
Column(
children: [
showPayNowButton(context, appointmentsVM),
12.height,
showPayLaterButton(context, appointmentsVM),
],
).paddingAll(21),
if ((appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived ||
appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted) &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payNow)
"Waiting for the payment from the customer"
.toText()
.paddingAll(21),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.arrived &&
(appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.paid ||
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payLater))
Column(
children: [
showWorkStartButton(context, appointmentsVM),
],
).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payPartial)
Column(
children: [
showPayLaterButton(context, appointmentsVM),
12.height,
showPayNowButton(context, appointmentsVM),
],
).paddingAll(21),
// "Show Pay Now".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.paid)
Column(
children: [
showCompleteButton(context, appointmentsVM),
],
).paddingAll(21),
// "Show Complete Button".toText(),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.workStarted &&
appointmentListModel.appointmentPaymentStatusEnum ==
AppointmentPaymentStatusEnum.payLater)
showPayNowButton(context, appointmentsVM).paddingAll(21),
if (appointmentListModel.appointmentStatusEnum ==
AppointmentStatusEnum.visitCompleted)
"Appointment is completed".toText().paddingAll(21),
// Padding(
// padding: const EdgeInsets.all(21.0),
// child: Column(
// children: [
// ShowFillButton(
// title: "Confirm Arrive",
// maxWidth: double.infinity,
// onPressed: () {
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
// },
// ),
// 12.height,
// ShowFillButton(
// title: "Cancel Appointment",
// maxWidth: double.infinity,
// isFilled: false,
// txtColor: MyColors.redColor,
// borderColor: MyColors.redColor,
// onPressed: () {
// showMyBottomSheet(context,
// child: CancelAppointmentReasonSheet(
// onCancelClick: (String reason) {},
// ));
// },
// ),
// ],
// ),
// ),
],
);
}
})),
);
}
Widget showWorkStartButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Work Start",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 7
});
Utils.hideLoading(context);
// showMyBottomSheet(
// context,
// child: ShowCollectPaymentSheet(
// onClickYes: () {},
// onClickNo: () {},
// ),
// );
},
);
}
Widget showPayNowButton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Pay Now",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentPaymentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentServicePaymentStatusID": 2
});
_updateAppointment(context, appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
},
);
}
Widget showArrivedutton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Arrived",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 3
});
_updateAppointment(context, appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
},
);
}
Widget showPayLaterButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Pay Later",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentPaymentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentServicePaymentStatusID": 4
});
_updateAppointment(context, appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
},
);
}
Widget showCompleteButton(
BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Complete",
maxWidth: double.infinity,
onPressed: () async {
Utils.showLoading(context);
await appointmentsVM.updateAppointmentStatus({
"appointmentID": appointmentListModel.id.toString(),
"appointmentStatusID": 8
});
_updateAppointment(context, appointmentListModel.branchId ?? 0);
Utils.hideLoading(context);
},
);
}
Widget showCancelButton(BuildContext context, AppointmentsVM appointmentsVM) {
return ShowFillButton(
title: "Cancel",
maxWidth: double.infinity,
isFilled: false,
txtColor: MyColors.redColor,
borderColor: MyColors.redColor,
onPressed: () {
showMyBottomSheet(
context,
child: ShowCollectPaymentSheet(
onClickYes: () {},
onClickNo: () {},
),
);
},
);
}
Future<void> _updateAppointment(BuildContext context, int branchId) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0",
"ProviderBranchID": branchId.toString(),
}, isNeedToRebuild: true);
}
}

@ -0,0 +1,106 @@
import 'package:car_provider_app/config/provider_routes.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/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:sizer/sizer.dart';
import 'package:flutter_svg/flutter_svg.dart';
class AppointmentDetailListWidget extends StatelessWidget {
bool isNeedClick;
AppointmentDetailListWidget({Key? key, this.isNeedClick = true}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"Olaya Brach".toText(
fontSize: 12,
color: MyColors.darkTextColor,
isBold: true,
),
"Abdullah Alhbas".toText(
fontSize: 14,
isBold: true,
),
Row(
children: [
"Appt. On:".toText(
color: MyColors.lightTextColor,
),
2.width,
"19-Mar-2023 11:48 AM".toText(),
],
),
],
),
),
SvgPicture.asset(
MyAssets.icEdit,
color: Colors.black,
width: 20,
height: 20,
)
],
),
8.height,
showServices("Maintenance"),
2.height,
showServices("Accessories and Modification"),
24.height,
"Total Amount".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"30,000".toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
onTap: () {
if (isNeedClick) navigateWithName(context, ProviderAppRoutes.updateAppointmentPage);
},
);
}
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,
),
],
);
}
}

@ -0,0 +1,144 @@
import 'package:car_provider_app/view_models/items_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/models/services_models/item_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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:provider/provider.dart';
import '../../settings/schedule/widgets/chips_picker_item.dart';
class SelectItemsSheet extends StatelessWidget {
int serviceId;
Function(List<ItemData>) onSelectItems;
List<PickerItem>? list;
SelectItemsSheet(
{Key? key,
required this.serviceId,
required this.onSelectItems,
this.list})
: super(key: key);
@override
Widget build(BuildContext context) {
context.read<ItemsVM>().getServiceItems(serviceId,list: list);
return SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height / 1.4,
child: Column(
children: [
Expanded(
child: Consumer<ItemsVM>(
builder: (_, model, child) {
return Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 6),
child: Column(
children: [
Row(
children: [
Expanded(
child: "Select Items"
.toText(fontSize: 24, isBold: true),
),
Center(
child: (model.serviceItems == null
? "0"
: model.serviceItems!.data!
.where((element) =>
element.isUpdateOrSelected == true)
.toList()
.length
.toString())
.toText(
fontSize: 10,
isBold: true,
color: Colors.white,
),
).toContainer(
borderRadius: 100,
width: 24,
height: 24,
paddingAll: 0,
backgroundColor: MyColors.darkPrimaryColor,
),
],
),
12.height,
TxtField(
hint: "Search Items",
onChanged: (v) {},
),
12.height,
Expanded(
child: model.serviceItems?.data == null
? const Center(child: CircularProgressIndicator())
: model.serviceItems?.data!.length == 0
? Center(child: "No Item Found".toText())
: ListView.separated(
itemBuilder:
(BuildContext context, int index) {
return Row(
children: [
Checkbox(
value: model
.serviceItems!
.data![index]
.isUpdateOrSelected,
onChanged: (bool? v) {
model.serviceItems!.data![index]
.isUpdateOrSelected = v;
model.notifyListeners();
},
),
12.width,
Expanded(
child: model.serviceItems!
.data![index].name!
.toText(),
),
],
);
},
separatorBuilder:
(BuildContext context, int index) {
return const Divider(
height: 1,
);
},
itemCount:
model.serviceItems?.data?.length ?? 0,
),
),
],
),
);
},
),
),
ShowFillButton(
title: 'Add Selected Items',
maxWidth: double.infinity,
margin: const EdgeInsets.all(20),
onPressed: () {
if (context.read<ItemsVM>().serviceItems != null) {
List<ItemData> list = [];
context.read<ItemsVM>().serviceItems!.data!.forEach((element) {
if (element.isUpdateOrSelected ?? false) {
list.add(element);
}
});
onSelectItems(list);
}
Navigator.pop(context);
},
)
],
),
);
}
}

@ -0,0 +1,185 @@
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/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
class ShowCollectPaymentSheet extends StatelessWidget {
Function() onClickYes;
Function() onClickNo;
ShowCollectPaymentSheet(
{required this.onClickYes, required this.onClickNo, Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 12),
child: Column(
children: [
"Do you want to collect the money before providing services?".toText(
fontSize: 24,
isBold: true,
),
21.height,
Row(
children: [
Expanded(
child: ShowFillButton(
title: "Yes",
onPressed: onClickYes,
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "No",
isFilled: false,
txtColor: MyColors.darkPrimaryColor,
onPressed: onClickNo,
),
),
],
),
],
),
);
}
}
class Reason {
String title;
bool isSelected;
Reason(this.title, this.isSelected);
}
class CancelAppointmentReasonSheet extends StatefulWidget {
Function(String) onCancelClick;
CancelAppointmentReasonSheet({required this.onCancelClick, Key? key})
: super(key: key);
@override
State<CancelAppointmentReasonSheet> createState() =>
_CancelAppointmentReasonSheetState();
}
class _CancelAppointmentReasonSheetState
extends State<CancelAppointmentReasonSheet> {
String reason = "";
List<Reason> reasonList = [
Reason("Operational Issue", true),
Reason("Material Issue", false),
Reason("The customer no longer responding", false),
Reason("Other", false),
];
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 12, bottom: 21),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Reason".toText(fontSize: 24, isBold: true),
ListView.separated(
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(top: 12, bottom: 12),
child: Row(
children: [
Container(
width: 14,
height: 14,
decoration: BoxDecoration(
color: reasonList[index].isSelected
? MyColors.darkPrimaryColor
: Colors.transparent,
borderRadius: BorderRadius.circular(122),
border: Border.all(
color: reasonList[index].isSelected
? MyColors.darkPrimaryColor
: borderColor,
width: 1),
),
child: const Icon(
Icons.done,
size: 12,
color: Colors.white,
),
),
12.width,
reasonList[index].title.toText(isBold: true)
],
),
).onPress(() {
for (var element in reasonList) {
element.isSelected = false;
}
setState(() {
reason = reasonList[index].title;
reasonList[index].isSelected = true;
});
});
},
separatorBuilder: (context, index) {
return Container(
width: double.infinity,
height: 1,
color: MyColors.borderColor,
);
},
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: reasonList.length,
),
if (reason == "Other")
TxtField(
hint: "Type Here...",
maxLines: 5,
onChanged: (v) {
reason = v;
},
),
12.height,
Row(
children: [
Expanded(
child: ShowFillButton(
title: "No",
isFilled: false,
txtColor: MyColors.darkPrimaryColor,
onPressed: () {
pop(context);
},
),
),
12.width,
Expanded(
child: ShowFillButton(
title: "Yes",
onPressed: () {
if (reason.isEmpty || reason == "Other") {
Utils.showToast("Please Select Reason");
} else {
widget.onCancelClick(reason);
pop(context);
}
},
),
),
],
)
],
),
);
}
}

@ -0,0 +1,152 @@
import 'dart:async';
import 'package:badges/badges.dart' as b;
import 'package:car_provider_app/view_models/dashboard_view_model.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/dashboard/fragments/ads_fragment.dart';
import 'package:car_provider_app/views/dashboard/fragments/appoinment_fragment.dart';
import 'package:car_provider_app/views/dashboard/fragments/my_requests_fragment.dart';
import 'package:car_provider_app/views/dashboard/widget/drawer_widget.dart';
import 'package:car_provider_app/views/settings/branch/branch_list_page.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/int_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/ad_view_model.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/requests_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/bottom_nav_bar.dart';
import 'package:provider/provider.dart';
import 'fragments/branch_appointment_fragment.dart';
import 'fragments/home_fragment.dart';
class DashboardPage extends StatefulWidget {
const DashboardPage({Key? key}) : super(key: key);
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
late DashboardVM dashboardVM;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
dashboardVM = Provider.of<DashboardVM>(context, listen: false);
context.read<RequestsVM>().populateRequestsFilterList();
_onRefresh();
}
Future<void> _onRefresh() async {
final requestsVM = context.read<RequestsVM>();
final chatVM = context.read<ChatVM>();
// context.read<AdVM>().populateAdsFilterList();
context.read<ServiceVM>().getBranchAndServices();
AdVM adVm = Provider.of<AdVM>(context, listen: false);
AppointmentsVM appointmentsVM =
Provider.of<AppointmentsVM>(context, listen: false);
if (appointmentsVM.myAppointments.isEmpty) {
await appointmentsVM.getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0"
});
}
adVm.populateAdsFilterList();
if (adVm.myAds.isEmpty) {
await adVm.getMyAds();
}
if (adVm.exploreAds.isEmpty) {
await adVm.getExploreAds();
}
if (adVm.vehicleTypes.isEmpty) {
await adVm.getVehicleTypes();
}
if (adVm.vehicleAdsDurations.isEmpty) {
await adVm.getVehicleAdsDuration();
}
if (requestsVM.myRequests.isEmpty) {
await requestsVM.getRequests(appType: AppType.provider);
}
// await chatVM.buildHubConnection(context);
}
@override
Widget build(BuildContext context) {
List<Widget> fragments = [
BranchListPage(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},
onRefresh: () async {
context.read<ServiceVM>().getBranchAndServices();
},
),
BranchAppointmentFragment(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},
onRefresh: () async {
context.read<ServiceVM>().getBranchAndServices();
},
),
HomeFragment(
onTap: () {
_scaffoldKey.currentState!.openDrawer();
},
onRefresh: () async {
_onRefresh();
},
onNotificaitonClick: () {
_onRefresh();
},
),
AdsFragment(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},
),
MyRequestsFragment(
onBackButtonTapped: () {
dashboardVM.updateIndex(2);
},
),
];
return Scaffold(
key: _scaffoldKey,
drawer: CustomDrawer(dashboardVM: dashboardVM),
// body: Consumer<DashboardVM>(builder: (context, model, _) {
// return fragments[dashboardVM.selectedNavbarBarIndex];
// }),
body: fragments[context.watch<DashboardVM>().selectedNavbarBarIndex],
bottomNavigationBar: CustomBottomNavbar(
onSelected: (i) {
dashboardVM.updateIndex(i);
},
isProvider: true,
selectedNavbarBarIndex: dashboardVM.selectedNavbarBarIndex,
),
);
}
}

@ -0,0 +1,135 @@
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';
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/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
class AdsFragment extends StatelessWidget {
bool isNeedAppBar;
VoidCallback onBackButtonTapped;
AdsFragment({Key? key, this.isNeedAppBar = true, required this.onBackButtonTapped}) : super(key: key);
Future<void> onRefreshAds(BuildContext context) async {
AdVM adVM = context.read<AdVM>();
await adVM.getExploreAds();
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(
appBar: !isNeedAppBar
? null
: CustomAppBar(
title: "Ads",
onBackButtonTapped: onBackButtonTapped,
),
body: Container(
color: MyColors.backgroundColor,
width: double.infinity,
height: double.infinity,
child: Column(
children: [
16.height,
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return Column(
children: [
Row(
children: [
Expanded(
child: ShowFillButton(
isFilled: adVM.isExploreAdsTapped,
maxHeight: 55,
title: "Explore Ads",
txtColor: adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
onPressed: () {
print("ads: ${AppState().getUser.data!.accessToken}");
adVM.updateIsExploreAds(true);
},
),
),
12.width,
Expanded(
child: ShowFillButton(
isFilled: !adVM.isExploreAdsTapped,
txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor,
maxHeight: 55,
title: "My Ads",
onPressed: () {
adVM.updateIsExploreAds(false);
},
),
),
],
).horPaddingMain(),
if (adVM.isExploreAdsTapped) ...[
16.height,
FiltersList(
filterList: adVM.exploreAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()),
needLeftPadding: false)
.paddingOnly(left: 21),
],
if (!adVM.isExploreAdsTapped) ...[
16.height,
FiltersList(
filterList: adVM.myAdsFilterOptions,
onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum()),
needLeftPadding: false,
).paddingOnly(left: 21),
],
],
);
},
),
16.height,
Expanded(
child: RefreshIndicator(
onRefresh: () => onRefreshAds(context),
child: Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
return BuildAdsList(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM));
},
),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
navigateWithName(context, AppRoutes.selectAdTypeView, arguments: injector.get<AppState>().currentAppType == AppType.provider);
},
backgroundColor: MyColors.darkPrimaryColor,
child: Icon(
Icons.add,
color: MyColors.white,
),
),
);
}
}

@ -0,0 +1,242 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/views/dashboard/widget/appointment_slider_widget.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/date_helper.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/tab/menu_tabs.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/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:provider/provider.dart';
class AppointmentFragment extends StatelessWidget {
String date = "";
VoidCallback onBackButtonTapped;
AppointmentFragment({Key? key, required this.onBackButtonTapped})
: super(key: key);
GlobalKey<RefreshIndicatorState> refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
Future<void> _pullRefresh(BuildContext context) async {
await context.read<AppointmentsVM>().getProviderMyAppointments({
"ServiceProviderID": injector
.get<AppState>()
.getUser
.data
?.userInfo
?.providerId
.toString() ??
"0"
});
}
@override
Widget build(BuildContext context) {
context.read<AppointmentsVM>().setupProviderAppointmentFilter();
date = DateHelper.formatAsDayMonthYear(DateTime.now());
return Scaffold(
appBar: CustomAppBar(
profileImageUrl: MyAssets.carBanner,
title: "Appointments",
onBackButtonTapped: onBackButtonTapped,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.search),
),
10.width,
],
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Consumer(builder: (BuildContext context,
AppointmentsVM appointmentsVM, Widget? child) {
return RefreshIndicator(
onRefresh: () => _pullRefresh(context),
key: refreshIndicatorKey,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
progressWidget(context),
FiltersList(
filterList: appointmentsVM.appointmentsFilterOptions,
padding: const EdgeInsets.symmetric(horizontal: 18),
onFilterTapped: (index, selectedFilterId) {
appointmentsVM.applyFilterOnAppointmentsVM(
appointmentStatusEnum:
selectedFilterId.toAppointmentStatusEnum(),
);
},
),
ListView.separated(
itemBuilder: (context, index) {
return AppointmentSliderWidget(
appointmentListModel:
appointmentsVM.myFilteredAppointments2[index],
isNeedTotalPayment: false,
onTap: () {
navigateWithName(
context,
ProviderAppRoutes.appointmentDetailList,
arguments: appointmentsVM
.myFilteredAppointments2[index]
.customerAppointmentList,
);
},
);
},
separatorBuilder: (context, snapchat) {
return 21.height;
},
itemCount: appointmentsVM.myFilteredAppointments2.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(21),
),
],
),
),
);
}),
),
);
}
Widget progressWidget(BuildContext context) {
return Column(
children: [
Row(
children: [
Expanded(
child: "Slots Overview".toText(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
date.toText(
fontWeight: FontWeight.bold,
),
const Icon(
Icons.keyboard_arrow_down_outlined,
size: 16,
),
],
)
.toContainer(
backgroundColor: MyColors.lightGreyEAColor,
borderRadius: 100,
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 6,
),
)
.onPress(() async {
date = await Utils.pickDateFromDatePicker(
context,
firstDate: null,
);
context.read<AppointmentsVM>().notifyListeners();
}),
],
),
24.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.lightGreyEAColor,
),
4.width,
"Empty: ".toText(
fontSize: 8,
color: Colors.white,
),
"8".toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
8.height,
Row(
children: [
Container(
width: 14,
height: 14,
color: MyColors.darkPrimaryColor,
),
4.width,
"Occupied: ".toText(
fontSize: 8,
color: Colors.white,
),
"54".toText(
fontSize: 9,
fontWeight: FontWeight.bold,
color: Colors.white,
),
],
).toContainer(
backgroundColor: MyColors.darkIconColor,
),
],
),
CircularPercentIndicator(
radius: 60.0,
lineWidth: 12.0,
percent: 0.7,
circularStrokeCap: CircularStrokeCap.round,
center: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
"Total Slots".toText(
fontSize: 13,
fontWeight: FontWeight.bold,
),
"24".toText(
fontSize: 24,
fontWeight: FontWeight.bold,
),
],
),
backgroundColor: MyColors.lightGreyEAColor,
progressColor: MyColors.darkPrimaryColor,
),
],
)
],
).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
margin: const EdgeInsets.all(21),
);
}
}

@ -0,0 +1,177 @@
import 'package:geolocator/geolocator.dart';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.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/general_models/m_response.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/utils/utils.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:easy_localization/easy_localization.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/tab/role_type_tab.dart';
import '../../../generated/locale_keys.g.dart';
import '../../../view_models/service_view_model.dart';
import 'package:provider/provider.dart';
import 'package:flutter_svg/flutter_svg.dart';
class BranchAppointmentFragment extends StatelessWidget {
bool isNeedAppBar;
VoidCallback onBackButtonTapped;
RefreshCallback onRefresh;
BranchAppointmentFragment({
Key? key,
this.isNeedAppBar = true,
required this.onBackButtonTapped,
required this.onRefresh,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: !isNeedAppBar
? null
: CustomAppBar(
title: "Appointments",
onBackButtonTapped: onBackButtonTapped,
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(left: 21, right: 21, top: 21),
child: RoleTypeTab(
context.watch<ServiceVM>().selectedBranchStatus == 3
? 0
: context.watch<ServiceVM>().selectedBranchStatus,
[
DropValue(3, "Active", ""),
DropValue(1, "Requested", ""),
],
onSelect: (DropValue value) {
context.read<ServiceVM>().updateSelectedBranchType(value.id);
},
),
),
Expanded(
child: Consumer<ServiceVM>(
builder: (context, model, _) {
if (model.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
List<BranchDetailModel> branches = [];
if (model.branches!.data != null) {
branches = model.branches!.data!.serviceProviderBranch!
.where((element) =>
model.selectedBranchStatus == element.statusId)
.toList();
}
return RefreshIndicator(
onRefresh: onRefresh,
child: branches.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.separated(
itemBuilder: (context, index) {
return Row(
children: [
Container(
width: 74,
height: 50,
decoration: const BoxDecoration(
color: MyColors.darkPrimaryColor,
borderRadius:
BorderRadius.all(Radius.circular(8)),
),
padding: const EdgeInsets.all(6),
child: SvgPicture.asset(
MyAssets.icBranches,
color: Colors.white,
),
),
12.width,
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.place,
size: 12,
color: MyColors.darkPrimaryColor,
),
Geolocator.distanceBetween(
AppState()
.currentLocation
.latitude,
AppState()
.currentLocation
.latitude,
double.parse(branches[index]
.latitude ??
"0"),
double.parse(branches[index]
.longitude ??
"0"))
.toStringAsFixed(2)
.toText(
fontSize: 12,
color:
MyColors.darkPrimaryColor,
)
],
),
Text(
branches[index].branchName ?? "",
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
"Tap to view".toText(
fontSize: 10,
color: MyColors.grey70Color),
],
),
),
12.width,
],
).toContainer().onPress(() async {
branches[index].countryID =
model.branches!.data!.countryID;
branches[index].countryName =
model.branches!.data!.countryName;
navigateWithName(
context, ProviderAppRoutes.appointment,
arguments: branches[index]);
});
},
separatorBuilder: (context, index) {
return 12.height;
},
itemCount: branches.length,
padding: const EdgeInsets.all(12),
),
);
}
},
),
),
],
),
),
);
}
}

@ -0,0 +1,161 @@
import 'package:car_provider_app/views/dashboard/widget/my_service_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/extensions/int_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/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/appointments_view_model.dart';
import 'package:mc_common_app/views/advertisement/ads_list.dart';
import 'package:mc_common_app/views/appointments/widgets/customer_appointment_slider_widget.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/view_all_widget.dart';
import 'package:badges/badges.dart' as b;
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import '../widget/appointment_slider_widget.dart';
class HomeFragment extends StatelessWidget {
VoidCallback onTap, onNotificaitonClick;
RefreshCallback onRefresh;
HomeFragment(
{required this.onTap,
required this.onRefresh,
required this.onNotificaitonClick,
Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
isDrawerEnabled: true,
leadingWidth: 100,
profileImageUrl: MyAssets.carBanner,
onTap: onTap,
actions: [
IconButton(
onPressed: onNotificaitonClick,
icon: const b.Badge(
badgeContent: Text(
'3',
style: TextStyle(
fontSize: 10,
color: Colors.white,
),
),
badgeStyle: b.BadgeStyle(
badgeColor: MyColors.primaryColor,
padding: EdgeInsets.all(5),
),
child: Icon(Icons.notifications_active),
),
),
10.width,
],
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: RefreshIndicator(
onRefresh: onRefresh,
child: ListView(
children: [
ViewAllWidget(
title: 'Upcoming Appointment',
subTitle: 'View All',
onSubtitleTapped: () {},
).horPaddingMain(),
// const AppointmentSliderWidget().horPaddingMain(),
CustomerAppointmentSliderWidget(
myUpComingAppointments:
context.read<AppointmentsVM>().myUpComingAppointments,
isNeedToShowEmptyMessage: true,
onAppointmentClick: () {
// navigateWithName(
// context, ProviderAppRoutes.appointment,
// arguments: branches[index]);
},
),
21.height,
ViewAllWidget(
title: 'My Branches',
subTitle: 'View All',
onSubtitleTapped: () {},
).horPaddingMain(),
const ServiceProviderWidget().horPaddingMain(),
Consumer(
builder: (BuildContext context, AdVM adVM, Widget? child) {
if (adVM.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return Column(
children: [
if (adVM.myActiveAdsForHome.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Active Ads",
subTitle: "View All",
onSubtitleTapped: () {
// context.read<DashboardVM>().onNavbarTapped(3);
// context.read<AdVM>().updateIsExploreAds(false);
},
).horPaddingMain(),
BuildAdsList(
shouldShowAdStatus: true,
isAdsFragment: false,
adsList: adVM.myActiveAdsForHome,
scrollPhysics:
const NeverScrollableScrollPhysics(),
),
],
)
],
if (adVM.exploreAds.isNotEmpty) ...[
Column(
children: [
15.height,
ViewAllWidget(
title: "My Recommended Ads",
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:
const NeverScrollableScrollPhysics(),
),
],
)
]
],
);
}
},
),
21.height,
// const AdWidget(
// count: 4,
// ),
],
),
),
),
);
}
}

@ -0,0 +1,85 @@
import 'dart:developer';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/view_models/requests_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/utils/enums.dart';
import 'package:mc_common_app/views/requests/widget/request_item.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/categories_list.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class MyRequestsFragment extends StatelessWidget {
final bool isNeedAppBar;
VoidCallback onBackButtonTapped;
MyRequestsFragment(
{super.key, this.isNeedAppBar = true, required this.onBackButtonTapped});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: !isNeedAppBar
? null
: CustomAppBar(
title: LocaleKeys.myServiceBranches.tr(),
onBackButtonTapped: onBackButtonTapped,
),
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.provider),
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.provider,
requestIndex: index);
},
separatorBuilder: (context, index) {
return 16.height;
},
itemCount: requestsVM.myFilteredRequests.length,
padding: const EdgeInsets.only(
left: 16, right: 16, bottom: 16, top: 8),
),
))
],
);
}),
),
);
}
}

@ -0,0 +1,355 @@
import 'package:car_provider_app/config/provider_routes.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/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';
import 'package:flutter_svg/flutter_svg.dart';
class AppointmentSliderWidget extends StatelessWidget {
AppointmentListModel appointmentListModel;
bool isNeedTotalPayment;
bool isNeedToShowItems;
bool isNeedToShowToMoreText;
bool isSelectable;
bool isNeedToShowAppointmentStatus;
bool isNeedToShowMergeStatus;
Function()? onTap;
AppointmentSliderWidget(
{required this.appointmentListModel,
required this.onTap,
this.isNeedTotalPayment = false,
this.isNeedToShowItems = false,
this.isNeedToShowToMoreText = true,
this.isSelectable = false,
this.isNeedToShowAppointmentStatus = false,
this.isNeedToShowMergeStatus = false,
Key? key})
: super(key: key);
List<Widget> buildServicesFromAppointment(
{required AppointmentListModel appointmentListModel}) {
if (appointmentListModel.appointmentServicesList == null ||
appointmentListModel.appointmentServicesList!.isEmpty) {
return [SizedBox()];
}
if (appointmentListModel.appointmentServicesList!.length == 1) {
List<Widget> itemsList = [];
if (isNeedToShowItems) {
itemsList = List.generate(
appointmentListModel
.appointmentServicesList?.first.serviceItems?.length ??
0,
(index) => (appointmentListModel.appointmentServicesList?.first
.serviceItems?[index].name ??
"")
.toString()
.toText(
color: MyColors.lightTextColor,
isBold: true,
),
);
}
return [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
showServices(
appointmentListModel
.appointmentServicesList![0].providerServiceDescription,
MyAssets.modificationsIcon,
),
if (isNeedToShowItems) ...itemsList,
],
)
];
}
List<Widget> servicesList = List.generate(
isNeedToShowToMoreText
? 2
: appointmentListModel.appointmentServicesList?.length ?? 0,
(index) {
List<Widget> itemsList = [];
if (isNeedToShowItems) {
itemsList = List.generate(
appointmentListModel
.appointmentServicesList?[index].serviceItems?.length ??
0,
(mIndex) =>
(" - ${appointmentListModel.appointmentServicesList?[index].serviceItems?[mIndex].name ?? ""}")
.toString()
.toText(
color: MyColors.lightTextColor,
isBold: true,
),
);
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
showServices(
appointmentListModel
.appointmentServicesList![index].providerServiceDescription,
MyAssets.modificationsIcon),
if (isNeedToShowItems) ...itemsList,
],
).paddingOnly(bottom: 4);
},
);
if (isNeedToShowToMoreText &&
appointmentListModel.appointmentServicesList!.length > 1) {
servicesList.add(
showServices(
"+ ${appointmentListModel.appointmentServicesList!.length - 1} More",
"",
isMoreText: true,
),
);
}
return servicesList;
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isSelectable)
SizedBox(
child: const SizedBox(
width: 14,
height: 14,
).toContainer(
borderRadius: 24,
marginAll: 4,
paddingAll: 0,
backgroundColor: (appointmentListModel.isSelected ?? false)
? MyColors.primaryColor
: MyColors.greyButtonColor,
),
).toContainer(
borderRadius: 24,
isEnabledBorder: true,
paddingAll: 0,
borderWidget: 3,
borderColor: MyColors.primaryColor,
),
if (isSelectable) 12.width,
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isNeedToShowMergeStatus)
"Appointment Merged".toText(color: MyColors.white).toContainer(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 3),
borderRadius: 12,
backgroundColor: MyColors.greenColor,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
(appointmentListModel.branchName ?? "").toText(
fontSize: 12,
color: MyColors.darkTextColor,
isBold: true,
),
(appointmentListModel.customerName ?? "").toText(
color: MyColors.black, isBold: true, fontSize: 16),
Row(
children: [
"Phone:".toText(
color: MyColors.lightTextColor,
),
2.width,
appointmentListModel.customerMobileNum
.toString()
.toText(
fontSize: 12,
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Appt. On:".toText(
color: MyColors.lightTextColor,
),
2.width,
Expanded(
child:
"${appointmentListModel.duration ?? ""} ${appointmentListModel.appointmentDate!.toFormattedDateWithoutTime()}"
.toText(
fontSize: 12,
),
),
],
),
Row(
children: [
"Location: ".toText(
color: MyColors.lightTextColor,
),
2.width,
appointmentListModel.appointmentType
.toString()
.toText(
fontSize: 12,
),
],
),
],
),
),
if (!isNeedTotalPayment)
if (appointmentListModel.customerAppointmentList!.length >
1)
"${appointmentListModel.customerAppointmentList!.length - 1}+ Appointments"
.toText(
fontSize: 8,
)
.toContainer(
borderRadius: 15,
backgroundColor: MyColors.lightGreyEAColor,
padding: const EdgeInsets.symmetric(
vertical: 6,
horizontal: 12,
),
),
if (isNeedToShowAppointmentStatus)
(appointmentListModel.appointmentStatusEnum!
.getAppointmentNameFromEnum())
.toText(color: MyColors.white)
.toContainer(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 3),
borderRadius: 12,
backgroundColor: MyColors.primaryColor,
),
],
),
8.height,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Column(
children: [
...buildServicesFromAppointment(
appointmentListModel: appointmentListModel),
if (isNeedTotalPayment)
Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
24.height,
"Total Amount".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
appointmentListModel.totalAmount
.toString()
.toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
2.height,
"Remaining Amount".toText(
fontSize: 12,
color: MyColors.lightTextColor,
isBold: true,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
appointmentListModel.remainingAmount
.toString()
.toText(fontSize: 16, isBold: true),
2.width,
"SAR:".toText(
color: MyColors.lightTextColor,
),
],
),
],
),
],
)
],
),
),
if (!isNeedToShowItems)
const Icon(
Icons.arrow_forward,
),
],
),
],
),
)
],
).toWhiteContainer(width: double.infinity, allPading: 12, onTap: onTap);
}
double calculateTotalPrice() {
double totalServiceListPrice = 0;
appointmentListModel.appointmentServicesList!.forEach((servicesElement) {
servicesElement.serviceItems!.forEach((itemsElement) {
totalServiceListPrice += double.parse(itemsElement.price ?? "0");
});
});
return totalServiceListPrice;
}
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,
),
),
],
);
}
}

@ -0,0 +1,216 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:car_provider_app/view_models/dashboard_view_model.dart';
import 'package:mc_common_app/classes/app_state.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/user_models/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';
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;
const CustomDrawer({Key? key, required this.dashboardVM}) : super(key: key);
@override
State<CustomDrawer> createState() => _CustomDrawerState();
}
class _CustomDrawerState extends State<CustomDrawer> {
void _openImagePicker() {
showDialog<ImageSource>(
context: context,
builder: (context) => AlertDialog(
content: const Text("Choose image source"),
actions: [
TextButton(
child: const Text("Camera"),
onPressed: () =>
widget.dashboardVM.pickImageFromPhone(context, 0)),
TextButton(
child: const Text("Gallery"),
onPressed: () =>
widget.dashboardVM.pickImageFromPhone(context, 1)),
],
),
);
}
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
children: [
Stack(
children: [
Container(
width: double.infinity,
height: 200,
color: MyColors.darkPrimaryColor.withOpacity(0.01),
child: Image.network(
ApiConsts.baseUrlServices +
AppState()
.getUser
.data!
.userInfo!
.userImageUrl
.toString(),
),
),
Positioned(
top: 10,
right: 10,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(30),
),
child: const Icon(
Icons.edit,
color: MyColors.darkPrimaryColor,
).onPress(() {
_openImagePicker();
// _handleURLButtonPress(context, ImageSourceType.camera);
}),
),
12.height,
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(30),
),
child: const Icon(
Icons.delete,
color: Colors.red,
).onPress(() async {
Utils.showLoading(context);
ImageResponse response =
await widget.dashboardVM.updateUserImage("");
if (response.messageStatus == 1) {
Utils.showToast("Image is Deleted");
setState(() {
AppState()
.getUser
.data!
.userInfo!
.userImageUrl = response.data;
});
}
Utils.hideLoading(context);
}),
),
],
),
],
),
)
],
),
Container(
width: double.infinity,
color: MyColors.darkPrimaryColor.withOpacity(0.1),
padding: const EdgeInsets.all(20),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"userName".toText(
isBold: true,
fontSize: 20,
letterSpacing: -1.44,
),
AppState()
.getUser
.data!
.userInfo!
.roleName!
.toText(fontSize: 10),
],
),
),
ShowFillButton(
title: LocaleKeys.edit.tr(),
fontSize: 12,
maxHeight: 35,
maxWidth: 70,
onPressed: () {
navigateWithName(context, AppRoutes.editAccountPage);
},
),
],
),
),
ListTile(
leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: LocaleKeys.defineLicences.tr().toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.defineLicense);
},
),
ListTile(
leading: SvgPicture.asset(MyAssets.nextIcon,
color: MyColors.darkPrimaryColor),
title: "Subscriptions".toText(fontSize: 12),
onTap: () {
navigateWithName(context, ProviderAppRoutes.mySubscriptionsPage);
},
),
ListTile(
leading: Image.asset(
MyAssets.icWorldPng,
width: 20,
height: 20,
color: MyColors.darkPrimaryColor,
),
title: LocaleKeys.english.tr().toText(fontSize: 12),
onTap: () {
if (EasyLocalization.of(context)?.currentLocale?.countryCode ==
"SA") {
context.setLocale(const Locale("en", "US"));
} else {
context.setLocale(const Locale('ar', 'SA'));
}
},
),
ListTile(
leading: const Icon(
Icons.logout,
color: MyColors.darkPrimaryColor,
),
title: LocaleKeys.signOut.tr().toText(fontSize: 12),
onTap: () {
pop(context);
navigateReplaceWithName(context, AppRoutes.registerSelection);
},
),
],
),
);
}
}

@ -0,0 +1,68 @@
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:car_provider_app/view_models/service_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/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class ServiceProviderWidget extends StatelessWidget {
const ServiceProviderWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 140,
child: Consumer(
builder: (BuildContext context, ServiceVM model, Widget? child) {
if (model.state == ViewState.busy) {
return const Center(child: CircularProgressIndicator());
} else {
return model.branches!.data! == null
? const Center(child: Text("No Branch Found"))
: model.branches!.data!.serviceProviderBranch!.isEmpty
? Center(child: Text(LocaleKeys.no_branch.tr()))
: ListView.builder(
itemCount: model.branches!.data!.serviceProviderBranch!.length,
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
width: 90,
child: Column(
children: [
Image.asset(
MyAssets.bnCar,
width: 80,
height: 80,
fit: BoxFit.cover,
).toCircle(borderRadius: 100),
8.height,
model.branches!.data!.serviceProviderBranch![index].branchName!.toText(
fontSize: 14,
isBold: true,
textAlign: TextAlign.center,
),
],
),
).onPress(
() {
model.branches!.data!.serviceProviderBranch![index].countryID = model.branches!.data!.countryID;
model.branches!.data!.serviceProviderBranch![index].countryName = model.branches!.data!.countryName;
navigateWithName(context, ProviderAppRoutes.branchDetail, arguments: model.branches!.data!.serviceProviderBranch![index]);
},
);
},
);
}
},
),
);
}
}

@ -0,0 +1,69 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class AppMap extends StatefulWidget {
final CameraPositionCallback onCameraMove;
Map initialCamera;
late AppMapState _state;
final Function onMapCreated;
AppMap(this.initialCamera,
{required this.onCameraMove, required this.onMapCreated});
@override
State<StatefulWidget> createState() => _state = AppMapState();
moveTo({required CameraPosition cameraPostion}) {
_state.googleMapController
.animateCamera(CameraUpdate.newCameraPosition(cameraPostion));
}
}
class AppMapState extends State<AppMap> {
bool isHuawei = false;
Completer<GoogleMapController> _googleMapControllerComp = Completer();
late GoogleMapController googleMapController;
checkIsHuawei() async {
setState(() {});
}
@override
void initState() {}
@override
void dispose() {
super.dispose();
googleMapController.dispose();
}
@override
Widget build(BuildContext context) {
if (isHuawei == null) return CircularProgressIndicator();
return googleMap();
}
Widget googleMap() {
return GoogleMap(
mapType: MapType.normal,
zoomControlsEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition.fromMap(widget.initialCamera) ??
const CameraPosition(
target: LatLng(-26.1711459, 27.9002758), zoom: 2.0),
onCameraMove: widget.onCameraMove,
onMapCreated: (GoogleMapController controller) {
googleMapController = controller;
_googleMapControllerComp.complete(controller);
widget.onMapCreated();
},
);
}
}

@ -0,0 +1,181 @@
import 'dart:async';
import 'package:easy_localization/src/public_ext.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:car_provider_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/navigator.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:permission_handler/permission_handler.dart';
import 'map_selection_widget.dart';
class PickLocationPage extends StatefulWidget {
Function(double, double, String) onPickAddress;
PickLocationPage({required this.onPickAddress});
@override
State<PickLocationPage> createState() => _PickLocationPageState();
}
class _PickLocationPageState extends State<PickLocationPage> {
double latitude = 0;
double longitude = 0;
final Set<Marker> markers = new Set();
late AppMap appMap;
static CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
late LatLng currentPostion;
Completer<GoogleMapController> mapController = Completer();
final ValueNotifier<String> _counter = ValueNotifier<String>("");
@override
void initState() {
appMap = AppMap(
_kGooglePlex.toMap() as Map,
onCameraMove: (camera) {
_updatePosition(camera);
},
onMapCreated: () {
// goToCurrentLocation();
_getUserLocation();
setState(() {});
},
);
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.pickLocation.tr(),
isRemoveBackButton: false,
),
body: Column(
children: [
Expanded(
child: Stack(
children: [
if (appMap != null) appMap,
ValueListenableBuilder<String>(
builder: (BuildContext context, String value, Widget? child) {
// This builder will only get called when the _counter
// is updated.
return value.isNotEmpty
? Container(
width: double.infinity,
margin: EdgeInsets.all(12),
child: Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Text(value ?? ""),
)),
)
: Container();
},
valueListenable: _counter,
),
const Align(
alignment: Alignment.center,
child: Icon(
Icons.place,
color: Colors.red,
size: 50,
),
),
],
),
),
Container(
width: double.infinity,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ShowFillButton(
title: LocaleKeys.pickAddress.tr(),
onPressed: () {
widget.onPickAddress(latitude, longitude, _counter.value);
pop(context);
},
),
),
),
],
),
);
}
Future<void> _updatePosition(CameraPosition _position) async {
latitude = _position.target.latitude;
longitude = _position.target.longitude;
updateAddress(latitude, longitude);
}
void _getUserLocation() async {
if (await Permission.location.request().isGranted) {
var position = await GeolocatorPlatform.instance.getCurrentPosition();
currentPostion = LatLng(position.latitude, position.longitude);
latitude = position.latitude;
longitude = position.longitude;
setMap();
updateAddress(latitude, longitude);
} else {
requestPermissions().then(
(value) async {
if (value[Permission.location]!.isGranted) {
var position =
await GeolocatorPlatform.instance.getCurrentPosition();
currentPostion = LatLng(position.latitude, position.longitude);
latitude = position.latitude;
longitude = position.longitude;
setMap();
updateAddress(latitude, longitude);
}
},
);
}
}
updateAddress(double latitude, double longitude) async {
// List<Placemark> placemarks =
// await placemarkFromCoordinates(latitude, longitude);
// _counter.value =
// '${placemarks.first.street}, ${placemarks.first.subLocality}, ${placemarks.first.locality}, ${placemarks.first.postalCode}, ${placemarks.first.country}';
// print("Address121: " + placemarks[0].toString());
}
setMap() {
setState(() {
_kGooglePlex = CameraPosition(
target: currentPostion,
zoom: 14.4746,
);
appMap.moveTo(cameraPostion: _kGooglePlex);
});
}
Future<String> getCurrentAddress() async {
// List<Placemark> placemarks = await placemarkFromCoordinates(latitude, longitude);
// return placemarks.first.name ?? "";
return "";
}
}
Future<Map<Permission, PermissionStatus>> requestPermissions() async {
var permissionResults = [Permission.calendar].request();
return permissionResults;
}

@ -0,0 +1,284 @@
import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/app_state.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/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:mc_common_app/view_models/requests_view_model.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/info_bottom_sheet.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 RequestDetailPage extends StatelessWidget {
final RequestDetailPageArguments requestDetailPageArguments;
const RequestDetailPage({Key? key, required this.requestDetailPageArguments}) : super(key: key);
Future buildSendOfferBottomSheet(BuildContext context) {
final requestDetail = requestDetailPageArguments.requestModel;
return showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) {
return InfoBottomSheet(
title: "Make an offer".toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
12.height,
TxtField(
value: requestsVM.offerPrice,
errorValue: requestsVM.offerPriceError,
keyboardType: TextInputType.number,
hint: "Enter amount",
onChanged: (v) => requestsVM.updateOfferPrice(v),
),
12.height,
TxtField(
maxLines: 5,
value: requestsVM.offerDescription,
errorValue: requestsVM.offerDescriptionError,
keyboardType: TextInputType.text,
hint: "Description",
onChanged: (v) => requestsVM.updateOfferDescription(v),
),
],
),
25.height,
ShowFillButton(
title: "Submit",
onPressed: () {
requestsVM.onSendOfferPressed(
context: context,
receiverId: requestDetail.customerID,
message: requestsVM.offerDescription,
requestId: requestDetail.id,
offerPrice: requestsVM.offerPrice,
requestModel: requestDetail,
requestIndex: requestDetailPageArguments.requestIndex,
isFromChatScreen: false,
);
},
maxWidth: double.infinity,
),
19.height,
],
),
));
});
},
);
}
Widget buildBottomButton({required RequestStatus requestStatus, required String statusText, required BuildContext context, required Function() onViewChatTapped}) {
switch (requestStatus) {
case RequestStatus.submitted:
case RequestStatus.inProgress:
case RequestStatus.paid:
case RequestStatus.shipping:
return ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: "View Chat",
isBold: false,
onPressed: onViewChatTapped,
);
case RequestStatus.completed:
case RequestStatus.cancelled:
case RequestStatus.expired:
case RequestStatus.pending:
return buildDisabledButton(statusText);
}
}
Widget buildDisabledButton(String text) {
return ShowFillButton(
backgroundColor: MyColors.grey98Color.withOpacity(0.3),
txtColor: MyColors.lightTextColor,
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: text,
isBold: false,
onPressed: () {},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Request Detail",
),
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Image.asset(MyAssets.bnCar),
24.height,
buildRequestContainer(context),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.only(
top: 21,
right: 21,
left: 21,
),
),
if (!requestDetailPageArguments.requestModel.isChatted) ...[
ShowFillButton(
maxWidth: double.infinity,
margin: const EdgeInsets.all(15),
maxHeight: 55,
title: "Send Offer",
isBold: false,
fontSize: 18,
onPressed: () => buildSendOfferBottomSheet(context),
),
] else ...[
buildBottomButton(
requestStatus: requestDetailPageArguments.requestModel.requestStatus,
statusText: "Offer ${requestDetailPageArguments.requestModel.requestStatusName}",
context: context,
onViewChatTapped: () async {
ChatViewArguments chatViewArguments = ChatViewArguments(
chatTypeEnum: ChatTypeEnum.requestOffer,
receiverId: requestDetailPageArguments.requestModel.customerID,
senderId: AppState().getUser.data!.userInfo!.userId.toString(),
requestId: requestDetailPageArguments.requestModel.id,
providerIndex: -1,
// This will be only sent in case of customer
requestModel: requestDetailPageArguments.requestModel,
requestIndex: requestDetailPageArguments.requestIndex, // This will be only sent in case of provider
);
final chatVM = context.read<ChatVM>();
await chatVM
.getUsersChatMessagesForProvider(
customerId: requestDetailPageArguments.requestModel.customerId,
context: context,
requestOfferId: 0,
requestId: requestDetailPageArguments.requestModel.id,
customerRequestIndex: requestDetailPageArguments.requestIndex,
)
.whenComplete(
() => navigateWithName(
context,
AppRoutes.chatView,
arguments: chatViewArguments,
),
);
},
),
],
],
),
),
);
}
Widget buildRequestContainer(BuildContext context) {
final requestDetail = requestDetailPageArguments.requestModel;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
requestDetail.vehicleTypeName.toText(fontSize: 16, isBold: true),
showItem("Manufacturer:", requestDetail.brand),
showItem("Model:", "${requestDetail.year}"),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"${requestDetail.city ?? ""} ${requestDetail.countryName}".toText(
color: MyColors.lightTextColor,
),
requestDetail.createdOn.getTimeAgo().toText(color: MyColors.lightTextColor),
],
),
],
),
showItem("Customer Name", requestDetail.customerName),
showItem("Description", requestDetail.description),
showItem("Price Range:", ""),
Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
"${requestDetail.price.toInt()}".toText(fontSize: 25, isBold: true),
2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, height: 2.3),
],
),
Row(
children: [
Utils.statusContainerChip(
text: "Offer ${requestDetail.requestStatusName}",
chipColor: MyColors.grey98Color.withOpacity(0.3),
textColor: MyColors.lightTextColor,
),
],
),
],
),
),
// const Icon(Icons.arrow_forward)
],
),
],
);
}
Widget showItem(String title, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title.isNotEmpty)
title.toText(
color: MyColors.lightTextColor,
),
if (title.isNotEmpty) 2.width,
if (value.isNotEmpty) Expanded(child: value.toText(isBold: true)),
],
);
}
}

@ -0,0 +1,52 @@
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/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:mc_common_app/widgets/txt_field.dart';
class SendOfferPage extends StatelessWidget {
const SendOfferPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const CustomAppBar(
title: "Send Offer",
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
"Send Price Offer".toText(
fontSize: 14,
isBold: true,
),
12.height,
TxtField(
hint: "35,0000",
),
12.height,
TxtField(
hint: "Comment",
),
],
).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.all(21),
),
ShowFillButton(
title: "Submit",
onPressed: () {},
maxWidth: double.infinity,
margin: const EdgeInsets.all(21),
),
],
),
);
}
}

@ -0,0 +1,372 @@
import 'dart:convert';
import 'dart:developer';
import 'package:car_provider_app/config/provider_routes.dart';
import 'package:car_provider_app/view_models/service_view_model.dart';
import 'package:car_provider_app/views/settings/services/services_list_page.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:car_provider_app/view_models/branch_view_model.dart';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart';
import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart';
import 'package:mc_common_app/models/provider_branches_models/profile/categroy.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/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';
import '../../../generated/locale_keys.g.dart';
class BranchDetailPage extends StatelessWidget {
BranchDetailModel branchData;
BranchDetailPage(this.branchData);
List<CategoryData> categories = [];
@override
Widget build(BuildContext context) {
branchData.branchServices!.forEach((element) {
categories.add(
CategoryData(
id: element.categoryId,
categoryName: element.categoryName,
categoryNameN: element.categoryName,
),
);
});
categories = categories.toSet().toList();
for (var payment in categories) {
branchData.branchServices!.forEach((element) {
if (payment.id == element.categoryId) {
payment.services ??= [];
payment.services!.add(element);
}
});
}
branchData.categories = categories;
return Scaffold(
appBar: CustomAppBar(
title: branchData.branchName.toString(),
),
body: Consumer<ServiceVM>(builder: (context, model, _) {
return SizedBox(
width: double.infinity,
height: double.infinity,
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: titleWidget(MyAssets.icBranches,
LocaleKeys.branchInfo.tr()),
),
IconButton(
onPressed: () {
navigateWithName(
context, ProviderAppRoutes.defineBranch,
arguments: branchData);
},
icon: SvgPicture.asset(MyAssets.icEdit),
)
],
),
Column(
children: [
showData("${LocaleKeys.country.tr()}:",
branchData.countryName.toString()),
showData("${LocaleKeys.city.tr()}:",
branchData.cityName.toString()),
showData("${LocaleKeys.branchName.tr()}:",
branchData.branchName.toString()),
showData(
"${LocaleKeys.branchDescription.tr()}:",
branchData.branchDescription.toString()),
showData("${LocaleKeys.address.tr()}:",
branchData.address.toString()),
],
),
],
),
),
Container(
width: double.infinity,
color: MyColors.darkIconColor,
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 8),
child: Row(
children: [
const Icon(
Icons.calendar_month,
color: Colors.white,
),
8.width,
Expanded(
child: "Set or Edit Branch Schedule".toText(
isUnderLine: true,
fontSize: 14,
isBold: true,
color: Colors.white,
),
),
const Icon(
Icons.arrow_forward,
size: 20,
color: Colors.white,
),
],
),
).onPress(() {
navigateWithName(
context, ProviderAppRoutes.schedulesList,
arguments: branchData.id.toString());
}),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.add,
color: Colors.white,
).toContainer(
borderRadius: 100,
paddingAll: 3,
backgroundColor: MyColors.darkIconColor,
),
8.width,
"Add Services".toText(
fontSize: 14,
color: MyColors.lightTextColor,
isBold: true,
),
],
)
.toContainer(
borderRadius: 0,
backgroundColor: MyColors.darkWhiteColor,
width: double.infinity,
paddingAll: 20,
margin:
const EdgeInsets.only(left: 20, right: 20, top: 20),
)
.onPress(() {
navigateWithName(
context,
ProviderAppRoutes.createServices3,
arguments: CreateBranchModel(
branchId: branchData.id.toString(),
branchName: branchData.branchName.toString(),
),
);
}),
categories.isEmpty
? "No Service Added Yet".toText(fontSize: 12)
: ListView.separated(
itemBuilder: (context, pIndex) {
return InkWell(
onTap: () {
categories[pIndex].branchId =
branchData.id.toString();
categories[pIndex].branchName =
branchData.branchName.toString();
navigateWithName(
context, ProviderAppRoutes.servicesList,
arguments: categories[pIndex]);
},
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: SvgPicture.asset(
MyAssets.maintenanceIcon,
width: 16,
height: 16,
),
),
8.width,
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
categories[pIndex]
.categoryName
.toString()
.toText(
fontSize: 16,
isBold: true),
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: SvgPicture.asset(
// MyAssets.icEdit,
// width: 16,
// height: 16,
// ),
// ),
],
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
),
Row(
children: [
Expanded(
child: ListView.builder(
itemBuilder:
(context, index) {
return Container(
child: (EasyLocalization.of(
context)
?.currentLocale
?.countryCode ==
"SA"
? categories[
pIndex]
.services![
index]
.serviceDescriptionN
.toString()
: categories[
pIndex]
.services![
index]
.serviceDescription
.toString())
.toText(
fontSize: 12,
color: MyColors
.lightTextColor,
isBold: true,
),
);
},
itemCount: categories[pIndex]
.services
?.length,
physics:
const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
),
),
const Padding(
padding: EdgeInsets.all(4.0),
child: Icon(
Icons.arrow_forward,
size: 20,
),
),
],
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment.end,
)
],
)),
],
).toContainer(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
isShadowEnabled: true,
),
);
},
itemCount: categories.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.all(20),
separatorBuilder:
(BuildContext context, int index) {
return 12.height;
},
),
12.height,
],
),
),
),
Container(
width: double.infinity,
height: 1,
color: Colors.grey[100],
),
if (AppState().userType == UserType.providerDealer)
Padding(
padding: const EdgeInsets.all(12.0),
child: ShowFillButton(
title: "Assign Dealer User",
maxWidth: double.infinity,
backgroundColor: Colors.transparent,
borderColor: MyColors.darkPrimaryColor,
txtColor: MyColors.darkPrimaryColor,
isFilled: false,
onPressed: () {
navigateWithName(context, ProviderAppRoutes.dealerUser,
arguments: branchData.id.toString());
},
),
),
],
),
);
}),
);
}
Widget titleWidget(String icon, String title) {
return Row(
children: [
SvgPicture.asset(
icon,
width: 18,
height: 18,
color: MyColors.darkPrimaryColor,
),
12.width,
title.toText(fontSize: 16, color: Colors.black, isBold: true),
],
);
}
Widget showData(String title, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
title.toText(fontSize: 10, color: Colors.black, isBold: true),
8.width,
Flexible(
child: value.toText(
fontSize: 12,
color: MyColors.textColor,
),
)
],
);
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save